我的碰撞检测有什么问题?

时间:2022-06-01 17:53:26

I want to program a game. I have already programmed enemies and a player. Whenever the game objects, it doesn't matter whether enemy or player, move against the cornors (left and top or right and top or left and bottom or right and bottom), the game objects move outside of the field.

我想编写一个游戏。我已经设定了敌人和玩家。每当游戏对象时,无论敌人或玩家是否移动到角落(左侧和顶部或右侧和顶部或左侧和底部或右侧和底部)都无关紧要,游戏对象移动到场外。

There is also a second problem. Sometimes, the enemies stick in the edge of the field for a short time

还有第二个问题。有时候,敌人会在场地边缘停留很短的时间

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

Does anyone know what I did wrong?

有谁知道我做错了什么?

Thanks for each help

感谢您的帮助

1 个解决方案

#1


1  

The problem is because you're using a copy of the player position (stored in playerPos) while also updating the current player position (using player.getPosition()). If the x and y positions are both negative, you'll initially set the player x position to 0. In the next line, since y is negative, you set the player position to a 0 y but the old still negative x position from the copy.

问题是因为您正在使用玩家位置的副本(存储在playerPos中),同时还会更新当前玩家位置(使用player.getPosition())。如果x和y位置都是负数,则最初将玩家x位置设置为0.在下一行中,由于y为负数,因此您将玩家位置设置为0 y,但旧的仍为负x位置复制。

There are several possible solutions, including always getting the player position (and not using the copy) or adding a way to only set the player x or y position without having to set both.

有几种可能的解决方案,包括始终获取玩家位置(并且不使用副本)或添加仅设置玩家x或y位置而无需同时设置两者的方法。

#1


1  

The problem is because you're using a copy of the player position (stored in playerPos) while also updating the current player position (using player.getPosition()). If the x and y positions are both negative, you'll initially set the player x position to 0. In the next line, since y is negative, you set the player position to a 0 y but the old still negative x position from the copy.

问题是因为您正在使用玩家位置的副本(存储在playerPos中),同时还会更新当前玩家位置(使用player.getPosition())。如果x和y位置都是负数,则最初将玩家x位置设置为0.在下一行中,由于y为负数,因此您将玩家位置设置为0 y,但旧的仍为负x位置复制。

There are several possible solutions, including always getting the player position (and not using the copy) or adding a way to only set the player x or y position without having to set both.

有几种可能的解决方案,包括始终获取玩家位置(并且不使用副本)或添加仅设置玩家x或y位置而无需同时设置两者的方法。