runterfallen und absturz beheben

Anfängerfragen zum Programmieren mit PureBasic.
Gn00bi
Beiträge: 22
Registriert: 10.04.2007 16:00

runterfallen und absturz beheben

Beitrag von Gn00bi »

Der Sinn des spieles ist es, mithilfe der maus die wände so zu erstellen, dass die spielfigur(blau) darauf laufen kann. sollte mal keins da sein ,soll sie hinuterfallen, bi sie wieder auf eine wand tritt. gespielt wird ausschließlich mit der maus (linke mausttaste gedrückt halten um die wand weiter zu bekommen) beendent wird mit esc.

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 700, 700, "test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0), 0, 0, 700, 700, 0, 0, 0)

Enumeration
 #Zeiger
 #Wand
 #Seite
 #Unten
 #Mitte
 #Spieler
 #kolli
EndEnumeration

#tileh = 20
#tilew = 20
#rrand = 640 - #tilew
#urand = 640 - #tileh
#orand = 20
#lrand = 20
SpielerX = #lrand
SpielerY = #orand
Anzahl = 11

CreateSprite(#Spieler, 20, 20)
 StartDrawing(SpriteOutput(#Spieler))
  Box(0, 0, 20, 20, RGB(0,0,255))
 StopDrawing()

CreateSprite(#Zeiger, 20, 20)
 StartDrawing(SpriteOutput(#Zeiger))
  Box(0, 0, 20, 20, RGB(255,0,0))
 StopDrawing()

CreateSprite(#Wand, 20, 20)
 StartDrawing(SpriteOutput(#Wand))
  Box(0, 0, 20, 20, RGB(255,255,0))
 StopDrawing()
  
CreateSprite(#Seite, 60, 640)
 StartDrawing(SpriteOutput(#Seite))
   Box(0, 0, 60, 640, RGB(255,255,255))
 StopDrawing()
 
CreateSprite(#Unten, 640, 60)
 StartDrawing(SpriteOutput(#Unten))
   Box(0, 0, 640, 60, RGB(255,255,255))
 StopDrawing()
 
CreateSprite(#Mitte, 60, 60)
 StartDrawing(SpriteOutput(#Mitte))
   Box(0, 0, 60, 60, RGB(255,0,255))
 StopDrawing()
 
CreateSprite(#kolli, 20, 20)
 StartDrawing(SpriteOutput(#kolli))
  Box(0, 0, 20, 20, RGB(150,0,0))
 StopDrawing()


Structure waendekoords
  xx.l
  yy.l
EndStructure

Global NewList Waendelist.waendekoords()

Procedure Waende(x,y)  
 AddElement(Waendelist())
  Waendelist()\xx = x
  Waendelist()\yy = y
EndProcedure

Waende(20, 40)
Waende(40, 40)
Waende(60, 40)
Waende(80, 40)
Waende(100, 40)
Waende(120, 40)
Waende(20, 60)
Waende(40, 60)
Waende(60, 60)
Waende(80, 60)
Waende(100, 60)
Waende(120, 60)

Repeat

ExamineKeyboard()
ExamineMouse()
ClearScreen(0)
 
StartDrawing(SpriteOutput(#Mitte))
 Box(0,0,60,60,RGB(255,0,255))
 DrawingMode(1)
  DrawText(10, 10, Str(ListIndex(Waendelist())))
  DrawText(10, 20, Str(Aufladung))
 LastElement(Waendelist())
 DrawText(10, 30, Str(Waendelist()\yy))
StopDrawing()


MouX = MouseX()
MouY = MouseY()
CurX = MouX
CurY = MouY

If MouseButton(#PB_MouseButton_Left) 
 If Mausgedrueckt = 0 Or Mausgedrueckt = 1
  Auflader + 10
  If Auflader = 20
   Aufladung + 20
   Auflader = 0
  EndIf
  Mausgedrueckt = 1
 EndIf
EndIf


  Select ActBord
  
    Case 0                      ; Oberer Rand
      If MouY > #tileh
        If MouX < #tilew
          ActBord = 3
        ElseIf MouX > #rrand
          ActBord = 1
        EndIf
      EndIf
      CurY = 0 
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tileh
 WandX = CurX
 WandY = Aufladung
 Aufladung = 0
 Waende(WandX, WandY)
 Anzahl + 1
 Mausgedrueckt = 2
EndIf

    Case 1                   ;Rechter Rand
      If MouX < #rrand
        If MouY < #tileh
          ActBord = 0
        ElseIf MouY > #urand
          ActBord = 2
        EndIf
      EndIf
      CurX = #rrand
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tilew
 WandX = #rrand - Aufladung
 WandY = CurY
 Aufladung = 0
 Waende(WandX, WandY)
 Anzahl + 1
 Mausgedrueckt = 2
EndIf

    Case 2                  ;Unterer Rand
      If MouY < #urand
        If MouX < #tilew
          ActBord = 3
        ElseIf MouX > #rrand
          ActBord = 1
        EndIf
      EndIf
      CurY = #urand
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tileh
 WandX = CurX
 WandY = #urand - Aufladung
 Aufladung = 0
 Waende(WandX, WandY)
 Anzahl + 1
 Mausgedrueckt = 2
EndIf

    Case 3                      ;Linker Rand
      If MouX > #tilew
        If MouY < #tileh
          ActBord = 0
        ElseIf MouY > #urand
          ActBord = 2
        EndIf
      EndIf
      CurX = 0
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tilew
 WandX = Aufladung
 WandY = CurY
 Aufladung = 0
 Waende(WandX, WandY)
 Anzahl + 1
 Mausgedrueckt = 2
EndIf

  EndSelect
  
  If CurX > #rrand
   CurX = #rrand
  EndIf
  If CurY > #urand
   CurY = #urand
  EndIf

If SpielerX => #rrand - #tilew
 Richtung = 1
ElseIf SpielerX <= #lrand
 Richtung = 0
EndIf

If Richtung = 0
 SpielerX + 1
ElseIf Richtung = 1
 SpielerX - 1
EndIf





If MouseButton(#PB_MouseButton_Left) And Mausgedrueckt = 2
 Mausgedrueckt = 0
EndIf

DisplaySprite(#Kolli, SpielerX, SpielerY + 20)

For c = 0 To Anzahl
 SelectElement(Waendelist(), c)
 DisplaySprite(#Wand, Waendelist()\xx, Waendelist()\yy)
Next

DisplaySprite(#Spieler, SpielerX, SpielerY)
DisplaySprite(#Seite, 640, 0)
DisplaySprite(#Unten, 0, 640)
DisplaySprite(#Mitte, 640, 640)
DisplaySprite(#Zeiger, CurX, CurY )

FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape)
End


tja also mein problem ist, dass es 1. meistens nach nem stück einfach abst+rzt und 2. ich keine richtige idee hab, wie ich dafür sorgen könnte, dass der Spieler (blaues viereck) nach unten fällt, wenn er nicht mehr über einer Wand (gelbes viereck) ist. und wenn noch andere fehler / vereinfachungen bei mir gefunden werden, dürft ihr mir die natürlich auch gerne mitteilen
ach und noch etwas wenn ich das ganze mit einem ereignis beenden will, dann läuft das spiel nicht mehr flüssig, wenn mir dabei viell. auch noch jmnd helfen könnte wäre das auch nett

€dit: oben beschreibung hinzugefügt und das problem mit dem beenden
Zuletzt geändert von Gn00bi am 03.07.2008 20:06, insgesamt 1-mal geändert.
Benutzeravatar
kswb73
Beiträge: 319
Registriert: 04.02.2008 16:51
Kontaktdaten:

Beitrag von kswb73 »

Könntest du bitte den Sinn deines Programmes etwas genauer erklären. Ich rätsel die ganze Zeit was da überhaupt passieren soll.
Soll jetzt nicht böse gemeint sein. Häng einfach eine Beschreibung davor
Windows XP: PB 4.31, PB 4.4, PB 4.51
Open Suse 11.2: PB 4.4
Benutzeravatar
kswb73
Beiträge: 319
Registriert: 04.02.2008 16:51
Kontaktdaten:

Beitrag von kswb73 »

Lass die LinkedList mal lieber weg und nimm ein Array. Das geht deutlich leichter. Hier hab ich mal ein Beispiel geschrieben. Der Spieler bewegt sich Feldweise.
Das ganze sollt sich ganz gut in deinem Programm einbauen lassen, da du die Mauer offenbar auch nur Feldweise bauen kannst. Die Tastensteuerung müsstest du dann noch mit deiner automitschen ersetzten.

Code: Alles auswählen

#Speed=1

InitSprite()
InitKeyboard()

Global SpielerX=1 ;Hier ist die Position des Spielers in Felder
Global SpielerY=0

Global MoveX=0 ;Diese beiden Variablen nutz ich um anzugeben um wo geanauf vom aktuellen Feld ausgegangen der Spieler sich befindet.
Global MoveY=0

Dim Feld.b(9,9)

Feld(1,6)=1
Feld(2,6)=1
Feld(3,6)=1
Feld(4,6)=1
feld(4,5)=1

OpenWindow(1,0,0,200,200,"Fallen mit Arrey")
  OpenWindowedScreen(WindowID(1),0,0,200,200,0,0,0)

Enumeration
#Spieler
#Mauer
EndEnumeration

CreateSprite(#Spieler,20,20) ;Laden der Bilder
  StartDrawing(SpriteOutput(#Spieler))
  Box(0,0,20,20,RGB(0,0,255))
  StopDrawing()
  
CreateSprite(#Mauer,20,20)
  StartDrawing(SpriteOutput(#Mauer))
  Box(0,0,20,20,RGB(0,255,255))
  StopDrawing()

Procedure Move(MoveSX,MoveSY) ;Durch diese Procedure sparen wir und die ganzen eingaben
SpielerX+MoveSX
SpielerY+MoveSY

MoveX+MoveSX*20
MoveY+MoveSY*20
EndProcedure

Repeat
  Repeat
  WEvent=WindowEvent() ;Damit Windows nicht mein das Fenster gäbe keine Rückmeldung
    If WEvent=#PB_Event_CloseWindow
    End
    EndIf
  Until WEvent=0
ClearScreen(0)
ExamineKeyboard()

DisplaySprite(#Spieler,SpielerX*20-moveX,SpielerY*20-MoveY) ;Wir zeigen den Spieler an.

  If MoveX>0 ;Hier lassen wir den Spieler auf sein Feld Bewegen. Über diese Taktik können wir trotz des Feldsystems flüssige bewegungen machen.
  MoveX-#Speed
    If MoveX<0
    MoveX=0
    EndIf
  ElseIf MoveX<0
  MoveX+#Speed
    If MoveX>0
    MoveX=0
    EndIf
  EndIf
  
  If MoveY>0
  MoveY-#Speed
    If MoveY<0
    MoveY=0
    EndIf
  ElseIf MoveY<0
  MoveY+#Speed
    If MoveY>0
    MoveY=0
    EndIf
  EndIf
  
  For a=0 To 9 ;hier zeigen wir das Feld an.
    For b=0 To 9
      If Feld(a,b)=1
      DisplaySprite(#Mauer,a*20,b*20)
      EndIf
    Next b
  Next a
  
  If SpielerX<9 And MoveX=0 And MoveY=0 And Feld(SpielerX,SpielerY+1)=0 ; Wenn das Feld unter dem Spieler leer ist bewegt er sich ein Feld nach unten.
  Move(0,1); Wichtig hierbei ist dass der Spieler vorher stillsteht, oder zumindestes nicht fällt, da sonst bei bewegungen Fehler auftreten.
  EndIf
  
  If MoveX=0 And MoveY=0 ;Hier nochmal eine Steuerung über die Tastatur. 
    If KeyboardPushed(#PB_Key_Right) And Feld(SpielerX+1,SpielerY)=0 ;Hier käm dann bei dir deine automatische Steuerung rein.
    Move(1,0)
    EndIf
    
    If KeyboardPushed(#PB_Key_Left) And Feld(SpielerX-1,SpielerY)=0
    Move(-1,0)
    EndIf
  EndIf

FlipBuffers()
ForEver

[edit]
Kurz noch mal eingefügt dass man nicht durch Wände laufen kann.
[/edit]
[edit]
Kleiner Fehler Korriegiert (die Kollisionüberprüfung für linksbewegung war falsch).
[/edit]
Zuletzt geändert von kswb73 am 04.07.2008 20:01, insgesamt 1-mal geändert.
Windows XP: PB 4.31, PB 4.4, PB 4.51
Open Suse 11.2: PB 4.4
Benutzeravatar
kswb73
Beiträge: 319
Registriert: 04.02.2008 16:51
Kontaktdaten:

Beitrag von kswb73 »

Hab mir mal die Zeit genomment deinen Code zu bearbeiten. Der Code ist nicht großartig verändert. Ich hab ein WindowEvent() am Anfang des Codes eingebaut, da Windows sonst nach einer Zeit meint, dein Fenster gäbe keine Rückmeldung (ist also abgestürzt). Die Anzahl der Mauer wird jetzt beim Anzeigen berechnet und nichtmehr wie vorher direkt beim Bauen, da du so Fehler verhinderst.
Das Fallen ist jezt natürlich auch drinn und die Feldaufteilung per Array auch.

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 700, 700, "test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0), 0, 0, 700, 700, 0, 0, 0)

Enumeration
 #Zeiger
 #Wand
 #Seite
 #Unten
 #Mitte
 #Spieler
 #kolli
EndEnumeration

#tileh = 20
#tilew = 20
#rrand = 640 - #tilew
#urand = 640 - #tileh
#orand = 20
#lrand = 20
#Speed = 2 ;damit du die Geschwindigkeit leicht einstellen kanst.
Global SpielerX = #lrand/20
Global SpielerY = #orand/20
Global MoveX
Global MoveY
Global Richtung

CreateSprite(#Spieler, 20, 20)
 StartDrawing(SpriteOutput(#Spieler))
  Box(0, 0, 20, 20, RGB(0,0,255))
 StopDrawing()

CreateSprite(#Zeiger, 20, 20)
 StartDrawing(SpriteOutput(#Zeiger))
  Box(0, 0, 20, 20, RGB(255,0,0))
 StopDrawing()

CreateSprite(#Wand, 20, 20)
 StartDrawing(SpriteOutput(#Wand))
  Box(0, 0, 20, 20, RGB(255,255,0))
 StopDrawing()
 
CreateSprite(#Seite, 60, 640)
 StartDrawing(SpriteOutput(#Seite))
   Box(0, 0, 60, 640, RGB(255,255,255))
 StopDrawing()
 
CreateSprite(#Unten, 640, 60)
 StartDrawing(SpriteOutput(#Unten))
   Box(0, 0, 640, 60, RGB(255,255,255))
 StopDrawing()
 
CreateSprite(#Mitte, 60, 60)
 StartDrawing(SpriteOutput(#Mitte))
   Box(0, 0, 60, 60, RGB(255,0,255))
 StopDrawing()
 
CreateSprite(#kolli, 20, 20)
 StartDrawing(SpriteOutput(#kolli))
  Box(0, 0, 20, 20, RGB(150,0,0))
 StopDrawing()


Global Dim Feld.b(32,32)

Procedure Move(MoveSX,MoveSY) ;Durch diese Procedure sparen wir und die ganzen eingaben
  If Feld(SpielerX+MoveSX,SpielerY+MoveSY)=0
  SpielerX+MoveSX
  SpielerY+MoveSY

  MoveX+MoveSX*20
  MoveY+MoveSY*20
  ElseIf MoveSX
    If Richtung=1
    Richtung=0
    ElseIf Richtung=0
    Richtung=1
    EndIf
  EndIf
EndProcedure

Procedure Waende(x,y) 
Feld(X/20,Y/20)=1
EndProcedure

Feld(0,2)=1
Feld(1,2)=1
Feld(2,2)=1
Feld(3,2)=1
Feld(4,2)=1

Feld(0,3)=1
Feld(1,3)=1
Feld(2,3)=1
Feld(3,3)=1
Feld(4,3)=1

Repeat

ExamineKeyboard()
ExamineMouse()
ClearScreen(0)
WindowEvent()

If SpielerY<31 And MoveX=0 And MoveY=0 And Feld(SpielerX,SpielerY+1)=0
Move(0,1)
EndIf
 
StartDrawing(SpriteOutput(#Mitte))
 Box(0,0,60,60,RGB(255,0,255))
 DrawingMode(1)
  DrawText(10, 20, Str(Aufladung))
  DrawText(10,0,Str(Anzahl))
StopDrawing()


MouX = MouseX()
MouY = MouseY()
CurX = MouX
CurY = MouY

If MouseButton(#PB_MouseButton_Left)
 If Mausgedrueckt = 0 Or Mausgedrueckt = 1
  Auflader + 10
  If Auflader => 20
   Aufladung + 20
   Auflader = 0
    If Aufladung>620
    Aufladung=620
    EndIf
  EndIf
  Mausgedrueckt = 1
 EndIf
EndIf


  Select ActBord
 
    Case 0                      ; Oberer Rand
      If MouY > #tileh
        If MouX < #tilew
          ActBord = 3
        ElseIf MouX > #rrand
          ActBord = 1
        EndIf
      EndIf
      CurY = 0
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tileh
 WandX = CurX
 WandY = Aufladung
 Aufladung = 0
 Waende(WandX, WandY)
 Mausgedrueckt = 2
EndIf

    Case 1                   ;Rechter Rand
      If MouX < #rrand
        If MouY < #tileh
          ActBord = 0
        ElseIf MouY > #urand
          ActBord = 2
        EndIf
      EndIf
      CurX = #rrand
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tilew
 WandX = #rrand - Aufladung
 WandY = CurY
 Aufladung = 0
 Waende(WandX, WandY)
 Mausgedrueckt = 2
EndIf

    Case 2                  ;Unterer Rand
      If MouY < #urand
        If MouX < #tilew
          ActBord = 3
        ElseIf MouX > #rrand
          ActBord = 1
        EndIf
      EndIf
      CurY = #urand
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tileh
 WandX = CurX
 WandY = #urand - Aufladung
 Aufladung = 0
 Waende(WandX, WandY)
 Mausgedrueckt = 2
EndIf

    Case 3                      ;Linker Rand
      If MouX > #tilew
        If MouY < #tileh
          ActBord = 0
        ElseIf MouY > #urand
          ActBord = 2
        EndIf
      EndIf
      CurX = 0
If MouseButton(#PB_MouseButton_Left) = 0 And Mausgedrueckt = 1 And Aufladung > #tilew
 WandX = Aufladung
 WandY = CurY
 Aufladung = 0
 Waende(WandX, WandY)
 Mausgedrueckt = 2
EndIf

  EndSelect
 
  If CurX > #rrand
   CurX = #rrand
  EndIf
  If CurY > #urand
   CurY = #urand
  EndIf

If SpielerX*20 => #rrand - #tilew
 Richtung = 1
ElseIf SpielerX*20 <= 0
 Richtung = 0
EndIf

If MoveX=0 And MoveY=0
  If Richtung = 0
  Move(1,0)
  ElseIf Richtung = 1
  Move(-1,0)
  EndIf
EndIf




If MouseButton(#PB_MouseButton_Left) And Mausgedrueckt = 2
 Mausgedrueckt = 0
EndIf

DisplaySprite(#Kolli, SpielerX*20-MoveX, SpielerY*20-MoveY + 20)

Anzahl=0
For c=0 To 31
  For d=0 To 31
    If feld(c,d)
    DisplaySprite(#Wand,c*20,d*20)
    Anzahl+1 ;Auf diese Weise musst hast du immer den richtigen Wert.
    EndIf
  Next d
Next c

DisplaySprite(#Spieler, SpielerX*20-MoveX, SpielerY*20-MoveY)
DisplaySprite(#Seite, 640, 0)
DisplaySprite(#Unten, 0, 640)
DisplaySprite(#Mitte, 640, 640)
DisplaySprite(#Zeiger, CurX, CurY )

If MoveX>0
MoveX-#Speed
  If MoveX<0
  MoveX=0
  EndIf
ElseIf MoveX<0
MoveX+#Speed
  If MoveX>0
  MoveX=0
  EndIf
EndIf

If moveY>0
moveY-#Speed
  If moveY<0
  moveY=0
  EndIf
ElseIf moveY<0
moveY+#Speed
  If moveY>0
  moveY=0
  EndIf
EndIf

FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape)
End
PS: Wenn dir die Variabeln-, Konstanten- oder Arraynamen nicht gefallen, so kanst du sie ganz einfach mit der Suchen und ersetzten Funktion austauschen.
Windows XP: PB 4.31, PB 4.4, PB 4.51
Open Suse 11.2: PB 4.4
Antworten