我的碰撞检测做错了什么?
What have I done wrong with my collision detection?
我想编写一个游戏。我已经对敌人和玩家进行了编程。每当游戏对象,无论是敌人还是玩家,逆着角(左上或右上或左下或右下)移动时,游戏对象都会移出场地。
还有第二个问题。有时,敌人会在场地边缘停留一小段时间
#include <Windows.h>
#include <SFML/Graphics.hpp>
#include <vector>
#include <ctime>
#include <cstdlib>
#include "Player.hpp"
#include "Square.hpp"
#define WIDTH 800
#define HEIGHT 600
bool kUp = false, kDown = false, kLeft = false, kRight = false;
Player player(WIDTH / 2 - 10, HEIGHT / 2 - 10, 10, sf::Color::Green);
std::vector<Square> squares(10);
sf::RenderWindow window;
void update(float elapsedTime) {
if (kUp == true) player.move(0, -300.0f * elapsedTime);
if (kDown == true) player.move(0, 300.0f * elapsedTime);
if (kLeft == true) player.move(-300.0f * elapsedTime, 0);
if (kRight == true) player.move(300.0f * elapsedTime, 0);
sf::Vector2f playerPos = player.getPosition();
if (playerPos.x < 0) player.setPosition(0, playerPos.y);
if (playerPos.y < 0) player.setPosition(playerPos.x, 0);
if (playerPos.x > WIDTH - 20) player.setPosition(WIDTH - 20, playerPos.y);
if (playerPos.y > HEIGHT - 20) player.setPosition(playerPos.x, HEIGHT - 20);
for (int i = 0; i < squares.size(); ++i) {
sf::Vector2f squareSpeed = squares[i].getSpeed();
squares[i].move(squareSpeed.x * elapsedTime, squareSpeed.y * elapsedTime);
sf::Vector2f squarePos = squares[i].getPosition();
if (squarePos.x < 0) squares[i].setSpeed(-squareSpeed.x, squareSpeed.y);
if (squarePos.y < 0) squares[i].setSpeed(squareSpeed.x, -squareSpeed.y);
if (squarePos.x > WIDTH - 5) squares[i].setSpeed(-squareSpeed.x, squareSpeed.y);
if (squarePos.y > HEIGHT - 5) squares[i].setSpeed(squareSpeed.x, -squareSpeed.y);
}
}
void draw() {
for (int i = 0; i < squares.size(); ++i) {
window.draw(squares[i]);
}
window.draw(player);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
window.create(sf::VideoMode(WIDTH, HEIGHT), "Runner - The Red Squares", sf::Style::Titlebar | sf::Style::Close, settings);
window.setVerticalSyncEnabled(true);
srand(time(0));
for (int i = 0; i < squares.size(); ++i) {
squares[i] = Square(rand() % WIDTH, rand() % HEIGHT, 5, 5, sf::Color::Red);
}
sf::Clock clock;
while (window.isOpen()) {
sf::Time elapsedTime = clock.restart();
window.clear(sf::Color::Black);
update(elapsedTime.asSeconds());
draw();
window.display();
sf::Event evt;
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::Closed) {
window.close();
}
if (evt.type == sf::Event::KeyPressed) {
if (evt.key.code == sf::Keyboard::Up) kUp = true;
if (evt.key.code == sf::Keyboard::Down) kDown = true;
if (evt.key.code == sf::Keyboard::Left) kLeft = true;
if (evt.key.code == sf::Keyboard::Right) kRight = true;
}
if (evt.type == sf::Event::KeyReleased) {
if (evt.key.code == sf::Keyboard::Up) kUp = false;
if (evt.key.code == sf::Keyboard::Down) kDown = false;
if (evt.key.code == sf::Keyboard::Left) kLeft = false;
if (evt.key.code == sf::Keyboard::Right) kRight = false;
}
}
sf::sleep(sf::milliseconds(15));
}
return 0;
}
有谁知道我做错了什么吗?
感谢大家的帮助
问题是因为您在使用玩家位置的副本(存储在 playerPos
中)的同时还更新了当前玩家位置(使用 player.getPosition()
)。如果 x
和 y
位置均为负数,您最初将玩家 x
位置设置为 0。在下一行中,由于 y
为负数,您设置玩家位置到 0 y
但旧的 仍然是负数 x
副本的位置。
有几种可能的解决方案,包括始终获取玩家位置(而不是使用副本)或添加一种方法来仅设置玩家 x
或 y
位置而不必同时设置两者.
我想编写一个游戏。我已经对敌人和玩家进行了编程。每当游戏对象,无论是敌人还是玩家,逆着角(左上或右上或左下或右下)移动时,游戏对象都会移出场地。
还有第二个问题。有时,敌人会在场地边缘停留一小段时间
#include <Windows.h>
#include <SFML/Graphics.hpp>
#include <vector>
#include <ctime>
#include <cstdlib>
#include "Player.hpp"
#include "Square.hpp"
#define WIDTH 800
#define HEIGHT 600
bool kUp = false, kDown = false, kLeft = false, kRight = false;
Player player(WIDTH / 2 - 10, HEIGHT / 2 - 10, 10, sf::Color::Green);
std::vector<Square> squares(10);
sf::RenderWindow window;
void update(float elapsedTime) {
if (kUp == true) player.move(0, -300.0f * elapsedTime);
if (kDown == true) player.move(0, 300.0f * elapsedTime);
if (kLeft == true) player.move(-300.0f * elapsedTime, 0);
if (kRight == true) player.move(300.0f * elapsedTime, 0);
sf::Vector2f playerPos = player.getPosition();
if (playerPos.x < 0) player.setPosition(0, playerPos.y);
if (playerPos.y < 0) player.setPosition(playerPos.x, 0);
if (playerPos.x > WIDTH - 20) player.setPosition(WIDTH - 20, playerPos.y);
if (playerPos.y > HEIGHT - 20) player.setPosition(playerPos.x, HEIGHT - 20);
for (int i = 0; i < squares.size(); ++i) {
sf::Vector2f squareSpeed = squares[i].getSpeed();
squares[i].move(squareSpeed.x * elapsedTime, squareSpeed.y * elapsedTime);
sf::Vector2f squarePos = squares[i].getPosition();
if (squarePos.x < 0) squares[i].setSpeed(-squareSpeed.x, squareSpeed.y);
if (squarePos.y < 0) squares[i].setSpeed(squareSpeed.x, -squareSpeed.y);
if (squarePos.x > WIDTH - 5) squares[i].setSpeed(-squareSpeed.x, squareSpeed.y);
if (squarePos.y > HEIGHT - 5) squares[i].setSpeed(squareSpeed.x, -squareSpeed.y);
}
}
void draw() {
for (int i = 0; i < squares.size(); ++i) {
window.draw(squares[i]);
}
window.draw(player);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
window.create(sf::VideoMode(WIDTH, HEIGHT), "Runner - The Red Squares", sf::Style::Titlebar | sf::Style::Close, settings);
window.setVerticalSyncEnabled(true);
srand(time(0));
for (int i = 0; i < squares.size(); ++i) {
squares[i] = Square(rand() % WIDTH, rand() % HEIGHT, 5, 5, sf::Color::Red);
}
sf::Clock clock;
while (window.isOpen()) {
sf::Time elapsedTime = clock.restart();
window.clear(sf::Color::Black);
update(elapsedTime.asSeconds());
draw();
window.display();
sf::Event evt;
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::Closed) {
window.close();
}
if (evt.type == sf::Event::KeyPressed) {
if (evt.key.code == sf::Keyboard::Up) kUp = true;
if (evt.key.code == sf::Keyboard::Down) kDown = true;
if (evt.key.code == sf::Keyboard::Left) kLeft = true;
if (evt.key.code == sf::Keyboard::Right) kRight = true;
}
if (evt.type == sf::Event::KeyReleased) {
if (evt.key.code == sf::Keyboard::Up) kUp = false;
if (evt.key.code == sf::Keyboard::Down) kDown = false;
if (evt.key.code == sf::Keyboard::Left) kLeft = false;
if (evt.key.code == sf::Keyboard::Right) kRight = false;
}
}
sf::sleep(sf::milliseconds(15));
}
return 0;
}
有谁知道我做错了什么吗?
感谢大家的帮助
问题是因为您在使用玩家位置的副本(存储在 playerPos
中)的同时还更新了当前玩家位置(使用 player.getPosition()
)。如果 x
和 y
位置均为负数,您最初将玩家 x
位置设置为 0。在下一行中,由于 y
为负数,您设置玩家位置到 0 y
但旧的 仍然是负数 x
副本的位置。
有几种可能的解决方案,包括始终获取玩家位置(而不是使用副本)或添加一种方法来仅设置玩家 x
或 y
位置而不必同时设置两者.