Schüsse springen
Übersicht

BackbufferBetreff: Schüsse springen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo zusammen,
bei dem Spaceshooter den programmiere ist mir folgendes aufgefallen: Manchmal treffen die Schüsse das Ziel nicht. Zuerst dachte ich, dass es nur Einbildung ist, schließlich werden die Kollisionen pixelgenau überprüft. Jetzt glaube ich den Fehler gefunden zu haben. Jeder Schuss hat eine Geschwindigkeit, die angibt, wieviel pixel er sich pro frame bewegt. Ist das Ziel nun kleiner als diese Geschwindigkeit, dann springt der Schuss sozusagen über das Ziel. Wie kann ich das änder? |
||
da_poller |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
vieleicht wenn der abstand kleiner als geschwindigkeit ist als treffer gelten lassen...
ansonsten müsste es eig über imagescollide gehen... oder machst du das ohne images? |
||
![]() |
Jean |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mach doch den Schuss einfach in der Kollisionsabfrage um den "Sprung pro Frame" länger. Einfach anstelle von IMAGESCOLLIDE IMAGERECTCOLLIDE verwenden, da du dort die Länge / Breite des Schusses selbst definieren kannst. So sollte es klappen. | ||
Backbuffer |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
da_poller hat Folgendes geschrieben: vieleicht wenn der abstand kleiner als geschwindigkeit ist als treffer gelten lassen...
ansonsten müsste es eig über imagescollide gehen... oder machst du das ohne images? Ich verwende imagescollide. Das Problem ist eben nur das in der einen Abfrage, der Schuss vor dem Schiff ist und in der nächsten Abfrage ist er bereits hinter dem Schiff, so dass die Bilder nicht kollidieren, obwohl der Schuss "durch" das Schiff geflogen ist. Jean hat Folgendes geschrieben: Mach doch den Schuss einfach in der Kollisionsabfrage um den "Sprung pro Frame" länger. Einfach anstelle von IMAGESCOLLIDE IMAGERECTCOLLIDE verwenden, da du dort die Länge / Breite des Schusses selbst definieren kannst. So sollte es klappen.
Eigentlich eine gute Idee, aber es wirft ein anderes Problem auf. Wenn der Schuss sehr lang und schmal ist (Phaser-Strahl), würde ein Schuss der den Gegner in schräger Richtung knapp verfehlt zu einer Kollision führen. |
||
![]() |
kriD |
![]() Antworten mit Zitat ![]() |
---|---|---|
versuch doch mal mehrere zwischenstufen der flugbahn der schüsse auf kollision mit dem objekt zu überprüfen..
angenommen die geschwindigkeit des schusses beträgt 8, und das objekt ist nur 3 breit, dann "springt" der schuss ja meißtens über das objekt hinweg, weil es nie mit ihm kollidiert. wenn du nun aber die geschwindigkeit (8) noch weiter aufteilst und pro frame dann zB 4 oder 8 kollisionsberechnungen machst, also praktisch die flugbahn des geschosses auf kollision überprüfst (am besten mit ner for-schleife), dann bekommst du sicherlich eine kollision. du nimmst also an, dass dan geschoss die geschwindigkeit 1 hat und überprüfst auf kollision, danach nimmst du an, es habe die geschwindigkeit 2, dann 3 usw und mit jeder geschwindigkeit auf kollision prüfen.. dies hat allerdings den nachteil, dass so häufiges imagescollide-nutzen ziemlich performance frisst. lg kriD [/code] |
||
Wenn ich du wäre, wäre ich lieber ich! |
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn du es so machst, wie kriD beschrieben hat, würd ich das so machen :
Code: [AUSKLAPPEN] For s.schuss = Each schuss
For i = 1 to 8 ;8 ist hier die end geschwindigkeit... s\x = s\x + s\Cosin*i s\y = s\y + s\Sinus*i If RectsOverlap(VordersterPunktdesschusses_x,-_y,1,1,colobj_x,colobj_y,3,3) then bla. Next So kann man es machen, geht warscheinlich auch noch einfacher... mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
Backbuffer |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also, ich habe versucht euren Vorschlag umzusetzen, bin aber auf neue Probleme gestoßen.
Wenn ich den Schuss in Zwischenschritten prüfe führt das dazu, dass ich zwei Positionswerte des Schusse habe. Eimal, die wo er tatsächlich gemalt wird und einmal die fiktiven die ich für die collisionsabfrage verwende. Das führt dann aber effektiv dazu, dass das was man sieht nicht mit dem übereinstimmt, was berechnet wird. Z.B. wird das Schiff jetzt zwar getroffen, der Schuss ist aber optisch gesehen schon weiter und verschwindet damit erst hinter dem Schiff. Zwar könnte man diese Problem sicherlich irgendwie beheben, aber ich glaube nicht, dass es auf Dauer gut ist, wenn das was angezeigt wird etwas anderes ist als das, womit gerechnet wird. Vielleicht finde ich noch eine andere Lösung. |
||
![]() |
Moundblack |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie wäre es, wenn du deinen ganzen Code mal postest? ![]() ![]() Lg Thomas |
||
Backbuffer |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also ich weiß nicht, ob der Code hier wirklich weiter hilft. Aber schaden kanns auch nicht.
Hier wird der Schuss erstellt: Code: [AUSKLAPPEN] If KeyDown(57) Then
shot.t_Shot = New t_Shot ;hier wird der schuss erstellt If player\current_weapon = 0 And player\blaster = 1 Then shot\t_weaponstyle = blaster If player\current_weapon = 1 And player\ionbolt= 1 Then shot\t_weaponstyle = ionbolt If player\current_weapon = 2 And player\laser= 1 Then shot\t_weaponstyle = laser If player\current_weapon = 3 And player\phaser= 1 Then shot\t_weaponstyle = phaser shot\deltax =player\xspeed shot\deltay = player\yspeed shot\direction = player\heading ;Schussrichtung ist Blickrichtung des Schiffes shot\xpos = player\xpos-shot\deltax+Cos(shot\direction)*8 ;Schuss ensteht auf Spielerposition mit kleinen Abstand (8 pixel), dessen Richtung vom Winkel abhängt shot\ypos = player\ypos-shot\deltay+Sin(shot\direction)*8 ;Schuss ensteht auf Spielerposition mit kleinen Abstand, (8 pixel)dessen Richtung vom Winkel abhängt shot\owner = player\ship_id ;Besitzer des Schusses ist der Spieler If player\timer_shot < MilliSecs() And player\cur_energy >= shot\t_weaponstyle\energy_cost Then PlaySound shot\t_weaponstyle\sound player\timer_shot = MilliSecs() + shot\t_weaponstyle\firerate player\cur_energy = player\cur_energy - shot\t_weaponstyle\energy_cost If player\cur_energy < 0 Then player\cur_energy = 0 Else Delete shot End If End If End If End Function Und hier ist die Kollisionsabfrage: Code: [AUSKLAPPEN] Function test_collision()
For shot.t_Shot = Each t_Shot ;jeder Schuss wird durchlaufen shot\xpos = shot\deltax + shot\xpos + Cos(shot\direction) * shot\t_weaponstyle\speed shot\ypos = shot\deltay + shot\ypos + Sin(shot\direction) * shot\t_weaponstyle\speed ;Position des Schuss wird durch Geschwindigkeit in Winkelrichtung modifiziert, shot\delta ist die Geschwindigkeit des Raumschiffes (so wird ein "nachziehen" des Schusses im Schrägflug verhindert) player = First t_Ship ;Zeile damit die ship\... variablen gelesen werden können If shot\owner = player\ship_id Then ;wenn schuss von Spieler abgefeuert wurde DrawImage shot_gfx(Floor(shot\direction/imagestep)*imagestep, shot\t_weaponstyle\image), shot\xpos+player\xdistance, shot\ypos+player\ydistance ;Schuss wird an relativer position gemalt, dabei wird die Schussrichtung auf den nächsten imagestep gerundet, For ship.t_ship = Each t_ship ;jeder Gegner wird durchgegangen If ship\player=0 And ImagesCollide (shot_gfx(Floor(shot\direction/imagestep)*imagestep, shot\t_weaponstyle\image), shot\xpos, shot\ypos,0, ship_gfx(Floor(ship\heading/imagestep)*imagestep,ship\t_shipstyle\image,ship\image_booster), ship\xpos, ship\ypos,0) Then ;die Bilder vom Schuss und vom Gegner werden auf den absoluten Positionen auf Kollision verglichen If ship\cur_shield > shot\t_weaponstyle\damage Then PlaySound shield_hit_sfx DrawImage shield_gfx(ship\t_shipstyle\size), ship\xpos+player\xdistance, ship\ypos+player\ydistance ship\cur_shield=ship\cur_shield-shot\t_weaponstyle\damage ;bei treffer wird gegnerschild um Waffenschaden reduziert If ship\cur_shield < 0 Then ship\cur_shield = 0 shot\remove=1 ;Schuss wird zum löschen vorgemerkt Else If 0 < ship\cur_shield < shot\t_weaponstyle\damage Then PlaySound hull_hit_sfx DrawImage hit_gfx, ship\xpos+player\xdistance, ship\ypos+player\ydistance ship\cur_hull = ship\cur_hull+ship\cur_shield-shot\t_weaponstyle\damage ship\cur_shield = 0 shot\remove=1 ;Schuss wird zum löschen vorgemerkt Else If ship\cur_shield <= 0 Then PlaySound hull_hit_sfx DrawImage hit_gfx, ship\xpos+player\xdistance, ship\ypos+player\ydistance ship\cur_hull=ship\cur_hull - shot\t_weaponstyle\damage ;bei treffer wird gegnerschild um Waffenschaden reduziert shot\remove=1 ;Schuss wird zum löschen vorgemerkt End If End If If ship\cur_hull <= 0 Then ;wenn Gegner kein rumpf mehr hat explosion.t_explosion= New t_explosion explosion\next_frame = 1 explosion\max_frame = 16 explosion\xpos=ship\xpos explosion\ypos=ship\ypos ship\remove = 1 ;Gegner wird zum löschen vorgemerkt End If End If Next If Sqr((shot\xpos-player\xpos)^2+(shot\ypos-player\ypos)^2 ) > shot\t_weaponstyle\range Then shot\remove = 1 ;wenn Schuss die Waffenreichweite überschreitet wird er zum löschen vorgemerkt Else For ship.t_ship = Each t_ship If shot\owner = ship\ship_id Then ;wenn schuss von Gegner abgefeuert wurde ;ship.t_ship = Object.t_ship(ship\ship_id) If Sqr((shot\xpos-ship\xpos)^2+(shot\ypos-ship\ypos)^2) > shot\t_weaponstyle\range Then shot\remove = 1 ;wenn Schuss die Waffenreichweite überschreitet wird zum löschen vorgemerkt ;For player.t_ship = Each t_ship ;für jedes Spielerschiff ein durchlauf DrawImage shot_gfx(Floor(shot\direction/imagestep)*imagestep, shot\t_weaponstyle\image), shot\xpos+player\xdistance, shot\ypos+player\ydistance ;Schuss wird gemalt If ImagesCollide (shot_gfx(Floor(shot\direction/imagestep)*imagestep,shot\t_weaponstyle\image), shot\xpos, shot\ypos,0, ship_gfx(Floor(player\heading/imagestep)*imagestep,player\t_shipstyle\image,player\image_booster), player\xpos, player\ypos,0) Then ;die Bilder vom Schuss und vom Spieler werden auf den absoluten Positionen auf Kollision verglichen If player\cur_shield > shot\t_weaponstyle\damage Then PlaySound shield_hit_sfx DrawImage shield_gfx(player\t_shipstyle\size), screenwidth/2, screenheight/2 player\cur_shield=player\cur_shield-shot\t_weaponstyle\damage ;bei treffer wird gegnerschild um Waffenschaden reduziert If player\cur_shield < 0 Then player\cur_shield = 0 shot\remove=1 ;Schuss wird zum löschen vorgemerkt Else If 0 < player\cur_shield < shot\t_weaponstyle\damage Then PlaySound hull_hit_sfx DrawImage hit_gfx, screenwidth/2, screenheight/2 player\cur_hull = player\cur_hull+player\cur_shield-shot\t_weaponstyle\damage player\cur_shield = 0 shot\remove=1 ;Schuss wird zum löschen vorgemerkt Else If player\cur_shield <= 0 Then PlaySound hull_hit_sfx DrawImage hit_gfx, screenwidth/2, screenheight/2 player\cur_hull=player\cur_hull-shot\t_weaponstyle\damage ;bei treffer wird gegnerschild um Waffenschaden reduziert shot\remove=1 ;Schuss wird zum löschen vorgemerkt End If End If If player\cur_hull <= 0 Then ;wenn spieler kein rumpf mehr hat player_dead = 1 explosion.t_explosion= New t_explosion explosion\next_frame = 1 explosion\max_frame = 16 explosion\xpos=player\xpos explosion\ypos=player\ypos ;player\remove = 1 ;Gegner wird zum löschen vorgemerkt ;ship\remove = 1 ;Gegner wird zum löschen vorgemerkt End If End If ;Next End If Next End If Next End Function |
||
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
villeichnt kannst du je wenn du bei 8 pixeln pro schleife einfach bei pixel 4 und 8 was malen, dann wieder bei 4 und dann bei 8...
mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Dein Problem (flasche Zeichenposition) lässt sich ganz einfach lösen wenn Du das Zeichnen der Schüsse erst nach der Kollisionsprüfung vornimmst.
Du machst die schrittweise Kollisionsprüfung (Wobei als Schrittweite für die Kollision die kleinste Seitenlänge eines Gegner genügt). Sollte die einen Treffer ergeben wird als Schussposition die Position eingesetzt bei der der Treffer erfolgte (und die Kollisionsprüfung verlassen). So hast Du Kollision und korrekte Position unter einem Hut. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group