2017-03-05 33 views
0

我试图做一个游戏,你给闪躲进来的盒子(东西)。我不知道如何使用if语句来编写快速而简单的碰撞检测。 我试图在“碰撞检测”中对此进行编码。我需要它,以便如果箭头(玩家)触摸游戏关闭的框。C++ SFML科里森检测

主要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

有很多方法可以做到集对象之间的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; 

还值得一提的是,在游戏中,你必须考虑到此举增量是因为物体速度VS帧速率过大的可能性,允许物体看起来相互移动。您可以通过构建包围两个对象的前/后位置的边界矩形进行补偿,并在进行涉及交叉扫描时间交集的更复杂计算之前首先进行测试。

+0

感谢哟,我已成功地制定出一个方法来创建一个科里森检测不使用边界框,但感谢:3 –

0

有SFML的方式来做碰撞,它会适用于你的情况。

,你可以做这样的:

if (player.getGlobalBounds().intersects(thing.getGlobalBounds())) 
{ 
     // player and thing is collided! do something 
} 

@Wheezil的回答是这样做,像你的情况轴线对齐对象的标准方式。这是更好地实现它自己,所以你知道是怎么回事了:)