Ready64 Forum
Commodore 64 => Aiuto & Domande => Topic aperto da: input - 06 Maggio 2021, 21:52:42
-
buonasera ragazzi, ho quasi finito di creare un gioco in basic stile pac man, ma mi sono arenato sulle collisioni: so che per abilitare sprite/sprite la lecazione e pokev+30 mentre sprite/sfondo è pokev+31 .
in poche parole, con pokev+30 abilito la collisione dello sprite 0 e con peekl(v+30) ne leggo il suo contenuto , e dopo le faccio fare le azione a mio piacimento tramite delle condizioni.
Il mio problema è , perche quando creo con lo sprite 0 (valore 1) una collissione con lo sprite 2 (valore 4) , totale valore 5 , lo sprite 0 continuare ad attraversarlo senza fermarsi. invece vorrei che quando si verifica la collisione, lo sprite rimanesse fermonella stessa posizione prima della collisione , come se avesse un muro davanti. ma questo non succede, non capisco dove sto sbagliando.
questo è un piccolo listato di esempio grazie
2 x=100 : Y=139 : XX=80: YY=100:t=0 :REM Coordinate posizione iniziale sprite 0 e 2
3 poke650,128 :REM ripetizione automatica dei tasti
5 print chr$(147) :REM cancella lo schescrmo
10 V=53248 :REM inizio registro video
11 POKEV+21,5 :REM abilita lo sprite 0 e 2
12 poke2040,192: poke2042,193: REM Variabile inizio puntatore forma dal 192 e 193 blocco
13 FOR N =12288 to 12350 :READQ: POKEN, Q: NEXT :REM legge dati sprite 0
15 FOR N =12416 to 12478 :READQ: POKEN, Q: NEXT :REM legge dati sprite 2
17 print chr$(147)
19 pokev+30,0 :REM abilita collisione sprite 0
40 POKEV+0,x :REM coordinate x sprite 0
42 POKEV+1,y :REM coordinate Y sprite 0
44 POKEV+4,xx :REM coordinate Y sprite 2
46 POKEV+5,yy :REM coordinate Y sprite 2
47 REM PUNTEGGIO
48 print "{home}",t
59 REM CONTROLLO MOVIMENTO
69 geta$: ifa$=" " then 69
70 if a$=chr$(157) then x=x-5 :REM SINISTRA(5 = velocita di spostamento)
80 if a$=CHR$(29 ) then x=x+5 :REM DESTA IDEM
86 if a$=chr$(17) then y=y+5 :REM GIU IDEM
95 if a$=CHR$(145) then y=Y-5 :REM SU IDEM
150 REM conserva il valore letto in B
155 B=peek(v+30)
158 REM B assume il valore di 5 se collidono gli sprite 0 e 2
159 REM (sprite 0=1, sprite 2=4)tot=5
160 if peek (v+30) = 5 then gosub 200
165 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DEI DUE SPRITE PRIMA DELLA COLLISIONE
270 x=x-5
280 x=x-5
286 y=y-5
295 y=Y-5
296 REM PUNTEGGIO
297 t=t+1
310 return
-
Un paio di osservazioni che spero possano servire
1) Non serve "abilitare le collisioni", queste vengono già rilevate a livello hardware dal registro 53278.
2) Leggere da quel registro ne azzera il contenuto, quindi la seconda PEEK non ha senso.
-
si hai ragione non si finisce mai di imparare , infatti gia la variabile B mi rileva il valore dello scontro tra lo sprite 0 e 2 .
ho eliminato la linea ( 160 if peek (v+30) = 5 then gosub 200,) come mi hai consigliato , il programma gira lo stesso , pertanto dovro utilizzare come condizione la variabile B , sostituindo la linea 160 con questo nuovo codice
160 if B=5 then gosub 200
comunque mi rimane il problema per quello che riguardo lo scontro tra sprite/sprite , non riesco a collocare le coordinate , per fare in modo che quando si verifica una collissione con un altro o con lo sfondo , questo si fermi dinanzi all ostacolo.
puo darmi qualche altro consiglio per favore grazie
-
mane il problema per quello che riguardo lo scontro tra sprite/sprite , non riesco a collocare le coordinate , per fare in modo che quando si verifica una collissione con un altro o con lo sfondo , questo si fermi dinanzi all ostacolo.
puo darmi qualche altro consiglio per favore grazie
Non so come tu abbia definito gli sprites ma secondo me c'è qualcosa che non va nella subroutine alla riga 200. Se vuoi simulare uno scontro come minimo ti serve conoscere la direzione dell'ultimo spostamento, in modo da ripristinare le coordinate dello sprite prima dell'impatto.
-
ho modificato la la ruotina 200, che avrebbe il compito di ristituire alle coordinate x e y lo stesso valore che aveva prima della collisione , come giustamente mi hai fatto osservare, pero lo sprite 0 ( che è quello che muovo con i tasti) attraversa l altro sprite (sprite 2) anche dopo la collisione e non si ferma
162 if B=5 then gosub 200
165 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
280 x=x
281 y=y
297 t=t+1 :rem mi rileva se ce una collisione o meno, è un test
300 return
-
280 x=x
281 y=y
Questi sono no-op, devi salvare il valore di prima della modifica.
-
l ho avevo provato anche questo, ma non va, ho memorizzato le variabili x e y prima della collisione in spx ed spy . e poi li ho richiamate con la sobrutina ma non va, qualcosa mi sfugge
questo e la porzione di codice che avevo provato prima .. avevo provato anche un altra opzione simile a questa , ma funziona perfettamente soltanto in un verso, delle quattro direzioni.
c'e qualcosa che mi sfugge che non riesco a capire cosa, comunque grazie del consiglio
40 POKEV+0,x :REM coordinate x sprite 0
42 POKEV+1,y :REM coordinate Y sprite 0
44 POKEV+4,xx :REM coordinate Y sprite 2
46 POKEV+5,yy :REM coordinate Y sprite 2
49 spx=x :REM posizione x prima della collisione
50 spy=y :REM posizione y prima della collisione
53 REM PUNTEGGIO
54 print "{home}",t,b Rem per un test collisione e punteggio
55 B=peek(v+30)
59 REM CONTROLLO MOVIMENTO
69 geta$: ifa$=" " then 69
71 if a$=chr$(157) then x=x-5 :REM SINISTRA
80 if a$=CHR$(29 ) then x=x+5 : rem DESTA IDEM
86 if a$=chr$(17) then y=y+5 : REM GIU IDEM
95 if a$=CHR$(145) then y=Y-5 :REM SU IDEM
150 REM conserva il valore letto in B
157 print x
162 if B=5 then gosub 200 :REM
165 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
280 x=spx
281 y=spy
297 t=t+1
300 return
-
c'e qualcosa che mi sfugge che non riesco a capire cosa, comunque grazie del consiglio
Ok, un altro suggerimento da vecchio. :maximo:
Prendi un foglio di carta e prova ad eseguire il programma passo-passo come se tu fossi la CPU, scrivendo lo stato iniziale delle variabili e dei registri e come questo cambia dopo ogni istruzione.
Lo so, è noioso e faticoso ma per programmini così semplici si può fare ed è il miglior metodo che io conosca per imparare a pensare algoritmicamente.
Buon lavoro!
P.S.: si chiama "subroutine", né "sobrutina" né "ruotina".
-
49 spx=x :REM posizione x prima della collisione
50 spy=y :REM posizione y prima della collisione
Ricorda che per il C64 le variabili si distinguono solo in base ai primi due caratteri: spx e spy sono entrambe la stessa variabile (la variabile sp). Queste due righe in quest'ordine hanno dunque l'effetto di sp=y.
-
l avevo letto neanche una settimana fa, nonostante lo sapessi,
non ci sarei mai arrivato, perche devo fare molta pratica ed esperienza ancora.
comunque adesso gli sprite si attaccano correttamente, ma non si spostano piu, sono come incollati, gia e qualcosa .
adesso povero a trovare la soluzione per poterli spostare . Di nuovo grazie a voi che mi sostenete
-
comunque adesso gli sprite si attaccano correttamente, ma non si spostano piu, sono come incollati
Attenzione: il registro 53278 viene aggiornato solo quando viene rilevata una collisione, cioè nel momento in cui gli sprites devono essere ridisegnati sullo schermo. In generale, questo avviene un certo intervallo di tempo dopo che ne viene aggiornata la posizione (che corrisponde, nel peggiore dei casi, a circa la durata di un intero quadro video, cioè 1/50 di secondo).
Occorre quindi essere sicuri che il contenuto del registro sia consistente con le nuove coordinate memorizzate (una soluzione semplice può essere introdurre un'attesa di almeno 1/50 di secondo tra la scrittura delle nuove coordinate e la lettura del registro).
-
da ieri che ci sto provando, dopo i vostri consigli utilissimi, ho pensato , essendo il basic molto
lento ad eseguire tutte queste operazioni , pertanto non riesce a finire di svuotare il baffer del registro 53278 ( leggerne il contenuto per azzerarlo) che subito gia riscontra nuovamente un ulteriotre collissione e pertanto non ha il tempo materiiale di leggere il suo contenuto è distaccarsi , quindi rimane sempre attaccato.
ora con questa nuova e importante info che gentilmente mi hai inviato, spero di poter risolvere il problema grazie :)
-
ho provato ad inserire un ritardo un po piu alto di 1/50 s , con un ciclo for m= 1 to 50, il tempo che impiega lo schermo a ridisegnare tutto lo schermo. pensavo che sarebbe stato sufficiente. ma no va lo stesso, ho provato vari valori piu e piu bassi ma senza alcun risultato. il ciclo lo inserito , subito dopo la scrittuira della nuova coordinata e prima della lettura della locazione 53728, ma il risultato rimane invariato.
avevo provato con il joystick, ma rimane lo stesso problema , si muove in tutte le direzione, appena avviene lo scontro, si incolla e non si stacca piu.
questo è uno stralcio. questo è uno stralcio di listato della parte interessata del listato, dove sicuramente si annida il problema che non riesco ancora a risolvere
17 print chr$(147)
40 POKEV+0,x :REM coordinate x sprite 0
42 POKEV+1,y :REM coordinate Y sprite 0
44 POKEV+4,xx :REM coordinate Y sprite 2
46 POKEV+5,yy :REM coordinate Y sprite 2
49 px=x :REM posizione x prima della collisione
50 py=y :REM posizione y prima della collisione
53 REM PUNTEGGIO
54 print "{home}",t,b
56 B=peek(v+30): REM lettura del rgistro 53278
59 REM CONTROLLO MOVIMENTO
69 geta$: ifa$=" " then 69
71 if a$=chr$(157) then x=x-5 :REM SINISTRA
80 if a$=CHR$(29 ) then x=x+5 : rem DESTA IDEM
86 if a$=chr$(17) then y=y+5 : REM GIU IDEM
95 if a$=CHR$(145) then y=Y-5 :REM SU IDEM
150 REM conserva il valore letto in B
157 print x
162 if B=5 then gosub 200
164 form = 1 to 5 :nextm :REM ritardo
165 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
260 REM SCRITTURA NUOVE COORDINATE
280 x=px
281 y=py
282
297 t=t+1
300 return
-
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
260 REM SCRITTURA NUOVE COORDINATE
280 x=px
281 y=py
Qui non stai scrivendo le nuove coordinate nei registri, stai semplicemente aggiornando delle variabili interne.
ho provato ad inserire un ritardo un po piu alto di 1/50 s , con un ciclo for m= 1 to 50, il tempo che impiega lo schermo a ridisegnare tutto lo schermo.
Come fai ad esserne sicuro? Cerca qualcosa di più affidabile, ad esempio l'orologio di sistema (TI$).
Ribadisco l'utilità di prendere carta e penna.
Saluti
-
credo che dovcra fare proprio cosi, magari creando prima un diagramma di flusso e seguirlo psso passo
-
sono riuscito a rsolverlo , anche se funziona non sono soddisfatto,
non mi piace la ripetizione dei tasti, non lo trovo elegante
40 POKEV+0,x :REM coordinate x sprite 0
42 POKEV+1,y :REM coordinate Y sprite 0
44 POKEV+4,xx :REM coordinate Y sprite 2
46 POKEV+5,yy :REM coordinate Y sprite 2
53 REM PUNTEGGIO
54 print "{home}",t,b
56 B=peek(v+30): REM lettura del rgistro 53278
57 if B=5 then gosub 200
59 REM CONTROLLO MOVIMENTO
69 geta$: ifa$=" " then 69
71 if a$=chr$(157) then x=x-5 :REM SINISTRA
80 if a$=CHR$(29 ) then x=x+5 : rem DESTA IDEM
86 if a$=chr$(17) then y=y+5 : REM GIU IDEM
95 if a$=CHR$(145) then y=Y-5 :REM SU IDEM
175 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
260 REM SCRITTURA NUOVE COORDINATE
270 rem x= px
280 if a$=chr$(157) then x=x+5
285 if a$=chr$(29) then x=x-5
286 if a$=chr$(17) then y=y-5
287 if a$=chr$(145) then y=y+5
297 t=t+1
300 return
-
chiedevo un vostro consiglio sul risultato, e comunque voglio ringraziarvi di aver perso del vostro tempo per me
-
chiedevo un vostro consiglio sul risultato
Direi che è una soluzione piuttosto spartana e poco precisa; in effetti, può capitare che lo sprite mobile penetri nello sprite fisso e ne resti intrappolato, anche se per un semplice giochino in BASIC può andare.
-
lo so che è molta spartana , per questo volevo una vostra opinione.
ho provato e riprovato, ma non resta intrappolato, l unico piccolo difetto è che in due direzioni lo sprite quando collide con un altro sprite , penetra di 5 pixel l altro ( che sarebbero i pixel di incremento o decremento ) se riduco l incremento riduco la velocita ma riduco anche la penetrazione . ( per poi ritornare alla posizione iniziale prima della collisione, mentre con i caratteri la collisione e perfetta .
se vuoi darmi una soluzuione piu elegante e meno spartana te ne sarai molto grato. anche perche non mi servirebbe per copiarla, ma solo per studiarla e capire meglio la loro funzionalita . comunque provero ancora domani, se riesco bene, altrimenti dovro rassegnarmi. ciao e grazie di tutto buonaserata
-
lo so che è molta spartana , per questo volevo una vostra opinione.
ho provato e riprovato, ma non resta intrappolato
Mah, io ho copiato il tuo codice pari-pari su VICE dando agli sprites delle coordinate di partenza casuali ed è capitato 3/4 volte che lo sprite mobile si incagliasse nell'altro, avrò preso lo spigolo del vetro.
se vuoi darmi una soluzuione piu elegante e meno spartana te ne sarai molto grato
Nei post sopra mi sembra di averti dato dei suggerimenti, anche piuttosto precisi: se vuoi fare meglio di così, pensaci sopra.
provero ancora domani, se riesco bene, altrimenti dovro rassegnarmi
Spirito sbagliato, se mi consenti. Nella scienza e nella tecnica non si raggiunge mai la perfezione e non ha senso "rassegnarsi". Se qualcosa piace davvero si va avanti con l'ardore di migliorare costantemente le proprie conoscenze e capacità, altrimenti si lascia perdere subito e si fa altro.
Saluti
-
ma io ho modificato il codice come mi hai detto , questo e quello che ho provato e funziona, spartanamente ma funziona , ho inserito anche un piccolo sfondo per le collissioni, vedrai che funziona, utilizzo cbm prg studio, ho modificato qualcosa , ho fatto come mi hai consigliato
-
questo è il listato a me funziona , non capisco come mai a te non funziona, avrai copiato parte di codice modificato, ma
5 x=50 : Y=19 : XX=100: YY=80:t=0 :REM Coordinate posizione iniziale sprite 0 e 2
10 poke650,128 :REM ripetizione automatica dei tasti
15 print chr$(147) :REM cancella lo schescrmo
20 V=53248 :REM inizio registro video
25 POKEV+21,5 :REM abilita lo sprite 0 e 2
30 poke2040,192: poke2042,193: REM Variabile inizio puntatore forma dal 192 e 193 blocco
31 FOR N =12288 to 12350 :READQ: POKEN, Q: NEXT :REM legge dati sprite 0
32 FOR N =12416 to 12478 :READQ: POKEN, Q: NEXT :REM legge dati sprite 2
34 print chr$(147)
40 POKEV+0,x :REM coordinate x sprite 0
42 POKEV+1,y :REM coordinate Y sprite 0
44 POKEV+4,xx :REM coordinate Y sprite 2
46 POKEV+5,yy :REM coordinate Y sprite 2
48 REM PUNTEGGIO
49 print "{home}{right*30}",t
50 PRINT " {cyan}{168}"
51 PRINT " {168} {168} {168}"
52 PRINT " {168} {168} {168}"
53 PRINT " {168} {168} {168}"
54 PRINT " {168} {168} {168}"
55 PRINT " {168} {168} {168}"
56 PRINT " {168} {168} {168}"
57 PRINT " {168} {168} {168}"
58 PRINT " {168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}{168}"
85 c=peek(v+30): REM lettura del rgistro 53278
86 B=peek(v+31): REM lettura del rgistro 53279
87 if B=1 or c=5 then gosub 200
90 REM CONTROLLO MOVIMENTO
91 geta$: ifa$=" " then 91
92 if a$=chr$(157) then x=x-5 :REM SINISTRA
93 if a$=CHR$(29 ) then x=x+5 : rem DESTA IDEM
94 if a$=chr$(17) then y=y+5 : REM GIU IDEM
95 if a$=CHR$(145) then y=Y-5 :REM SU IDEM
100 ifX=>254 then x=254
102 ifX<=24 then x=24
103 if Y=>229 then y=229
104 if Y<=50 then y=50
105 goto 40
200 print "collisione{home}"
250 REM POSIZIONI DELLO SPRITE 0 PRIMA DELLA COLLISIONE
280 if a$=chr$(157) then x=x+5
285 if a$=chr$(29) then x=x-5
286 if a$=chr$(17) then y=y-5
287 if a$=chr$(145) then y=y+5
297 t=t+1
300 return
1115 REM DATI DISEGNO SPRITE
1145 DATA 255,255,255
1175 DATA 255,255,255
1205 DATA 255,255,255
1235 DATA 224,0,7
1265 DATA 224,0,7
1295 DATA 224,0,7
1325 DATA 224,0,7
1355 DATA 224,0,7
1385 DATA 224,0,7
1415 DATA 224,0,7
1445 DATA 224,0,7
1475 DATA 224,0,7
1505 DATA 224,0,7
1535 DATA 224,0,7
1565 DATA 224,0,7
1595 DATA 224,0,7
1625 DATA 224,0,7
1655 DATA 224,0,7
1685 DATA 255,255,255
1715 DATA 255,255,255
1745 DATA 255,255,255
1775 REM
1805 DATA 255,255,255
1835 DATA 255,255,255
1865 DATA 255,255,255
1895 DATA 224,0,7
1925 DATA 224,0,7
1955 DATA 224,0,7
1985 DATA 224,0,7
2015 DATA 224,0,7
2045 DATA 224,0,7
2075 DATA 224,0,7
2105 DATA 224,0,7
2135 DATA 224,0,7
2165 DATA 224,0,7
2195 DATA 224,0,7
2225 DATA 224,0,7
2255 DATA 224,0,7
2285 DATA 224,0,7
2315 DATA 224,0,7
2345 DATA 255,255,255
2375 DATA 255,255,255
2405 DATA 255,255,255