Kolizja wielu obiektów
Ostatnio zmodyfikowano 2017-04-25 12:26
aaadam Temat założony przez niniejszego użytkownika |
Kolizja wielu obiektów » 2017-04-24 15:53:36 Witam, piszę grę, zastanawiam się jak dobrze zaimplementować przekazywanie wartości kolizyjnych ile dodać lub odjąć hp o ile zwiększć damage itp. (sama kwestia kolizji jest zaimplementowana)Posiadam kilka konterów EntityManager które puszuje pochodnymi obiektami od Entity. Oczywiście mogę to w jakiś 'łopatologiczny sposób zrobić ' ale zastanawiam się nad 'dobrym' podejściem. Zastanawiam się nad storzeniem obiektu colision_instance i dodać go do elementu entity i tam jakos to zaprogamować. Prosze o porade. Trochę kodu poniżej Moja klasa która zawiera wszystkie managery #pragma once #include "GameScreen.h" #include "EntityManager.h" #include "ScreenManager.h" #include "Camera.h" #include "Map.h" #include "GamePlayScreenLayout.h" class GamePlayScreen : public GameScreen { private: Map map; EntityManager player; EntityManager enemies; EntityManager bullets; EntityManager enemies_bullets; Camera GameCamera; GamePlayScreenLayout layout; public: void GetInput( sf::Event & event ); void Update( float time, sf::RenderWindow & Window ); void Draw( sf::RenderWindow & Window ); void LoadContent(); void UnLoadContent(); bool Delay(); GamePlayScreen(); ~GamePlayScreen(); };
klaasa entityManager : #pragma once #include "Player.h" #include "Enemy_Red.h" #include "Enemy_Brown.h" #include "Enemy_Black.h" #include "Bullet.h" #include <vector> #include <string> class EntityManager { public: std::vector < Entity *> entities; void GetInput( sf::Event & event ); void Update( float time, sf::Vector2f cameraPosition ); void Draw( sf::RenderWindow & Window, sf::Vector2f CameraPosition ); void LoadContent( std::string type ); virtual void UnLoadContent(); void EntityCollision( EntityManager & e2 ); EntityManager(); ~EntityManager(); };
void EntityManager::EntityCollision( EntityManager & e2 ) { for( unsigned int i = 0; i < entities.size(); i++ ) { for( unsigned int j = 0; j < e2.entities.size(); j++ ) { if( entities[ i ]->state != Entity::ExplosionAnimation && e2.entities[ j ]->state != Entity::ExplosionAnimation ) { if( entities[ i ]->rekt->Intersects_pixel_perfect( * e2.entities[ j ]->rekt, entities[ 0 ]->mask, e2.entities[ 0 ]->mask ) ) { e2.entities[ j ]->OnCollision(); entities[ i ]->OnCollision(); } } } } }
kod kolizji playera tak samo działa na każdą kolizje czy to z enemy czy to z enemy_bullet lub Tile czyli mapa a chcę to rozróżnić dla każdego typu kolizji void Player::OnCollision() { this->hp -= 1; position = prevPosition; if( direction == Right ) this->position.x = position.x - moveSpeed; if( direction == Left ) this->position.x = position.x + moveSpeed; if( direction == Up ) this->position.y = position.y + moveSpeed; if( direction == Down ) this->position.y = position.y - moveSpeed; sprite.setPosition( position ); delete rekt; rekt = new FloatRekt( this->position.x, this->position.y, spriteSize.x, spriteSize.y ); }
|
|
Rashmistrz |
» 2017-04-24 20:04:22 Nie rozumiem problemu. (sama kwestia kolizji jest zaimplementowana) |
? ile dodać lub odjąć hp o ile zwiększć damage itp. |
Co to ma do kolizji? (Oprócz tego, że zdarzeniem aktywującym jest kolizja.) |
|
aaadam Temat założony przez niniejszego użytkownika |
» 2017-04-25 08:50:24 hmm widzę, że źle przedstawiłem Problem... spróbuje troche inaczej : mam klasę entity która służy do dziedziczenia przez obiekty enemy, Player, bullet itp, ma ona w sobie virtualną funkcje : virtual void OnCollision();
która zawsze jest tworzona w klasach pochodnych. Ta funkcja jest wywoływana wówczas kiedy zachodzi kolizja. Mam klasę GamePlayScreen która odpowiedzialna za wszystko co się dzieje podczas działania gry... kod update : void GamePlayScreen::Update( float time, sf::RenderWindow & Window ) { layout.Update( time, player.entities[ 0 ]->hp, GameCamera.position ); GameCamera.Update( Window, player.entities[ 0 ]->position ); map.Update( time, GameCamera.position ); player.Update( time, GameCamera.position ); enemies.Update( time, GameCamera.position ); bullets.Update( time, GameCamera.position ); player.EntityCollision( enemies ); enemies.EntityCollision( bullets ); map.Collision( player ); map.Collision( bullets ); }
widać tutaj że np ta linijka kodu : player.EntityCollision(enemies); odpowiedzialna jest na wykrywanie kolizji playera z enemy itp każdy ten typ Player, enemies,bullets jest typu entitymanager który zawiera Vektor typu entity : class EntityManager { public: std::vector < Entity *> entities; void GetInput( sf::Event & event ); void Update( float time, sf::Vector2f cameraPosition ); void Draw( sf::RenderWindow & Window, sf::Vector2f CameraPosition ); void LoadContent( std::string type ); virtual void UnLoadContent(); void EntityCollision( EntityManager & e2 ); EntityManager(); ~EntityManager(); };
a to jest fukncja entityColision : void EntityManager::EntityCollision( EntityManager & e2 ) { for( unsigned int i = 0; i < entities.size(); i++ ) { for( unsigned int j = 0; j < e2.entities.size(); j++ ) { if( entities[ i ]->state != Entity::ExplosionAnimation && e2.entities[ j ]->state != Entity::ExplosionAnimation ) { if( entities[ i ]->rekt->Intersects_pixel_perfect( * e2.entities[ j ]->rekt, entities[ 0 ]->mask, e2.entities[ 0 ]->mask ) ) { e2.entities[ j ]->OnCollision(); entities[ i ]->OnCollision(); } } } } }
chcę jakoś przekazać parametr do e2.entities[j]->OnCollision(); oraz entities ->OnCollision(); i zastanawiam się jak to dobrze zoorgranizować żeby rozróżnić kolizje różnego typu np playera z enemy playera z mapą playera z pociskami przeciwników... wydaje mi się ze mogę poprostu przekazać parametr do fukncji :
player.EntityCollision( enemies, std::string( "Player/enemy" ) );
i w funkcji playera dac ifa ...
void Player::OnCollision( std::string typeColision ) { if( typeColision == "Player/enemy" ) { this->hp -= 1; position = prevPosition; if( direction == Right ) this->position.x = position.x - moveSpeed; if( direction == Left ) this->position.x = position.x + moveSpeed; if( direction == Up ) this->position.y = position.y + moveSpeed; if( direction == Down ) this->position.y = position.y - moveSpeed; sprite.setPosition( position ); delete rekt; rekt = new FloatRekt( this->position.x, this->position.y, spriteSize.x, spriteSize.y ); } else if( std::string typeColision == "Player/map" ) itp }
ale może da się to w jakiś lepszy sposób osiągnąć bo przekazywanie tego parametru wydaje mi się trochę nie elegancke mam nadzieje że przedstawiłem teraz dobrze o co mi chodzi
|
|
1aam2am1 |
» 2017-04-25 12:26:40 http://cpp0x.pl/kursy/Wzorce-projektowe/Wzorce-czynnosciowe/odwiedzajacy/282 |
|
« 1 » |