Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Delphi - aiuto con Snake
Forum - Delphi - aiuto con Snake

Avatar
haberdasherv_ (Normal User)
Rookie


Messaggi: 22
Iscritto: 11/04/2009

Segnala al moderatore
Postato alle 13:12
Domenica, 18/10/2009
sto cercando di fare il classico gioco snake in delphi usando come cibo una label e come corpo del serpente dei componenti di tipo TAled(installati da me). il problema col quale mi sono scontrato attualmente è il movimento della coda del serpente. non riesco a fare in modo che questa coda giri come è giusto che faccia esattamente nei punti in cui ha girato anche la testa. per farvi un esempio, se la testa va dritta verso l'alto e io, quando arriva ad un punto P=(X,Y), premo la freccia sinistra, la testa va a sinistra mentre le code non dovrebbero girare subito ma aspettare di arrivare anche loro al punto P per cambiare direzione. ho fatto più prototipi di funzioni che dovrebbero fare ciò ma neanche una di queste ha funzionato fin'ora... qualcuno saprebbe darmi una mano?
ho allegato il progetto in questione con salvata l'ultima funzione che fa semplicemente cambiare posizione alla coda in funzione della direzione della testa (senza tenere conto del fatto che dovrebbe girare in quel certo punto dove gira la testa).
Grazie mille per eventuali aiuti.


haberdasherv_ ha allegato un file: Snake.zip (210292 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da haberdasherv_ il 18/10/2009 alle 13:14
PM Quote
Avatar
Anonymous (Member)
Guru


Messaggi: 1059
Iscritto: 30/07/2006

Segnala al moderatore
Postato alle 13:54
Domenica, 18/10/2009
Ciao.. il delphi è un pochetto che non lo tocco.... e purtroppo ho avuto problemi all'hd con windows quindi per ora sto solo su mac e quindi nn posso provare il tuo codice...


cmq posso suggerirti più o meno una strada al tuo problema...

praticamente ti puoi creare un nuovo tipo di variabile che accetta due campi per le coordinate.

dopo dichè crei un array di questa struttura nel quale viene salvata ogni posizione che effettua la testa
cosi dopo la coda per ricordarsi il tragitto della testa basta che accede a quell'array....


ad esempio:

la testa si trova in posizione 1? allora salva nella cella 1 dell'array la coordinata x e y
cosi anche quando la coda si troverà in posizione 1, basta che accede a quell'array e preleva le coord...

Ultima modifica effettuata da Anonymous il 18/10/2009 alle 13:56
PM Quote
Avatar
haberdasherv_ (Normal User)
Rookie


Messaggi: 22
Iscritto: 11/04/2009

Segnala al moderatore
Postato alle 14:48
Domenica, 18/10/2009
infatti è quello che ho fatto, ho creato un array a due dimensioni (x e y) nel quale vengono salvate ogni volta le coordinate del punto in cui la testa è prima di cambiare direzione, solo che non so come fare per dire alle code di dirigersi prima verso quel punto, poi verso la testa... tutti i codici che ho provato a scrivere alla fine fanno in modo che le code arrivino al punto in questione e si fermino là senza raggiungere la testa...

PM Quote
Avatar
Anonymous (Member)
Guru


Messaggi: 1059
Iscritto: 30/07/2006

Segnala al moderatore
Postato alle 15:13
Domenica, 18/10/2009
no.. quello che dico io non è di creare un array a due dimensioni....

ma un array ad una sola dimensione, nelle quali celle ci sta una struttura che contiene sia x sia y in modo tale che poi ogni volta che la testa si muove, l'array viene aggiornato con l'aggiunta della posizione....


capito??

crei un nuovo tipo di dato chiamato ad esempio posizione, che avrà come campi due interi: x e y in modo tale che dopo puoi usare la variabile "attuale" accedendo i campi x e y
in questo modo crei il nuovo tipo di dato e la variabile (anche se non son sicuro sia scritto sintatticamente bene... documentati su questa cosa)
Codice sorgente - presumibilmente Delphi

  1. TYPE attuale = posizione;
  2.      posizione= record
  3.      x:integer;
  4.      y:integer;
  5. end;




dopodiché crei un array di tipo poszione, in cui inserisci ad ogni passo che fa la testa le sue coordinate

una specie cosi:
Codice sorgente - presumibilmente Plain Text

  1. array[i].x = posizione_attuale_della_coordinata_x_della_testa;
  2. array[i].y = posizione_attuale_della_coordinata_y_della_testa;


dove i è l'i-esimo movimento della testa...

ovviamente i dovrà essere una variabile globale.... che dovrà venire incrementata di 1 ogni volta che la testa fa un passo.


in questo modo, tu terrai traccia di ogni posto in cui è stata la testa, e saprai sempre dove era in qualsiasi momento tu voglia....
quindi accederai a queste informazioni per far sapere alla coda dove è che deve andare.... dopo diché quando la coda le ha prese, puoi anche cancellarli dall'array in modo da riottenere spazio...

poi ci sarà da fare una procedura che oltre a cancellare i vecchi dati dall'array, transli verso sinistra tutti i successivi, per non tenere celle vuote nell'array, ma cmq queste due operazioni possono anche essere fatte una volta ogni X mosse... nn c'è bisogno di farle sempre

Ultima modifica effettuata da Anonymous il 18/10/2009 alle 15:16
PM Quote
Avatar
gigisoft (Member)
Guru


Messaggi: 696
Iscritto: 11/10/2008

Segnala al moderatore
Postato alle 17:56
Domenica, 18/10/2009
Salve,
non c'e' bisogno di nessun array, semplicemente bisogna spostare ad ogni movimento del serpente ogni pezzo del corpo nella posizione in cui si trovava il precedente ( partendo dalla coda, ovviamente ) e infine spostare la testa nella posizione in cui deve andare.
Un altro metodo puo' essere ( se non ci sono problemi di ordine dei pezzi del corpo del serpente ) di spostare semplicemente l'ultimo pezzo del serpente nel punto dove deve andare la testa ( la punta della coda diventera' la nuova testa ).
Spero di essere stato abbastanza chiaro;
se non lo sono stato ( e se conosci il C++ ) dai un'occhiata al mio programmino dello snake che trovi nell'area programmi :D

Ciao. :k:

Luigi

Ultima modifica effettuata da gigisoft il 18/10/2009 alle 17:57
PM Quote
Avatar
Anonymous (Member)
Guru


Messaggi: 1059
Iscritto: 30/07/2006

Segnala al moderatore
Postato alle 18:00
Domenica, 18/10/2009
è vero... sono due ottimi metodi questi...

PM Quote
Avatar
haberdasherv_ (Normal User)
Rookie


Messaggi: 22
Iscritto: 11/04/2009

Segnala al moderatore
Postato alle 19:11
Domenica, 18/10/2009
il metodo di gigisoft penso di non poterlo usare adesso ma solo successivamente quando finito questo progetto, lo riinizierò da capo usando però la classe canvas (per la quale non sarei ancora riuscito a trovare una qualche guida oltre al help del turbo delphi). il motivo è molto semplice: attualmente sto usando come "pezzi del serpente" dei componenti visuali di dimensioni 16x16 che si muovono di 2 pixel allo scattare di un timer che (almeno in teoria) dovrebbe scattare 1000 volte al secondo anche se poi scatta poco più di 6-7 volte per non so quale motivo... muovere i pezzi uno al posto dell'altro mi farebbe perdere molta fluidità...

inquanto alla soluzione di anonymous, se ho capito bene, consiste nel memorizzare ogni punto per il quale la testa è passata e poi farci passare i pezzi della coda pixel per pixel. beh, avendo una griglia di 500x450 memorizzare ogni singolo punto sarebbe un lavoraccio (per non parlare del fatto che il programma si ritroverebbe a gestire array di enormi dimensioni). quello che ho cercato di fare io è stato molto simile solo che ho cercato di memorizzare solamente i punti nei quali la testa cambiava direzione e fare in modo che le code si dirigessero verso quei punti. insomma ho creato una variabile contaangoli che aumentava di uno ad ogni cambiamento di direzione della testa. sfruttando la proprietà Tag di ogni componente della coda poi il programma avrebbe dovuto capire quali "angoli" la coda avesse superato e quali no. raggiunte le coordinate di un angolo la proprietà Tag del componente aumentava di uno dirigendo così la coda verso il prossimo "angolo". ad ogni movimento della testa venivano registrate le sue coordinate in un array bidimensionale (una dimensione per la X, e una per la Y) il cui indice era la variabile contaangoli.
così facendo rimanevano registrati i punti nei quali la testa girava e quando la coda non aveva nessun "angolo" verso cui dirigersi, si dirigeva verso la testa attraverso un codice del tipo
Codice sorgente - presumibilmente Delphi

  1. for i := 1 to contacode do
  2.     if Coda[i].Tag <> contaangoli then              
  3.     begin
  4.       if Coda[i].Top  > App[contaangoli,1] then
  5.         Coda[i].Top   := Coda[i].Top  -2;
  6.       if Coda[i].Top  < App[contaangoli,1] then
  7.         Coda[i].Top   := Coda[i].Top  +2;
  8.       if Coda[i].Left > App[contaangoli,2] then
  9.         Coda[i].Left  := Coda[i].Left -2;
  10.       if Coda[i].Left < App[contaangoli,2] then
  11.         Coda[i].Left  := Coda[i].Left +2;
  12.     end else
  13.     begin
  14.         if Coda[i].Top  > TestaG.Top  +15*i then
  15.           Coda[i].Top   := Coda[i].Top  -2;
  16.         if Coda[i].Top  < TestaG.Top  -15*i then
  17.           Coda[i].Top   := Coda[i].Top  +2;
  18.         if Coda[i].Left > TestaG.Left +15*i then
  19.           Coda[i].Left  := Coda[i].Left -2;
  20.         if Coda[i].Left < TestaG.Left -15*i then
  21.           Coda[i].Left  := Coda[i].Left +2;
  22.     end;


per qualche motivo però il codice non ha funzionato...

Ultima modifica effettuata da haberdasherv_ il 18/10/2009 alle 19:13
PM Quote