Frage wegen meinem 2D Shooter..

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Xsoft
Beiträge: 15
Registriert: 24.09.2004 18:17
Wohnort: Hessen
Kontaktdaten:

Frage wegen meinem 2D Shooter..

Beitrag von Xsoft »

Hallo,

/edit: das mit schiessen ist nun geklärt, und die kollision klappt auch zur hälfte !
Zuletzt geändert von Xsoft am 26.09.2004 13:45, insgesamt 1-mal geändert.
Windows XP Home Edition - SP1 - Pure Basic 3.93 - jaPBe
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Bei Geschossen würde ich eine Linked List verwenden. Dann noch eine Structure welche die Daten des Geschosses enthält.
Etwa so:

Code: Alles auswählen

structure geschoss_struc
  pos_x.w
  pos_y.w
  graphic.w
  damage.w
  speed_x.w
  speed_y.w
  abs_speed.w
endstructure

newlist bullet.geschoss_struc()
Wenn du jetzt schießt, einfach ein Element der Liste hinzufügen und die Eigeneschafen wie Pos_x, Pos_y, Speed_x, Speed_y und so setzen. Dann im Programmcode weiter unten eine Schleife welche jedes Listenelement durchläuft und bewegt:

Code: Alles auswählen

foreach bullet()
bullet()\pos_x = bullet()\pos_x + bullet()\speed_x
bullet()\pos_y = bullet()\pos_y + bullet()\speed_y
next bullet()
Dabei ist zu berücksichtigen, dass der Speed so gesetzt ist, dass die Richtung auch passt. Also, wenn der Schuss nach links gefeuert wird, dass dann speed_x = abs_speed und speed_y = 0 wird. (abs_speed enthält den gesamten Speed des Geschosses ohne Richtung. Also etwa 20.)
Beim Schuss nach oben muss dann speed_x = 0 sein und speed_y = -abs_speed.

Wenn du Schüsse hast, welche im 360 Grad winkel beliebig jeden Winkel annehmen können, musst du das per SInus, Cosinus und co. errechnen, welchen Wert Speed_x und Speed_y annehmen bei entsprechendem WInkel. Dabei hilft dir jetzt die Nutzung von abs_speed. Denn du musst den Vektor zerlegen in X und Y Richtung, und das geht dann wenn man die gesamtgeschwindigkeit kennt und den Winkel.

Mit dieser Formel kann man den Speed_x berechnen:

Code: Alles auswählen

bullet()\speed_x = (Cos(2 * 3.14 * ##WINKEL## / 360) * bullet()\abs_speed)
WICHTIG: ##WINKEL## muss natürlich durch den eigenen Winkel ersetzt werden. ALso durch den Schusswinkel des Geschosses.
Für Y rechnet man den Speed übrigends auch so aus wie oben, nur anstelle von Cosinus muss man Sinus nehmen.

Ich hoffe das hilft dir etwas mit den Geschossen. So kann man das zumindest machen und dann die Geschwindigkeit für die einzelnen Richtungen errechnen. Vektor zerlegen in X und Y und den Speed zur Position hinzufügen.

// Alle Codes sind nicht getestet sondern aus dem "Stand" aufgeschrieben. Schreibfehler können somit vorhanden sein.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

@Xsoft: Wenn du Zeit hast, kannst du auch den Sourcecode meines Spieles TankBlaster (http://mypage.bluewin.ch/remimeier/zip/TankBlaster.zip) analysieren. Sollte alles drinn sein, was du brauchst.

greetz
remi
Benutzeravatar
Xsoft
Beiträge: 15
Registriert: 24.09.2004 18:17
Wohnort: Hessen
Kontaktdaten:

Beitrag von Xsoft »

vielen dank euch zwei.
es funzt wunderbar !! fehlt nur noch die kollision !! *such*
Windows XP Home Edition - SP1 - Pure Basic 3.93 - jaPBe
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

collision könntest du so machen, dass du nach dem Bewegen des Spielers prüfst, ob er mit einem anderen Sprite kollidiert (per spritepixelcollision()) und dir die zuletzt gegangene Richtung des Spielers merkst. Wenn jetzt eine Berührung stattfindet, einfach in Gegenrichtung um 1 pixel verschieben und wieder au kollision prüfen. Das musst du dann solange machen, bis keine Kollision mehr auftritt. Und erst am Ende, wenn keine Kollision mehr ist, wird das Sprite angezeigt, dadurch bemerkt man nicht, dass der Spieler übrspünglich in das andere Sprite hinein gelaufen war und wieder "rausgeschoben" wurde. ;)
Und da du ja sowieso nur 2 Wege hast, links und rechts, sollte sich die Sache mit der Kollision recht einfach gestalten.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Mal ein kleines, unauskommentiertes Beispiel:

Code: Alles auswählen

InitSprite()
InitKeyboard()

Structure Point2D
  X.f
  Y.f
EndStructure

Global Tank.Point2D, TilesX, TilesY

TilesX = 1024/32
TilesY = 768/32

Dim Map.l(TilesX-1, TilesY-1)

Procedure CheckCollision(SpeedX.f, SpeedY.f)
  For x=0 To TilesX-1
    For y=0 To TilesY-1
      If Map(x, y) <> 0
        If SpriteCollision(0, Int(Tank\X + SpeedX), Int(Tank\Y + SpeedY), Map(x, y), x*32, y*32)
          ProcedureReturn 1
        EndIf
      EndIf
    Next y
  Next x
EndProcedure

OpenScreen(1024, 768, 32, "")

CreateSprite(0, 32, 32) ;Panzer
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, RGB(128, 128, 128))
StopDrawing()

CreateSprite(1, 64, 64) ;Objekt 1
StartDrawing(SpriteOutput(1))
Box(0, 0, 64, 64, RGB(128, 0, 0))
StopDrawing()

CreateSprite(2, 32, 32) ;Objekt 2
StartDrawing(SpriteOutput(2))
Box(0, 0, 32, 32, RGB(0, 0, 128))
StopDrawing()

Tank\X = 32
Tank\Y = 32

For x=0 To TilesX-1
  For y=0 To TilesY-1
    If x = 0 Or y = 0 Or y = TilesY-1 Or x = TilesX-1
      Map(x, y) = 2
    ElseIf x = Int(TilesX/2)-1 And y = Int(TilesY/2)-1
      Map(x, y) = 1
    EndIf
  Next y
Next x

Repeat
  ExamineKeyboard()
  
  ClearScreen(0, 128, 0)
  
  
  For x=0 To TilesX-1
    For y=0 To TilesY-1
      If Map(x, y) <> 0
        DisplaySprite(Map(x, y), x*32, y*32)
      EndIf
    Next y
  Next x
  If KeyboardPushed(#PB_KEY_UP)
    If CheckCollision(0, -0.5) = 0
      Tank\Y - 0.5
    EndIf
  ElseIf KeyboardPushed(#PB_KEY_DOWN)
    If CheckCollision(0, 0.5) = 0
      Tank\Y + 0.5
    EndIf
  EndIf
  
  If KeyboardPushed(#PB_KEY_LEFT)
    If CheckCollision(-0.5, 0) = 0
      Tank\X - 0.5
    EndIf
  ElseIf KeyboardPushed(#PB_KEY_RIGHT)
    If CheckCollision(0.5, 0) = 0
      Tank\X + 0.5
    EndIf
  EndIf
  
  DisplaySprite(0, Tank\X, Tank\Y)
  
  FlipBuffers(0)
Until KeyboardPushed(#PB_KEY_ESCAPE)
End
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
Xsoft
Beiträge: 15
Registriert: 24.09.2004 18:17
Wohnort: Hessen
Kontaktdaten:

Beitrag von Xsoft »

jo danke euch zwei..ich werds mal versuchen, die kollision zu machen!

wenn ich noch fragen hab, dann melde ich mich !!!


mfg xsoft
Windows XP Home Edition - SP1 - Pure Basic 3.93 - jaPBe
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Sunny hat geschrieben:

Code: Alles auswählen

Structure geschoss_struc
  pos_x.w
  pos_y.w
  graphic.w
  damage.w
  speed_x.w
  speed_y.w
  abs_speed.w
EndStructure
Auweia...
Ich würde für Spiele niemals Words benutzen. Aber auch keine Longs. Sondern wohl eher Floats. Wie will man denn sonst langsame und genaue Bewegungen erstellen?

Sollte also eher so aussehen:

Code: Alles auswählen

Structure geschoss_struc
  pos_x.f
  pos_y.f
  graphic.l
  damage.f
  speed_x.f
  speed_y.f
  abs_speed.f
EndStructure
Benutzeravatar
Xsoft
Beiträge: 15
Registriert: 24.09.2004 18:17
Wohnort: Hessen
Kontaktdaten:

Beitrag von Xsoft »

also ich hab das von sunny reingebaut, funzt wunderbar.
Nochmal danke an Sunny.
Jedenfalls habe ich probs mit der Kollision !
naja irgendwie muss ich es hinkriegen !

mfg
Windows XP Home Edition - SP1 - Pure Basic 3.93 - jaPBe
Antworten