Seite 1 von 2

Pong - Ball

Verfasst: 10.02.2012 22:52
von Shiv0r
Hallo

Ich bin relativ neu, was PureBasic angeht. Aus diesem Grund wollte ich zuerst einmal ein 2D Pong programmieren.
Nun bin ich bei dem Ball hängen geblieben, weil ich nicht genau weiß, wie ich ihn bewegen soll.

Folgende Überlegungen habe ich gemacht:
- Ball bewegt sich auf einer Geraden g=m*x
- Winkel: m = tan(alpha) => alpha = arctan(m) (alpha wäre dann immer der Steigungswinkel der Geraden)
- beim Auftreffen auf "Wand" oder Schläger: alpha = beta (beta wäre dann der Austrittswinkel)
-> dadurch bleibt die Steigung konstant, aber bei Kollision wechselt das Vorzeichen

Meine Frage wäre, ob meine Überlegungen richtig sind und ob ihr mir einen Anstoß zur Umsetzung geben könntet.

Bisher sind die Schläger schon implementiert und der Spieler kann einen bereits steuern. Was noch fehlt ist die Bewegung
des Balls, der Computer und die Spielmechanik (Punkte, Neustart, etc.).

Ich bedanke mich im Voraus für eure Hilfe! :)

Re: Pong - Ball

Verfasst: 11.02.2012 01:13
von STARGÅTE
Es ist nicht die optimale lösund, weil du ein Problem bekommst, wenn der Ball "hoch" fleigen soll und deine Steigung unendlich wird.

Besser ist es mit Vektoren zu arbeiten.
Das heißt, der Ball hat einen Ort (x,y) und eine Geschwindigkeit mit den Komponenten (vx, vy).

Im einfachen PONG kannst du dann bei Horizontalen Wänden einfach vy=-vy machen und
bei vertikalen Wänden einfach vx=-vx machen.

Re: Pong - Ball

Verfasst: 11.02.2012 14:08
von Shiv0r
Hallo
STARGÅTE hat geschrieben:Es ist nicht die optimale lösund, weil du ein Problem bekommst, wenn der Ball "hoch" fleigen soll und deine Steigung unendlich wird.

Besser ist es mit Vektoren zu arbeiten.
Das heißt, der Ball hat einen Ort (x,y) und eine Geschwindigkeit mit den Komponenten (vx, vy).

Im einfachen PONG kannst du dann bei Horizontalen Wänden einfach vy=-vy machen und
bei vertikalen Wänden einfach vx=-vx machen.
Erst einmal danke für deine schnelle Antwort!
Ja stimmt, das klingt logisch. Allerdings habe ich jetzt folgendes Problem:

Wenn der Ball beispielsweise den oberen Rand berührt, dann kehre ich das Vorzeichen um bzw. addiere vy.
Doch anscheinend ist die Subtraktion von vy noch immer aktiv, wie kann ich diese denn auflösen?
Das Problem ist dann, dass der Ball an der besagten Stelle "stehen" bleibt.

Hier der Auszug aus der Hauptschleife:

Code: Alles auswählen

Repeat
  ExamineKeyboard()
  ExamineMouse()


  If KeyboardPushed(#PB_Key_Up) And blau.Player\playerY > 0
    blau.Player\playerY - blau.Player\vy
  EndIf
  
  If KeyboardPushed(#PB_Key_Down) And blau.Player\playerY < 600 -SpriteHeight(#Sprite_Gruen)
    blau.Player\playerY + blau.Player\vy
  EndIf
  
  ;If (ball.Player\playerX < 800)
  ;  ball.Player\playerX + ball.Player\vx
  ;EndIf
  
  If (ball.Player\playerY < 600)
    ball.Player\playerY = ball.Player\playerY - ball.Player\vy
  EndIf
  
  If (ball.Player\playerY = 10)
    ball.Player\playerY = ball.Player\playerY + ball.Player\vy
  EndIf
  
  DisplayTransparentSprite(#Sprite_Blau, blau.Player\playerX, blau.Player\playerY)
  
  DisplayTransparentSprite(#Sprite_Gruen, gruen.Player\playerX, gruen.Player\playerY)

  DisplayTransparentSprite(#Sprite_Ball, ball.Player\playerX, ball.Player\playerY)
  
  
  FlipBuffers()
  
  ClearScreen(RGB(100, 20, 0))
  
  If KeyboardPushed(#PB_Key_Escape)
    End
  EndIf
  
Until KeyboardPushed(#PB_Key_Escape)

Genauer gesagt geht es um folgenden Teil:

Code: Alles auswählen

  If (ball.Player\playerY < 600)
    ball.Player\playerY = ball.Player\playerY - ball.Player\vy
  EndIf
  
  If (ball.Player\playerY = 10)
    ball.Player\playerY = ball.Player\playerY + ball.Player\vy
  EndIf

Ein Spielobjekt hat folgende Struktur:

Code: Alles auswählen

Structure Player
  playerX.l                   ; x-Koordinate
  playerY.l                   ; y-Koordinate
  vx.l                        ; x-Geschwindigkeit
  vy.l                        ; y-Geschwindigkeit
EndStructure

Ich bedanke mich wieder für eure Hilfe! :)


PS: An meinem "Code-Stil" gibt es sicherlich noch eine Menge zu tun, das weiß ich.
Aber für Kritik bin ich trotzdem offen.

Re: Pong - Ball

Verfasst: 11.02.2012 14:17
von The_Dark_Zim-.-
Offtopic:
Programmiert man heute in PB Objectorientiert :?
EndOfftopic

Re: Pong - Ball

Verfasst: 11.02.2012 15:06
von ts-soft
The_Dark_Zim-.- hat geschrieben:Offtopic:
Programmiert man heute in PB Objectorientiert :?
EndOfftopic
Wo denn? :bounce: kann ich nicht entdecken, oder ist die Nutzung von Strukturen bereits OOP?

GELÖSCHT

Verfasst: 11.02.2012 15:12
von mirca
GELÖSCHT

Re: Pong - Ball

Verfasst: 11.02.2012 15:18
von Fluid Byte

Re: Pong - Ball

Verfasst: 11.02.2012 15:59
von The_Dark_Zim-.-
@Fluid Byte
Was war nu echt unnötig -.-


Für mich ist sowas schon OOP aber egal zurück zum Thema.

Ich hab mal kurz was zusammengebastelt

Code: Alles auswählen

InitSprite()
InitKeyboard()

ExamineDesktops()

Global Width = DesktopWidth(0)
Global Height = DesktopHeight(0)

OpenScreen(Width,Height,DesktopDepth(0),"Pong")

SetFrameRate(50)

Global PlayerY = (Height/2)-30
Global PlayerX = 40
Global BallSpeedX = Random(4)+5
Global BallSpeedY = Random(4)+5
Global BallX = (width/2)-5
Global BallY = 25 + Random(Height-45)
Global Collision$ = "False"
Global Lives = 3

If Random(1) = 0
  BallSpeedX * -1  
EndIf
If Random(1) = 0
  BallSpeedY * -1  
EndIf

Procedure Restart()
  
  BallSpeedX = Random(4)+1
  BallSpeedY = Random(4)+1
  BallX = (width/2)-5
  BallY = 25 + Random(Height-45)
  
EndProcedure

Procedure PlayerLives()
  
  Lives -1
  If Lives = 0
    
    Repeat
      ClearScreen(RGB(0,0,0))
      StartDrawing(ScreenOutput())
      DrawText((Width/2),(Height/2)-5,"GAME OVER",RGB(0,255,0))
      StopDrawing()
      
      ExamineKeyboard()
      
      If KeyboardPushed(#PB_Key_Escape)
        End
      ElseIf KeyboardPushed(#PB_Key_R)
        Ende$ = "True"
        Lives = 3
        PlayerY = (Height/2)-30
        Restart()
      EndIf
      
      FlipBuffers()
      
    Until Ende$ = "True"
    
    
  EndIf
  
EndProcedure

Procedure BallCollision()
  
  
  BallX+BallSpeedX
  BallY+BallSpeedY
  
  If BallY-8 <= 21 Or BallY+8 => Height - 21
    BallSpeedY *-1
  EndIf
  If  BallX+8 => Width - 21
    BallSpeedX *-1
  EndIf
  If  BallX < 21
    PlayerLives()
    Restart()
  EndIf
  
  If BallX-8 > PlayerX And BallX-8 < PlayerX+20 And BallY-8 > PlayerY And BallY-8 < PlayerY+60
    If Collision$ = "False"
      BallSpeedX *-1
      Collision$ = "True"
    EndIf
  Else
    Collision$ = "False"
  EndIf
  
EndProcedure

Procedure BackGroundImage()
  
  StartDrawing(ImageOutput(0))
  
  Box(0, 0, Width, 20, RGB(255,255,255))
  Box(0, 0, 20, Height, RGB(255,255,255))
  Box(0, Height-20, Width, 20, RGB(255,255,255))
  Box(Width-20, 0, 20, Height, RGB(255,255,255))
  
  For i = 0 To 10
    Box((width/2)-10, 20+((Height/10)*i), 20, 40, RGB(255,255,255))
  Next
  
  StopDrawing()
  
EndProcedure

CreateImage(0,Width,Height)
BackGroundImage()

Repeat
  
  ExamineKeyboard()
  
  If KeyboardPushed(#PB_Key_Down)
    If PlayerY < Height-80
      PlayerY + 5
    EndIf
  ElseIf  KeyboardPushed(#PB_Key_Up)
    If PlayerY > 20
      PlayerY  -5
    EndIf
  EndIf
  
  If KeyboardPushed(#PB_Key_R)
    Lives = 3
    PlayerY = (Height/2)-30
    Restart()
  EndIf
  
  BallCollision()
  
  StartDrawing(ScreenOutput())
  
  ;####### Background
  
  DrawImage(ImageID(0),0,0)
  
  ;#######
  
  
  
  ;####### Player
  
  Box(PlayerX,PlayerY,20,60,RGB(255,0,0))
  
  ;#######
  
  ;####### Ball
  
  Circle(BallX,BallY,10,RGB(0,0,255))
  
  ;#######
  
  ;####### Text
  
  DrawText(20,0,"Player Lives: " + Str(Lives) + " | Press 'R' for Restart",RGB(0,0,0),RGB(255,255,255))
  
  ;#######
  
  
  StopDrawing()
  
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)

Re: Pong - Ball

Verfasst: 11.02.2012 21:20
von The_Dark_Zim-.-
@Shiv0r
Hab gerade nix zutun und hab mir deinen Code angeguckt.
Ist im prinzip ganz einfach warum der Ball stehen bleibt wenn er bei 10 angekommen ist ^^

Also du hast nun definiert das solange die Ball-Y-Koadinate < 600 ist die Y-Koadinate des Balls minus den Geschwindikeitswert genommen werden soll.

Code: Alles auswählen

   If ball.Player\playerY < 600
     ball.Player\playerY = ball.Player\playerY - ball.Player\vy
   EndIf
Funktioniert auch soweit. Nun hast du aber auch definiert das wenn die Y-Koadinate 10 erreicht er diese mit der Geschwindikeit addieren soll.

Code: Alles auswählen

   If (ball.Player\playerY = 10)
     ball.Player\playerY = ball.Player\playerY + ball.Player\vy
   EndIf
Das hat nun zur Folge das du sagst:
Y ist = 12 somit ersteinmal
Y - 2
y ist = 10 somit
Y + 2
macht immernoch 12 ;)

Ersetze einfach das:
ball.Player\playerY = ball.Player\playerY + ball.Player\vy
durch
ball.Player\vy = ball.Player\vy * (-1)

;)

Gruß Zim

Re: Pong - Ball

Verfasst: 11.02.2012 23:34
von Shiv0r
Hallo

Naja, klar gibt es noch viel an meinem Stil zu ändern. :wink:
Hatte vorher auch ein bisschen mehr mit C++ am Hut, wobei Strukturen ja im Grunde keine Klassen sind.

Jedenfalls habe ich den Fehler dann auch im Endeffekt gefunden und verändert, jetzt geht es bei mir an die
Implementierung des Computers, denn dieser muss ja irgendwie den Ball aufhalten wollen...

Danke jedenfalls für eure Hilfe!