2017-03-05 6 views
0

Ich versuche, ein Spiel zu machen, wo Sie gaben, um die eingehende Box auszuweichen (Sache). Ich weiß nicht, wie man eine schnelle und einfache Kollisionserkennung mit if-Anweisungen programmiert. Ich habe versucht, dies bei "// Kollisionserkennung" zu programmieren. Ich will es so, dass, wenn der Pfeil (Spieler) die Box berührt, das Spiel schließt.C++ SFML Collison Detection

Haupt 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(); 

    } 



    } 
    } 

Antwort

0

Es gibt viele Möglichkeiten 2D-Kollisionserkennung zwischen den Sätzen von Objekten zu tun (“ berühren sich irgendwelche dieser Objekte ") und das geht über den Rahmen dieser Frage hinaus. Was Sie zu fragen scheinen, ist viel einfacher: "Berühren sich zwei 2D Rechtecke?". Nehmen wir an, Sie Rechtecke R1 und R2 haben, dann können Sie verwenden:

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; 

Es ist auch erwähnenswert, dass in den Spielen Sie die Möglichkeit vs Framerate wegen der Objektgeschwindigkeit des Bewegungsschritt ist zu groß ermöglichen muss Objekte können sich scheinbar durcheinander bewegen. Sie können dies kompensieren, indem Sie umgrenzende Rechtecke erstellen, die die Vorher/Nachher-Positionen der beiden Objekte umfassen, und diese zuerst testen, bevor Sie in komplexere Berechnungen eintauchen, die den Schnittpunkt der durchgestrichenen Zeitvolumina beinhalten.

+0

danke yo, ich habe es geschafft, einen Weg zu einer Kollisionserkennung ohne Verwendung einer Bounding Box zu erstellen, aber danke: 3 –

0

Es gibt SFML Weg, um die Kollision zu tun, es wird für Ihren Fall arbeiten.

können Sie es wie folgt tun:

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

@Wheezil ‚s Antwort ist der normale Weg, es zu tun, für die Achse ausgerichtet Objekt wie der Fall sein. es ist besser, es selbst zu implementieren, damit Sie wissen, wie es passiert :)