无法将'bool solid'设置为仅部分瓷砖

时间:2014-03-27 21:14:36

标签: c++ sdl

首先,我想说我对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;
}

除了发布的内容,我还有一个图像加载功能,一个应用图像功能和一个计时器类。

2 个答案:

答案 0 :(得分:1)

我不肯定这是你的问题,但是如果类型不是1,那么你的固体变量是未设置的。 在构造函数中,您应该初始化所有成员变量。您可以使用初始化程序列表来确保您的变量中没有垃圾。

Tile::Tile(int tileNum, int type_e) : solid(false) {

答案 1 :(得分:1)

我明白了。我从未分配过myPlayer.box.w和myPlayer.box.h值。我不知道默认值是什么,但由于某种原因,无论玩家是谁,它都会发生碰撞。谢谢你的帮助!