我正在尝试制作一个游戏,你可以躲避传入的盒子(东西)。我不知道如何使用if语句编写快速简便的碰撞检测代码。 我试图在“//碰撞检测”中对此进行编码。我想要它,以便如果箭头(玩家)正在触摸该框,游戏就会关闭。
Main Menu.h
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
using namespace std;
#pragma once
class main_menu
{
public:
void startmenu(RenderWindow &gameDisplay, Font &font1, bool &MainMenu, RectangleShape &start, Event &evnt)
{
gameDisplay.setMouseCursorVisible(true);
Text starttext;
starttext.setCharacterSize(100);
starttext.setFont(font1);
starttext.setString("DODGE");
starttext.setFillColor(Color(255, 255, 255));
starttext.setStyle(Text::Bold);
FloatRect starttextRect = starttext.getLocalBounds();
starttext.setOrigin(starttextRect.width / 2, starttextRect.height / 2);
starttext.setPosition(Vector2f(1366 / 2.0f - 30, 768 - 700.0f));
RectangleShape outlinetop(Vector2f(1366, 50));
outlinetop.setFillColor(Color(255, 255, 255));
outlinetop.setPosition(0, 0);
RectangleShape outlinebottom(Vector2f(1366, 50));
outlinebottom.setFillColor(Color(255, 255, 255));
outlinebottom.setPosition(0, 718);
RectangleShape outlineright(Vector2f(50, 768));
outlineright.setFillColor(Color(255, 255, 255));
outlineright.setPosition(1316, 0);
RectangleShape outlineleft(Vector2f(50, 768));
outlineleft.setFillColor(Color(255, 255, 255));
outlineleft.setPosition(0, 0);
Text startbuttontext;
startbuttontext.setFont(font1);
startbuttontext.setCharacterSize(70);
startbuttontext.setString("PLAY");
startbuttontext.setFillColor(Color(255, 255, 255));
FloatRect startbuttontextRect = starttext.getLocalBounds();
startbuttontext.setOrigin(starttextRect.width / 2, startbuttontextRect.height / 2);
startbuttontext.setPosition(Vector2f(1366 / 2.0f + 60 - 30, 768 - 480.0f));
if (MainMenu == true)
{
Vector2f tempMouse(Mouse::getPosition(gameDisplay));
if (start.getGlobalBounds().contains(tempMouse) &&
evnt.type == Event::MouseButtonPressed &&
evnt.key.code == Mouse::Left)
{
MainMenu = false;
}
//mouseposx = (Mouse::getPosition(gameDisplay).x);
//mouseposy = (Mouse::getPosition(gameDisplay).y);
/*
while (Mouse::getPosition(gameDisplay).x > 1366 / 2.0 && Mouse::getPosition(gameDisplay).x < 1083)
while (Mouse::getPosition(gameDisplay).y > 768 - 450 && Mouse::getPosition(gameDisplay).y < 868)
if (Mouse::isButtonPressed(Mouse::Left))
MainMenu = false;
*/
if (Keyboard::isKeyPressed(Keyboard::Q))
{
MainMenu = false;
gameDisplay.close();
}
gameDisplay.draw(outlinebottom);
gameDisplay.draw(outlineleft);
gameDisplay.draw(outlineright);
gameDisplay.draw(outlinetop);
gameDisplay.draw(start);
gameDisplay.draw(starttext);
gameDisplay.draw(startbuttontext);
gameDisplay.display();
}
}
};
things.h
#include <SFML/Graphics.hpp>
#include <iostream>
#include <cstdlib>
using namespace sf;
using namespace std;
#pragma once
int RandomXpos = 0;
class Thing
{
public:
void thingspawn(RenderWindow &gameDisplay, int &enemystartx, int &enemystarty, int &enemywidth, int &enemyheight, RectangleShape &thing, int enemyspeed)
{
thing.setFillColor(Color(255,255,255));
if (thing.getPosition().y < 800)
thing.move(0.0f, 0.4f);
if (thing.getPosition().y >= 800)
{
RandomXpos = rand() % 1000;
thing.setPosition(RandomXpos, -200);
}
}
};
的main.cpp
#include <iostream>
#include <SFML/Graphics.hpp>
#include "things.h"
#include "Main Menu.h"
#include <cstdlib>
#include <Windows.h>
using namespace std;
using namespace sf;
int main()
{
//FreeConsole();
RenderWindow gameDisplay(VideoMode(1366, 768), "Game", Style::Fullscreen);
gameDisplay.clear();
int enemystarty = -200;
int enemystartx = 300;
int enemyheight = 30;
int enemywidth = 300;
int enemyspeed = 0.3;
int enemycount = 1;
int dodged = 0;
int blockcolor = 0;
bool MainMenu = true;
Font font1;
if (!font1.loadFromFile("OCRAEXT.ttf"))
{
//error...
}
RectangleShape start(Vector2f(400, 100));
start.setFillColor(Color(0, 0, 0));
start.setOutlineThickness(20);
start.setOutlineColor(Color(255, 255, 255));
FloatRect startRect = start.getLocalBounds();
start.setOrigin(startRect.width / 2, startRect.height / 2);
start.setPosition(Vector2f(1366 / 2.0f, 768 - 450.0f));
/*
RectangleShape player(Vector2f(200, 50));
player.setFillColor(Color(0, 0, 255));
player.setPosition(400, 700);
*/
Texture playertexture;
if (!playertexture.loadFromFile("whiter_arrow.jpg"))
{
//error...
}
Sprite player;
player.setTexture(playertexture);
player.setPosition(300, 600);
RectangleShape thing(Vector2f(enemywidth, enemyheight));
thing.setPosition(300, -200);
Event evnt;
while (gameDisplay.isOpen())
{
while (gameDisplay.pollEvent(evnt))
{
switch (evnt.type)
{
case Event::Closed:
gameDisplay.close();
case Event::KeyPressed:
if (Keyboard::isKeyPressed(Keyboard::Q))
gameDisplay.close();
}
}
main_menu object;
object.startmenu(gameDisplay, font1, MainMenu, start, evnt);
while (MainMenu == false)
{
gameDisplay.setMouseCursorVisible(false);
if (Keyboard::isKeyPressed(Keyboard::D))
if (player.getPosition().x < 1200)
{
player.move(0.3f, 0.0f);
}
if (Keyboard::isKeyPressed(Keyboard::A))
if (player.getPosition().x > 50)
{
player.move(-0.3f, 0.0f);
}
if (Keyboard::isKeyPressed(Keyboard::Q))
gameDisplay.close();
Thing thingobject;
thingobject.thingspawn(gameDisplay, enemystartx, enemystarty, enemywidth, enemyheight, thing, enemyspeed);
//collision detection
if (player.getPosition().y <= thing.getPosition().y)
if (player.getPosition().x == thing.getPosition().x)
gameDisplay.close();
gameDisplay.clear();
gameDisplay.draw(player);
gameDisplay.draw(thing);
gameDisplay.display();
}
}
}
答案 0 :(得分:0)
有许多方法可以在对象集之间进行2D碰撞检测(“将这些对象中的任何一个相互接触”),这超出了本问题的范围。你似乎要问的更简单:“做两个2D矩形触摸?”。假设您有矩形r1和r2,那么您可以使用:
collision = r1.x <= r2.x + r2.width &&
r2.x <= r1.x + r1.width &&
r1.y <= r2.y + r2.height &&
r2.y <= r1.y + r1.height;
值得注意的是,在游戏中,由于物体速度与帧速率的关系,您必须考虑移动增量太大的可能性,允许物体看起来彼此相互移动。您可以通过构建包含两个对象的前/后位置的边界矩形进行补偿,然后再进行测试,然后再进行涉及扫掠时间体积交叉的更复杂的计算。
答案 1 :(得分:0)
有SFML方式来进行碰撞,它适用于您的情况。
你可以这样做:if ( player.getGlobalBounds().intersects(thing.getGlobalBounds()) )
{
// player and thing is collided! do something
}
@ Wheezil 的答案是标准的方法,对于轴对齐的对象,就像你的情况一样。自己实施它会更好,所以你知道它是如何发生的:)