我正在使用SFML库在C ++中创建游戏,并且在实现平铺地图冲突期间(我从txt文件加载地图 - 1代表平台,0' s可用空间)。 https://imgur.com/a/tQZc6
我遇到了同时处理所有四种类型碰撞的问题(从底部,顶部,左侧和右侧)。我的意思是:当没有碰撞时,玩家可以正常移动,但是如果我们碰到了墙,碰撞只出现在FIRST写的if()语句中(在我们的例子中只发生正确的碰撞,其余的被省略)。这是我的代码(我只会粘贴必要的东西)
class Player
{
public:
Player();
Player(sf::Texture* texture, sf::Vector2u imageCount, sf::Vector2f position, float switchTime, float speed, float jumpSpeed);
~Player();
void UpdatePlayer(float deltaTime);
float top, right, left, bottom;
private:
sf::Vector2f _position;
float groundHeight = 40; //i've added gravity and hardcoded the ground height to create jumping
float _jumpSpeed; // later on, it will be replaced with bottom collision
const float gravity = 981.0f;
sf::RectangleShape body;
float _speed;
};
//Player.cpp
void Player::UpdatePlayer(float deltaTime)
{
sf::Vector2f movement(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
movement.x -= _speed * deltaTime; //we are using delta time in order to move the object in according to time
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
movement.x += _speed * deltaTime;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
movement.y = -sqrt(5.0f * gravity * _jumpSpeed) * deltaTime;
}
if (body.getPosition().y + body.getSize().y < groundHeight || movement.y < 0)
{
movement.y += gravity * deltaTime;
}
else
{
body.setPosition(body.getPosition().x, groundHeight - body.getSize().y);
movement.y = 0;
}
bottom = body.getPosition().y + body.getSize().y;
left = body.getPosition().x;
right = body.getPosition().x + body.getSize().x;
top = body.getPosition().y;
body.move(movement);
}
// Source.cpp
void LoadCollisionMap(const char*filename)
{
std::ifstream openfile(filename);
std::vector<int> tempMap;
CollMap.clear();
if (openfile.is_open())
{
while (!openfile.eof())
{
std::string str, value;
std::getline(openfile, str);
std::stringstream stream(str);
while (std::getline(stream, value, ' '))
{
if (value.length() > 0)
{
int a = atoi(value.c_str());
tempMap.push_back(a);
}
}
CollMap.push_back(tempMap);
tempMap.clear();
}
}
}
int main()
{
LoadCollisionMap("Map2.txt"); //Collision map
Player player(&playerTexture, sf::Vector2u(3, 9),sf::Vector2f(100.0f, 150.0f) ,0.3f, 400.0f, 555.0f);
for (int i = 0; i < CollMap.size(); i++)
{
for (int j = 0; j < CollMap[i].size(); j++)
{
if (CollMap[i][j] == 1)
{
int CollBottom, CollRight, CollLeft, CollTop;
CollBottom = i * 32 + 32;
CollTop = i * 32;
CollLeft = j * 32;
CollRight = j * 32 + 32;
if (player.right < CollLeft || player.left > CollRight || player.top > CollBottom || player.bottom < CollTop)
{
//no collision
}
else
{
if (player.right > CollLeft)
{
std::cout << "collision" << std::endl;
player.body.setPosition(player.body.getPosition().x - 1, player.body.getPosition().y);
break;
}
if (player.left < CollRight)
{
std::cout << "collision 2" << std::endl;
player.body.setPosition(player.body.getPosition().x + 1, player.body.getPosition().y);
break;
}
if (player.top < CollBottom)
{
std::cout << "collision 3" << std::endl;
player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y + 1);
break;
}
if (player.bottom > CollTop)
{
std::cout << "collision 4" << std::endl;
player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y - 1);
break;
}
}
}
}
}
答案 0 :(得分:0)
运算符break
会立即从最嵌套的循环返回。如果要检查所有碰撞,则应从碰撞检查中删除break
,并将其替换为例如bool变量。
bool collisionDetected = false;
if (player.right > CollLeft)
{
std::cout << "collision" << std::endl;
player.body.setPosition(player.body.getPosition().x - 1, player.body.getPosition().y);
collisionDetected = true;
}
...
if( collisionDetected )
break;