Folgendes Problem möchte ich hier mal diskutieren, da ich zwar eine Lösung für mich gefunden habe, die aber recht umständlich und aufwendig und nicht ganz fehlerfrei erscheint:
In Assembler möchte ich einen Player mehrere Schüsse feuern lassen. Also maximal 4 zum Beispiel. Nun fragt man also den Strig0 ab und wenn der gedrückt wurde geht Schuss1 los. Beim nächsten drücken dann Schuss2 usw.
Die laufenden Schüsse sind so lange blockiert, bis sie auf ein Hindernis gestossen sind und eine Aktion auslösen oder hinten aus dem Bildrand rausgelaufen sind und dann wieder für einen neuen Schuss zur Verfügung stehen. So simpel sich das anhört, so kompliziert finde ich die Umsetzung.
Ähnlich wie be den Zufallszahlen könnte ich mir hier etliche sehr gute Ansätze vorstellen... bin gespannt auf Eure Ideen.
Gruß
Peter
Mehrere Schüsse
Moderator: Rockford
- cas
- Beiträge: 879
- Registriert: 18.06.2021 21:01
- Wohnort: Solar System
- Has thanked: 201 times
- Been thanked: 421 times
- Kontaktdaten:
Re: Mehrere Schüsse
Hallo Peter,
ich habe keinen Programmcode, nur Ideen: es gibt die Möglichkeit, das Schüsse nur eine bestimmte Reichweite haben und "verschwinden" und wieder zur Verfügung stehen. Man muss nicht warten, bis die Schüsse den Bildschirmrand erreichen.
Das Hauptprogramm fragt STRIG(0) ab, setzt den Start-Wert (x/y/count) in Variablen/Speicherstellen.
Im VBI werden X oder/und Y angepasst und "count" heruntergezählt. Wenn "count" == 0, wird der Schuss "ausgeschaltet" und steht wieder zur Verfügung. Kollisions-Abfrage kann im VBI oder im Hauptprogramm geschehen, das Hauptprogramm muss sich nicht mit der Verwaltung der Schüsse beschäftigen.
Beste Grüsse
Carsten
ich habe keinen Programmcode, nur Ideen: es gibt die Möglichkeit, das Schüsse nur eine bestimmte Reichweite haben und "verschwinden" und wieder zur Verfügung stehen. Man muss nicht warten, bis die Schüsse den Bildschirmrand erreichen.
Das Hauptprogramm fragt STRIG(0) ab, setzt den Start-Wert (x/y/count) in Variablen/Speicherstellen.
Im VBI werden X oder/und Y angepasst und "count" heruntergezählt. Wenn "count" == 0, wird der Schuss "ausgeschaltet" und steht wieder zur Verfügung. Kollisions-Abfrage kann im VBI oder im Hauptprogramm geschehen, das Hauptprogramm muss sich nicht mit der Verwaltung der Schüsse beschäftigen.
Beste Grüsse
Carsten
- Dr. Irata
- Beiträge: 974
- Registriert: 24.08.2021 14:40
- Has thanked: 126 times
- Been thanked: 291 times
- Kontaktdaten:
Re: Mehrere Schüsse
Meine umständliche Lösung sieht aktuell so aus für 2 Schüsse:
Für die gleichmäßige Bewegung nehme ich den VBI - meine Schüsse laufen von rechts nach links, daher muss ich nur den x-Wert incementieren.
Damit der Schuss schneller läuft incrementiere ich 2x!
Diese Routine steht im VBI:
Die folgende längere Routine wird im Hauptprogramm abgearbeitet:
m1index und m2index beschreiben den Zustand von Schuss1 und Schuss2 - also läuft der jeweilige Schuss gerade.
Wenn die x-Position über 240 ist, dann ist der Bildrand erreicht und der jeweilige Schuss wird auf den entsprechenden Index gesetzt.
Das Gleiche (dann mit einer Aktion) passiert auch. bei einer Kollision, die ich woanders abfrage.
Insgesamt finde ich das zu umständlich programmiert, mir ist aber nichts besseres im Moment eingefallen.
Meine Routine bei Battle of Eris war noch koplizierter...
Für die gleichmäßige Bewegung nehme ich den VBI - meine Schüsse laufen von rechts nach links, daher muss ich nur den x-Wert incementieren.
Damit der Schuss schneller läuft incrementiere ich 2x!
Diese Routine steht im VBI:
Code: Alles auswählen
; m1index:
; 0 = kein Schuss
; 1 = nur Schuss1 läuft
; 2 = Schuss1 und 2 laufen
; 3 = nur Schuss2 läuft
#if .byte m1index=#3 .or .byte m1index=#2
mva xposm2 hposm1
inc xposm2
inc xposm2
#end
#if .byte m1index=#1 .or .byte m1index=#2
mva xposm1 hposm0
inc xposm1
inc xposm1
inc m2index
#end
Code: Alles auswählen
;Schuss1
#if .byte m1index=#0
#if .byte strig0=#0
mva xposp1 xposm1
ldy yposp1
iny
iny
iny
iny
iny
sty yposm1
lda #170
sta (miss1),y
iny
sta (miss1),y
inc m1index
#end
jmp ex
#end
#if .byte m1index=#3
#if .byte strig0=#0
mva xposp1 xposm1
ldy yposp1
iny
iny
iny
iny
iny
sty yposm1
lda #170
sta (miss1),y
iny
sta (miss1),y
dec m1index
#end
jmp ex
#end
;Schuss2
#if .byte m1index=#1 .and .byte m2index>#40
#if .byte strig0=#0
mva xposp1 xposm2
lda #85
ldy yposp1
iny
iny
iny
iny
iny
sty yposm2
sta (miss1),y
iny
sta (miss1),y
inc m1index
#end
#end
ex
; m1index:
; 0 = kein Schuss
; 1 = nur Schuss1 läuft
; 2 = Schuss1 und 2 laufen
; 3 = nur Schuss2 läuft
#if .byte xposm1>#240
lda #0
sta xposm1
sta hposm0
ldy yposm1
mva #0 (miss1),y
iny
mva #0 (miss1),y
inc m1index
#if .byte m1index=#2
lda #0
sta m1index
#end
#end
#if .byte xposm2>#240
lda #0
sta xposm2
sta hposm1
dec m1index
ldy yposm2
mva #0 (miss2),y
iny
mva #0 (miss2),y
#if .byte m1index=#2
lda #0
sta m1index
sta m2index
#end
#end
Wenn die x-Position über 240 ist, dann ist der Bildrand erreicht und der jeweilige Schuss wird auf den entsprechenden Index gesetzt.
Das Gleiche (dann mit einer Aktion) passiert auch. bei einer Kollision, die ich woanders abfrage.
Insgesamt finde ich das zu umständlich programmiert, mir ist aber nichts besseres im Moment eingefallen.
Meine Routine bei Battle of Eris war noch koplizierter...
- Kveldulfur
- Beiträge: 716
- Registriert: 17.08.2021 02:32
- Has thanked: 284 times
- Been thanked: 230 times
- Kontaktdaten:
Re: Mehrere Schüsse
Hi!
Ich möchte hier auch meine Variante vorstellen, wie ich in meinem neuem Spiel die Missiles nutze. Wobei ich wahrscheinlich es noch einmal ändern muss, weil es zuviele mögliche Schüsse sind
Im Prinzip ist es bei mir 3-teilig.
1) Auslöseroutine
2) Bewegungsroutine
3) Kollisionsroutine
Für die Missiles lege ich mir 4 Variablen an, wobei theoretisch 3 reichen würden:
1) X-Position des Missile
2) Y-Position des Missile
3) Flugrichtung des Missile
4) Status des Missile
Der PM-Speicherstart für die Missiles wird in der Variable "Missiles" hinterlegt.
Die Auslöseroutine:
Diese prüft in einer Schleife, welcher Missile ungenutzt ist (MissilesStat). Der erste ungenutzte Missiles wird im X-Register hinterlegt.
Dadurch ist es egal, welcher der Missiles frei geworden ist, er wird gefunden
Die Routine setzt nun das Missile und die entsprechenden Variablen.
Da mein Spieler oft auf der selben Höhe seine Schüsse abgibt, ist es wichtig den Missile per ORA hinzuzufügen.
Wenn ein Missile gesetzt wurde, wird es automatisch in der Bewegungsroutine bis zum Bildschirmrand in der angegebenen Richtung bewegt.
Am Rand angekommen, wird das Missile gelöscht und der Status auf Inaktiv gesetzt:
Wie man ein Missile bewegt und die Kollision prüft, sollte bekannt sein.
Beim Bewegen gehe ich übrigens wieder eine Schleife von 3-0 durch und prüfen über den Status, welcher Missile bewegt werden muss.
Bei der Kollision müssen ebenfalls nur aktive Missiles geprüft werden.
Möchte man den Missile nach 20 Schritten wieder löschen, kann man leicht in einer weiteren Variable die Anzahl der Schritte sich merken und dann den Missile löschen.
Ich hoffe ich konnte so in etwa aufzeigen, wie ich es mache
Grüße
Janko
Ich möchte hier auch meine Variante vorstellen, wie ich in meinem neuem Spiel die Missiles nutze. Wobei ich wahrscheinlich es noch einmal ändern muss, weil es zuviele mögliche Schüsse sind
Im Prinzip ist es bei mir 3-teilig.
1) Auslöseroutine
2) Bewegungsroutine
3) Kollisionsroutine
Für die Missiles lege ich mir 4 Variablen an, wobei theoretisch 3 reichen würden:
1) X-Position des Missile
2) Y-Position des Missile
3) Flugrichtung des Missile
4) Status des Missile
Der PM-Speicherstart für die Missiles wird in der Variable "Missiles" hinterlegt.
Code: Alles auswählen
PMMemBase EQU $2000 ; $2000 bis $27FF
Missiles EQU PMMemBase+$300
Player0 EQU PMMemBase+$400
Player1 EQU PMMemBase+$500
Player2 EQU PMMemBase+$600
Player3 EQU PMMemBase+$700
MissilesX .DS 4
MissilesY .DS 4
MissilesRi .DS 4
MissilesStat .DS 4
Diese prüft in einer Schleife, welcher Missile ungenutzt ist (MissilesStat). Der erste ungenutzte Missiles wird im X-Register hinterlegt.
Code: Alles auswählen
LDX #3 ; freien Schuss suchen
@ LDA MissilesStat,X
BEQ MissileSetzen ; freier Missile gefunden
DEX
BPL @-
JMP MissileNichtfrei ; es konnte kein freier Missile gefunden werden
Die Routine setzt nun das Missile und die entsprechenden Variablen.
Code: Alles auswählen
MissileSetzen LDA #1 ; Missile als aktiv markieren
STA MissilesStat,X
LDA PlayerX ; Missile X setzen
STA MissilesX,X
STA HPOSM0,X
LDA PlayerY ; Missile Y setzen
STA MissilesY,X
TAY
LDA Missiles,Y ; Missiles im Speicher lesen
ORA ShootPixel,X ; Bits holen
STA Missiles,Y ; und zurück speichern
und Richtung...
STA MissilesRi,X
...
...
ShootPixel DTA %00000011
DTA %00001100
DTA %00110000
DTA %11000000
Wenn ein Missile gesetzt wurde, wird es automatisch in der Bewegungsroutine bis zum Bildschirmrand in der angegebenen Richtung bewegt.
Am Rand angekommen, wird das Missile gelöscht und der Status auf Inaktiv gesetzt:
Code: Alles auswählen
ShootOff LDA #0
STA MissilesStat,X ; Status auf 0 = Inaktiv
LDA MissilesY,X ; Y-Position holen
TAY
LDA Missiles,Y ; Missile aus Speicher laden
AND ShootMask,X ; per Maske löschen
STA Missiles,Y ; zurück sichern
...
...
ShootMask DTA %11111100
DTA %11110011
DTA %11001111
DTA %00111111
Beim Bewegen gehe ich übrigens wieder eine Schleife von 3-0 durch und prüfen über den Status, welcher Missile bewegt werden muss.
Bei der Kollision müssen ebenfalls nur aktive Missiles geprüft werden.
Möchte man den Missile nach 20 Schritten wieder löschen, kann man leicht in einer weiteren Variable die Anzahl der Schritte sich merken und dann den Missile löschen.
Ich hoffe ich konnte so in etwa aufzeigen, wie ich es mache
Grüße
Janko
Meine Projekte findest Du hier...
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast