bei
Code: Alles auswählen
; Hauptprogramm
Code: Alles auswählen
; Hauptprogramm
define quit.l = #false ; Soll das Programm sich beenden?
define PressedLeft.l = #false ; ist "Links" bereits gedrückt
define PressedRight.l = #false
define PressedUp.l = #false
define PressedDown.l = #false
Code: Alles auswählen
eventID = WaitWindowEvent()
Select eventID
Case #PB_Event_CloseWindow
End
EndSelect
Code: Alles auswählen
repeat
eventID = WindowEvent() ; ist ein Event vorhanden, wenn nein, nicht drauf warten, sondern 0 zurückgeben.
Select eventID
Case #PB_Event_CloseWindow
Quit = #true
case 0 ; kein Event
break ; repeat-schleife verlassen
EndSelect
forever
Das END hab ich rausgenommen und durch eine Variable ersetzt. END beendet dein Program sofort. Du kannst dann nichts mehr abspeichern etc. Ein End würde ich vermeiden bzw. erst wirklich am Schluss machen. Du musst ja bspw. reservierten Speicher, Bilder, Sounddateien etc. freigeben. Klar sollte bei End auch alles erfolgen, aber gewöhn dir an, das du Sachen freigibst, wenn du sie nicht mehr brauchst.
Statt WaitWindowEvent() erfolgt jetzt ein WindowEvent(). Das wartet nicht, gibt aber eine Null zurück, wenn kein Event mehr anliegt.
Die ganze Eventschleife abzuarbeiten dauert in der Regel unter einer Millisekunde. Die Zeit hast du!
statt
Code: Alles auswählen
x=0 : y=0 ; Bewegungsvariablen zurücksetzen
If Key(#VK_W) ; eine der WASD-Tasten gedrückt?
y-1 ; Dann Bewegungsvariablen entsprechend verändern
ElseIf Key(#VK_A)
x-1
ElseIf Key(#VK_S)
y+1
ElseIf Key(#VK_D)
x+1
EndIf
Zum anderen würde ich hier mit den "pressed"-Variablen überprüfen, ob die Taste schon gedrückt wurde, wenn ja, wird sie ignoriert.
Also bspw. so:
Code: Alles auswählen
x=0 : y=0 ; Bewegungsvariablen zurücksetzen
If Key(#VK_W) ; eine der WASD-Tasten gedrückt?
If pressedUp = #false ; war nicht gedürckt
y-1 ; Dann Bewegungsvariablen entsprechend verändern
endif
pressedUp = #true ; merken
else
pressedUp = #false; wurde losgelassen
endif
If Key(#VK_A)
if not pressedLeft ; geht auch mit not, eigentlich auch eleganter
x-1
endif
pressedLeft = #true
else
pressedLeft = #false
endif
If Key(#VK_S)
if not pressedDown
y+1
endif
pressedDown = #true
else
pressedDown = #false
endif
If Key(#VK_D)
if not pressedRight
x+1
endif
pressedRight = #true
else
pressedRight = #false
EndIf
Zudem hast du einen Denkfehler drin. Wenn du dir deine alte Tastenabfrage anschaust. Du hast immer Elseif drin, wenn du "W" und "S" gleichzeitig drückst, dann wird nur W abgearbeitet. Du hättest also bei deinen Fällen den Fall Beim testen auf X = -1 nicht mehr auf "W" testen müssen, weil der Fall nie eintreten kann.
Code: Alles auswählen
;Gedrückte Tasten auf zusätzlich gedrückte Nachbartasten überprüfen
If y=-1 ; Falls W gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_W)=0 Or Key(#VK_D) Or Key(#VK_A) ; bis entweder W losgelassen oder D oder A gedrückt worden ist
If Key(#VK_D) ; wenn zusätzlich D gedrückt wurde
x+1
ElseIf Key(#VK_A) ; wenn zusätzlich A gedrückt wurde
x-1
EndIf
ElseIf x=1 ; Falls D gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_D)=0 Or Key(#VK_W) Or Key(#VK_S) ; bis entweder D losgelassen oder W oder S gedrückt worden ist
If Key(#VK_W) ; wenn zusätzlich W gedrückt wurde
y-1
ElseIf Key(#VK_S) ; wenn zusätzlich S gedrückt wurde
y+1
EndIf
ElseIf y=1 ; Falls S gedrückt wurd
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_S)=0 Or Key(#VK_D) Or Key(#VK_A) ; bis entweder S losgelassen oder D oder A gedrückt worden ist
If Key(#VK_D) ; wenn zusätzlich D gedrückt wurde
x+1
ElseIf Key(#VK_A) ; wenn zusätzlich A gedrückt wurde
x-1
EndIf
ElseIf x=-1 ; Falls A gedrückt wurde
Repeat ; Solange warten
Until GetAsyncKeyState_(#VK_A)=0 Or Key(#VK_S) Or Key(#VK_W) ; bis entweder A losgelassen oder S oder W gedrückt worden ist
If Key(#VK_S) ; wenn zusätzlich S gedrückt wurde
y+1
ElseIf Key(#VK_W) ; wenn zusätzlich W gedrückt wurde
y-1
EndIf
EndIf
Code: Alles auswählen
Repeat
Delay(1) ; dann warten, bis alle Tasten losgelassen wurden
Until GetAsyncKeyState_(#VK_W)=0 And GetAsyncKeyState_(#VK_A)=0 And GetAsyncKeyState_(#VK_S)=0 And GetAsyncKeyState_(#VK_D)=0
Bau *niemals* solche Schleifen. Das konnte man bei den alten Heimcomputer (C64, Atari St, Amiga) etc. machen, du arbeitest in einen Multitasking-System. Entsprechend musst du sicherstellen, das die die Event-Schleife zuverlässig regelmäßig ausgeführt wird.
Löschen. Ist auch nicht mehr notwendig, wir haben das ja jetzt über die Pressed-Variablen gelöst.
Ich weis nicht genau was du programmieren willst. Aber eventuell sollen eine Gegner-KI auch reagieren können, wenn der Spieler nichts macht. Oder du möchtest eine "Idle-Animation" bei der Spielfigur abspielen, damit es nicht so statisch wirkt. Mit so einer "warte bis die Taste losgelassen wird"-Halb-Endlosschleife unmöglich.
achja, natürlich müssen wir noch:
Code: Alles auswählen
ForEver
Code: Alles auswählen
until quit
; alles freigeben, was du so gemacht hast, Hiscoreliste speicher etc.
end ; hier ist es richtig :)
Ich hätte eine Übungsaufgabe für dich:
Momentan ist es so, das du die Taste einmal drückst und die Figur nur einmal bewegt wird.
Ändere es so ab, das wenn man die Taste gedrückt hält, alle 500 Millisekunden die Figur sich weiter bewegt.
Diese 500 Millisekunden sollen natürlich wieder von vorne beginnen, wenn man die Taste loslässt und wieder drückt.
Und beachten für jede Taste getrennt. Also bspw rechts halten, soll in 500ms immer nach rechts gehen, aber du willst zwischendrin mal nach oben drücken können. Oder auch oben halten - und dann mit einen unabhängigen 500ms-Timer die tasten wiederholen.
Es gibt eine Funktion in PureBasic, mit der du die vergangene Zeit in Millisekunden rausfinden kannst. Such die mal und schau dir auch das Beispiel in der Anleitung dazu an.