不能将"布尔固体"设置为仅某些磁贴

Can't set 'bool solid' to only some tiles

本文关键字:设置 布尔固 不能      更新时间:2023-10-16

首先,我想说我对c++比较陌生,所以这个问题的解决方案可能相对简单。在SDL中,我一直在制作一款使用贴图的小型2d游戏。贴图位于一个单独的.txt文件中。瓷砖显示得很好,并且基于类型使用了正确的纹理。然而,当我尝试在构造函数中设置一个'solid' bool为true时,如果类型为1(石头瓷砖),并检查'update'函数中的碰撞,它会将每个瓷砖视为固体。这样玩家就会与背景发生碰撞。我做错了什么?

编辑:我添加了大部分以前未发布的代码。

这里是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 00 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 1 2 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 00 1 2 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 1 2 0 0 0 00 0 0 0 0 1 2 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0<<p> <<p>>

还有,这是我的碰撞函数:

#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;
}

除了张贴我有一个图像加载函数,一个应用图像函数,和一个定时器类。

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

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

我明白了。我从未给myPlayer.box.w和myPlayer.box.h赋值。我不知道默认值是多少,但不管玩家在哪里,它都会发生碰撞。谢谢你的帮助!