Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

09.03.2014, 01:23

c++/SDL 2d Collision

Hallo

Ich schreibe ja momentan an ein space shooter
nun habe ich ein problem mit der collision zwischen
2 bmps die ich via Sdl_blittSurface darstelle

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SDL_Rect shoot_Position;
    shoot_Position.x = imagePosition.x;
    shoot_Position.y = imagePosition.y; 
    
SDL_Rect EnemyPosition;
    EnemyPosition.x = rand() %  700 + 100;
    EnemyPosition.y = 20;   

...

  if (shoot_event == 1)
        {        
         SDL_BlitSurface(shoot, 0, screen, &shoot_Position);
          shoot_Position.y -= 10;
          
          if(shoot_Position.y < 5)
          {
           shoot_event = 0;
           shoot_Position.y = imagePosition.y;
           shoot_Position.x = imagePosition.x;
          }
       }
...


für die collision hab ich versucht die größe der bmps zu deffiniren

C-/C++-Quelltext

1
2
3
#define SHOOT_LENGHT 6  // shoot.bmp (6x12)
#define SHOOT_WIGHT 12
... ect...


So und jetzt zum problem:

Was mache ich bei der collisionsabfrage falsch ?

C-/C++-Quelltext

1
2
3
4
5
If ( shoot_Position.x + SHOOT_LENGHT == EnemyPosition.x + ENEMY_LENGHT &&
     shoot_Position.y + SHOOT_WIGHT == EnemyPosition.y + ENEMY_WIGHT)
{
  // ...
}
:hmm:

Versuche ich die feine abzuschießen, so schieß ich einfach hindurch

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

2

09.03.2014, 01:32

Überlege mal, was passieren muss, damit du triffst, und was du überprüfst.

EDIT: Eigentlich bin ich kein Fan von Rechtschreib-Hinweisen aber:

Wight = Wicht
Width = Breite

Lenght = ---
Length = Länge
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

3

09.03.2014, 02:59

... bearbeitet...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Patty1991« (09.03.2014, 11:14)


4

09.03.2014, 11:10

HABS !!! 8)

Ich habs jetzt mit dem 3d Gamestudio - aum82 Magazine (online monatsmagazine) gemacht
Ich hab die kollisionsabfrage übernommen und umgeschrieben , die dort für ein 2d tutorial für lite ç gezeight wird
Und tästsächlich funktioniert das ganze in sdl/c++ :thumbsup:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  if ((((shoot_Position.x + shoot_width >= EnemyPosition.x) && 
         (shoot_Position.x + shoot_width <= EnemyPosition.x + enemy_width)) ||
        ((EnemyPosition.x + enemy_width >= shoot_Position.x) && 
         (EnemyPosition.x + enemy_width <= shoot_Position.x + shoot_width))) && 
       (((shoot_Position.y + shoot_height >= EnemyPosition.y) &&
        (shoot_Position.y + shoot_height <= EnemyPosition.y + enemy_height)) ||
        ((EnemyPosition.y + enemy_height >= shoot_Position.y) && 
        (EnemyPosition.y + enemy_height <= shoot_Position.y + shoot_height))))
        
          {
           shoot_event = 0; 
           shoot_Position.y = imagePosition.y;
           shoot_Position.x = imagePosition.x; 
           EnemyPosition.y = 20;    
          }

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Patty1991« (09.03.2014, 11:21)


Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

5

09.03.2014, 11:14

Kannst du mir die kollisition mal schnell als codeschnippsel (am besten funkionierend) posten ?
der feind were 32x32 und der schuss 6x12 groß

Nein, ich poste dir keinen Codeschnipsel. Selber lernen hilft am meisten ;)

- Nur die if schleife mit den defines

Es gibt keine If-Schleifen, nur If-Abfragen.

Abgesehn von den rechtschreibfehlern muss doch folgendes passieren: :D

Damit eine kollision statt finden kann, muss doch schuss.x und y mit der position des feindes übereinstimmen,
da sie sich aber beide bewegen können sie sich nicht treffen - hier kommen jetz die defines ins spiel

Die kollision soll nich pixelgenau sein, sondern nur "treffend" 8o

Wieso auch immer die Defines bei diesem Problem helfen sollen verstehe ich nicht ganz (Abgesehen davon mag ich Defines sowieso nicht und benutze lieber const, aber das ist in einem solchen Fall Geschmackssache :))
Abgesehen davon hast du einen Denkfehler. Überlege mal, was schuss.x/y sind, und was die Position deines Feindes ist (qualitativ, nicht quantitativ).

Ein weiterer Tipp: Schüsse und Feinde sind Flächen, keine Punkte.

Edit: Schön, dass du es jetzt per Copy-Paste gelöst hast. Aber verstehst du die Lösung auch? Das ist das wichtigste. Niemals fremden Code verwenden, wenn man ihn nicht versteht.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

6

09.03.2014, 11:28

2 sachen noch: gibt es eine art *timestep für flüssige bewegungen weil object.x +=30; schlaüft ein bisschen sprunghaft
Und: warum ist die kollisionsabfrage soweit und kompliziert ausgeklammert (((...(...
- verstehn tuh ich es ansonsten

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

12.03.2014, 17:50

Ich finde, dass man sollte für Spielinterne Koordinaten keine Pixel verwenden sollte. Muss man dies dennoch machen sollte man dennoch keine Ganzzahlen für die Positionsangaben verwenden. Macht man das, kann man seinen Charakter ohne Probleme je Frame um weniger als 1 Pixel bewegen. Hat man Ganzzahlen, kann man seinen Charakter nur um eine feste Anzahl an Pixel/Frame bewegen, läuft das Spiel also mit 60 FPS ist die Geschwindigkeit des Charakters immer ein Vielfaches von 60 Pixel/Sekunde.

Die Bedingung ist einfach übermäßig mit Klammern ausgestattet. Werden alle unnötigen Klammern entfernt, landet man bei folgender Bedingung (für das if muss natürlich noch ein Klammernpaar drum herum):

Quellcode

1
2
3
4
((shoot_Position.x + shoot_width >= EnemyPosition.x && shoot_Position.x + shoot_width <= EnemyPosition.x + enemy_width) ||
 (EnemyPosition.x + enemy_width >= shoot_Position.x && EnemyPosition.x + enemy_width <= shoot_Position.x + shoot_width)) && 
((shoot_Position.y + shoot_height >= EnemyPosition.y && shoot_Position.y + shoot_height <= EnemyPosition.y + enemy_height) ||
 (EnemyPosition.y + enemy_height >= shoot_Position.y && EnemyPosition.y + enemy_height <= shoot_Position.y + shoot_height))

Hier lässt sich aber wieder eine Unschönheit erkennen: Man sollte seine Elemente grundsätzlich anhand ihres Mittelpunkts positionieren, nicht aber anhand einer ihrer Ecken. Drehungen sind bspw. nur dann problemlos möglich, wenn die Drehung um den Mittelpunkt durchgeführt wird (und die Berechnung auch anhand des Mittelpunkts arbeitet).
Der obige Code ist immernoch so umfangreich, da geprüft wird, ob die beiden Rechtecke sich berühren. Würde man prüfen, ob sie sich _nicht_ berühren und das Ergebnis negieren, würde man bei folgendem Code landen (bei dem bereits von einer Positionierung anhand des Mittelpunkts ausgegangen wird):

Quellcode

1
2
!(shoot_Position.x + shoot_width/2 < enemyPosition.x - enemy_width/2 && shoot_Position.x - shoot_width/2 > enemyPosition.x + enemy_width/2 ||
shoot_Position.y + shoot_height/2 < enemyPosition.y - enemy_height/2 && shoot_Position.y - shoot_height/2 > enemyPosition.y + enemy_height/2)

Und grundsätzlich lässt sich sagen, dass diese Prüfung ausgelagert werden sollte, da diese an vielen Stellen wahrscheinlich noch benötigt wird. Auch wird bisher davon ausgegangen, dass es sich bei den Elementen um Rechtecke handelt, obwohl Kreise evtl. besser geeignet sein könnten. Die Berechnung bei Kreisen (nicht bei Ellipsen) wäre (wenn konsequent Vektoren verwendet werden würden, die Operatoren überladen sind und sqrMagnitude das Quadrat der Länge des Vektors darstellt):

Quellcode

1
(shoot_size - enemy_size).sqrMagnitude < (shoot_Position - enemyPosition).sqrMagnitude


Es gibt durchaus noch diverse Stellen, an denen noch das Eine oder Andere verbessert werden könnte.
Ein wichtiges Beispiel wäre da noch die Benennung, die nicht ganz einheitlich ist. Mal sind Variablen kleingeschrieben_mit_unterstrichen, mal camelCase und dann wieder camel_Case_Mit_Unterstrichen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige