首先,我想说我对c ++比较陌生,所以这个问题的解决方案可能相对简单。在SDL中,我一直在使用瓷砖进行小型2D游戏。平铺贴图位于单独的.txt文件中。瓷砖显示完全正确,并根据类型使用正确的纹理。但是,当我尝试设置一个“坚实”的时候。如果类型为1(石块),则在构造函数中将bool设置为true,并在“更新”中检查是否存在冲突。功能,它将每块瓷砖视为坚固。这使得玩家与背景发生碰撞。我做错了什么。
编辑:我添加了以前未发布的大部分代码。
这是Tile.h
#pragma once
#include "SDL.h"
class Tile
{
public:
SDL_Rect box;
int type;
bool solid;
Tile(int tileNum,int type_e);
void show();
bool update(SDL_Rect A);
SDL_Surface* tile[3];
};
Tile.cpp
#include "Tile.h"
#include "Finals.h"
bool check_collisions(SDL_Rect A, SDL_Rect B);
Tile::Tile(int tileNum, int type_e)
{
box.x = (tileNum % 16) * 40;
box.y = (tileNum / 16) * 40;
box.w = 40;
box.h = 40;
type = type_e;
tile[0] = LoadImage("tile.png");
tile[1] = LoadImage("tile2.png");
tile[2] = LoadImage("tile3.png");
if(type_e == 1)
solid = true;
}
void Tile::show()
{
ApplyImage(box.x, box.y, tile[type], screen);
}
bool Tile::update(SDL_Rect A)
{
if(solid && check_collisions(A, box))
{
return true;
}
else
{
return false;
}
}
的main.cpp
#include "SDL.h"
#include "SDL_image.h"
#include "Finals.h"
#include <string>
#include "Tile.h"
#include <vector>
#include "Timer.h"
#include <fstream>
#include "Player.h"
SDL_Surface* screen;
SDL_Event Event;
int main( int argc, char* args[] )
{
extern SDL_Surface* screen;
SDL_Surface* background;
bool quit = false;
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
std::vector<Tile> tiles;
std::ifstream map ( "map.txt" );
int tileType = 0;
for (int iii = 0;iii < 192;iii++)
{
map >> tileType;
tiles.push_back(Tile(iii,tileType));
}
map.close();
Timer fps;
Player myPlayer;
while(!quit)
{
fps.startTimer();
while(SDL_PollEvent(&Event))
{
myPlayer.handleEvents();
if(Event.type == SDL_KEYDOWN)
{
if(Event.key.keysym.sym == SDLK_ESCAPE)
quit = true;
}
if(Event.type == SDL_QUIT)
quit = true;
}
myPlayer.move();
for(int iii = 0;iii < 192;iii++)
{
if(tiles[iii].update(myPlayer.box))
{
myPlayer.box.x -= myPlayer.xVel;
myPlayer.box.y -= myPlayer.yVel;
}
tiles[iii].show();
}
myPlayer.show();
SDL_Flip(screen);
if(fps.getTime() < 1000 / FPS)
{
SDL_Delay(1000/FPS - fps.getTime());
}
}
//Quit SDL
SDL_Quit();
return 0;
}
Player.cpp
#include "Player.h"
#include "Finals.h"
#include "SDL.h"
Player::Player()
{
box.x = 20;
box.y = 20;
xVel = 0;
yVel = 0;
}
void Player::handleEvents()
{
if(Event.type == SDL_KEYDOWN)
{
switch(Event.key.keysym.sym)
{
case SDLK_UP: yVel -= PLAYER_VEL; break;
case SDLK_DOWN: yVel += PLAYER_VEL; break;
case SDLK_RIGHT: xVel += PLAYER_VEL; break;
case SDLK_LEFT: xVel -= PLAYER_VEL; break;
}
}
if(Event.type == SDL_KEYUP)
{
switch(Event.key.keysym.sym)
{
case SDLK_UP: yVel += PLAYER_VEL; break;
case SDLK_DOWN: yVel -= PLAYER_VEL; break;
case SDLK_RIGHT: xVel -= PLAYER_VEL; break;
case SDLK_LEFT: xVel += PLAYER_VEL; break;
}
}
}
void Player::move()
{
box.x += xVel;
box.y += yVel;
if(box.x + PLAYER_WIDTH > SCREEN_WIDTH)
{
box.x = SCREEN_WIDTH - PLAYER_WIDTH;
}
if(box.y + PLAYER_HEIGHT > SCREEN_HEIGHT)
{
box.y = SCREEN_HEIGHT - PLAYER_HEIGHT;
}
if(box.x < 0)
box.x = 0;
if(box.y < 0)
box.y = 0;
}
void Player::show()
{
SDL_Surface* sprite;
sprite = LoadImage("player.png");
ApplyImage(box.x,box.y,sprite,screen);
SDL_FreeSurface(sprite);
sprite = NULL;
}
这是map.txt:
的上下文0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
另外,这是我的碰撞功能:
#include "SDL.h"
bool check_collisions(SDL_Rect A, SDL_Rect B)
{
int topA;
int topB;
int bottomA;
int bottomB;
int rightA;
int rightB;
int leftA;
int leftB;
topA = A.y;
bottomA = A.y + A.h;
leftA = A.x;
rightA = A.x + A.w;
topB = B.y;
bottomB = B.y + B.h;
leftB = B.x;
rightB = B.x + B.w;
if (bottomA <= topB)
return false;
if (rightA <= leftB)
return false;
if (topA >= bottomB)
return false;
if (leftA >= rightB)
return false;
return true;
}
除了发布的内容,我还有一个图像加载功能,一个应用图像功能和一个计时器类。
答案 0 :(得分:1)
我不肯定这是你的问题,但是如果类型不是1,那么你的固体变量是未设置的。 在构造函数中,您应该初始化所有成员变量。您可以使用初始化程序列表来确保您的变量中没有垃圾。
Tile::Tile(int tileNum, int type_e) : solid(false) {
答案 1 :(得分:1)
我明白了。我从未分配过myPlayer.box.w和myPlayer.box.h值。我不知道默认值是什么,但由于某种原因,无论玩家是谁,它都会发生碰撞。谢谢你的帮助!