I can post the code but it's commented in italian,and not very well written i think....
If the italian commentatios isn't a problem i post the source.
Only make sure to follow those steps.
The program is for creating path nodes (for the follow routine,or for routes..).
So the first time you run it don't load a file...create a new one and save it.
And load a bmp also,because if you don't the animation don't start.
After that you can load the file and if you can see the problem.
(I hope that you have the xlntii include...because i use them and i think that don't work without...)
here's the code:
Include "XSTART.BB"
AppTitle "Resolution selector"
;un semplice requester per decidere la risoluzione dello schermo
Print "What screen resolution do you want to use?"
Print "1] 640*480"
Print "2] 800*600"
Print "3] 1024*768"
Print "4] 1280*1024"
scelta=Input("Choose a resolution:")
Select scelta
Case 1
screen_height=640
screen_width=480
Case 2
screen_height=800
screen_width=600
Case 3
screen_height=1024
screen_width=768
Case 4
screen_height=1280
screen_width=1024
End Select
Graphics screen_height,screen_width,32,2
fps_timer=CreateTimer(60)
GUI_GFXSETUP()
;Window
Window = GUI_WINDOW(0,0,160,400,"Path-points Creator","",62,0,$00DADADA,$007682BC,$00FFFFFF,$00C8C8C8,$006470AA)
;Gadgets
Button1 = GUI_BUTTON(Window,8,32,104,"New path","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button2 = GUI_BUTTON(Window,8,56,104,"Load path","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button3 = GUI_BUTTON(Window,8,80,104,"Save path","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button4 = GUI_BUTTON(Window,8,104,104,"Try loaded p.","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button5 = GUI_BUTTON(Window,8,128,104,"Try new p.","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button6 = GUI_BUTTON(Window,8,152,104,"N° nodes","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button7 = GUI_BUTTON(Window,8,176,104,"Speed","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button8 = GUI_BUTTON(Window,8,200,104,"Precision","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button9 = GUI_BUTTON(Window,8,224,104,"Smoothness","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button10 = GUI_BUTTON(Window,8,248,104,"Objects","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button11 = GUI_BUTTON(Window,8,272,104,"Background","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button12 = GUI_BUTTON(Window,8,320,104,"Clear all path","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
Button13 = GUI_BUTTON(Window,8,368,104,"Exit","",0,1,"",$00EEEEEE,$00D2D2D2,$00000000)
GUI_OPENWIN(Window) ;abbiamo finito di creare la finestra perciò la apriamo
AppTitle "Path Generator Matteo M. 2004" ;titolo applicazione
;Caricamento immagini con relativo handle
;******************************************************************************
Global puntatore=LoadImage("puntatore.bmp")
Global enemy$;=LoadImage("enemy.bmp")
;******************************************************************************
;caricamento fonts
;******************************************************************************
Global caratteri=LoadFont("Comic Sans MS",20,0,0,0)
;******************************************************************************
;dichiarazione variabili globali,dimensionamento arrays,maniglie degli sprites,variabili e costanti varie
;******************************************************************************
Global uscita
Global percorso
Global salvapath
Global provapath
Global clearpath
Global npath
Global num
Global caricapath
Global creapath
Global testcurrent
Global mouse1 ;questa e la variabile assegnata al pulsante del mouse...
Global mouse2 ;idem per il tasto destro.....
MidHandle puntatore ;la maniglia del puntatore è il suo centro esatto
;MidHandle enemy ;maniglia dell'oggetto che si muove,qui chiamato "alieno"
HidePointer ;nasconde il puntatore del mouse
Global try$
Dim pathx#(max_path_points) ;array che serve per leggere i dati del percorso corrente
Dim pathy#(max_path_points) ;idem sopra...
Global path_counter=-1 ;contatore dei nodi
Global prova
Global puntatori
Global a.alieno ;il type a
Global b.alieno ;il type b
Const max_path_points=10 ;il numero massimo di nodi da utilizzare nell'array
Global startdrawing ;mi serve per far sapere che ho cliccato il pulsante per disegnare il percorso
Global alieno_creato ;mi serve per dire che ho caricato un immagine dell'oggetto
;******************************************************************************
;creazione "type"
;******************************************************************************
Type alieno
Field posizionex#
Field posizioney#
Field velocita#
Field angolo#
Field angolo2#
Field pathx#[max_path_points]
Field pathy#[max_path_points]
Field smoothness
Field precisione
Field current_path
Field path_counter
Field distanza
Field cx#
Field cy#
;Field percorso
End Type
;******************************************************************************
;funzioni varie:creazione oggetti,interfaccia,movimenti,disegno nodi ecc. ecc.
;******************************************************************************
Function crea_alieno_drawn(speed,smooth,precis)
If creapath=0 Then Goto uscita5
b.alieno=New alieno
read_drawn_path()
b\velocita#=speed
b\angolo#=0
b\angolo2#=0
b\smoothness=smooth
b\precisione=precis
b\path_counter=-1
b\distanza=0
b\current_path=0; resetta il nodo corrente a zero
b\cx=b\pathx[0]; setta le coordinate del rettangolo al primo nodo (cioe il nodo che e memorizzato nell'array)
b\cy=b\pathy[0]
movement_started=1; e il "flag" della partenza del movimento
b\posizionex=b\pathx#[0] ;questa e la partenza dell'oggetto,cioe il primo nodo!
b\posizioney=b\pathy#[0] ;idem come sopra per l'asse y
.uscita5
End Function
Function crea_alieno(speed,smooth,precis)
a.alieno=New alieno
read_path()
a\velocita#=speed
a\angolo#=0
a\angolo2#=0
a\smoothness=smooth
a\precisione=precis
a\path_counter=-1
a\distanza=0
a\current_path=0; resetta il nodo corrente a zero
a\cx=a\pathx[0]; setta le coordinate del rettangolo al primo nodo (cioe il nodo che e memorizzato nell'array)
a\cy=a\pathy[0]
;movement_started=1; e il "flag" della partenza del movimento
a\posizionex=a\pathx#[0] ;questa e la partenza dell'oggetto,cioe il primo nodo!
a\posizioney=a\pathy#[0] ;idem come sopra per l'asse y
percorso=0
End Function
Function muovi_alieno_drawn()
If creapath=0 Then Goto uscita3
For b.alieno=Each alieno
draw_current_path()
b\angolo#=0 ;setto l'angolo a zero
If b\current_path < b\path_counter Then;cosi facendo siamo sicuri che il nodo corrente sia minore di quello massimo consentito
;nell'array
b\angolo=ATan2(b\pathy[b\current_path+1]-b\pathy[b\current_path],b\pathx[b\current_path+1]-b\pathx[b\current_path])
;calcola l'angolo tra il nodo corrente e il prossimo nodo
b\cx=b\cx+Cos(b\angolo)*b\velocita;aumenta le coordinate x del rettangolo formato dal nodo e dall'origine,cioe quel rettangolo
;che si viene a formare se tracciassimo i lati dal punto di origine delle coordinate
;dello schermo a quelle del punto dove risiede il nodo
b\cy=b\cy+Sin(b\angolo)*b\velocita;aumenta le coordinate y del rettangolo formato dal nodo e dall'origine,cioe quel rettangolo
;che si viene a formare se tracceremo i lati dal punto di origine delle coordinate
;dello schermo a quelle del punto dove risiede il nodo
Color 100,200,100; cambia il colore di disegno
Rect b\cx-3,b\cy-3,6,6; disegna il rettangolino centrale alle sue coordinate
If Abs(b\cx-b\pathx[b\current_path+1]) < b\precisione And Abs(b\cy-b\pathy[b\current_path+1]) < b\precisione Then
;se le coordinate del famoso rettangolo (costruito tramite i punti di origine e del nodo...)sono entro TOT pixel
;di distanza dal PROSSIMO nodo (questa e una sorta di approssimazione,cioe e come una campo di forza che attrae
;l'oggetto...se il campo di forza e piccolo l'oggetto prosegue con l'angolatura che aveva prima e se ne
;infischiera dei nodi obbligatori...)
b\current_path=b\current_path+1; setta il nodo corrente come il prossimo nodo contenuto nell'array
b\cx=b\pathx[b\current_path]; setta le coordinate del famoso rettangolo (formato da BLA BLA BLA...)a quelle del nodo corrente
b\cy=b\pathy[b\current_path];idem come sopra con le coordinate y
;tutto questo viene calcolato con la variabile "precisione"
End If
End If
;If current_path => path_counter Then current_path=0
b\angolo2=ATan2( b\cy - b\posizioney, b\cx - b\posizionex ); calcola l'angolo tra le coordinate del nodo e quelle dell'oggetto che si vuole muovere
b\distanza=Sqr( (b\posizionex-b\cx)*(b\posizionex-b\cx)+(b\posizioney-b\cy)*(b\posizioney-b\cy) ); calcola la distanza tra loro due
DebugLog dist
DebugLog b\velocita ;apre la finestra di debug con i valori della distanza in real-time
b\posizionex=b\posizionex+(Cos(b\angolo2)/1)*(b\distanza / b\smoothness); muovi l'oggetto ad una velocita relativa alla distanza...il parametro "smoothness" e la
; "morbidezza" della curva che fara l'oggetto da muovere...piu e morbida la curva
;piu sara lenta
b\posizioney=b\posizioney+(Sin(b\angolo2)/1)*(b\distanza / b\smoothness);idem come sopra per la coordinata y
DrawImage enemy,b\posizionex,b\posizioney; disegna l'oggetto
b\path_counter=b\path_counter+1; incrementa il contatore dei nodi
;precedente funzione set_path() ora inglobata all'interno di muovi_alieno()
If b\path_counter>max_path_points-1 Then ; se il contatore dei nodi e piu grande del numero massimo di nodi resettalo a 1
b\path_counter=max_path_points-1
End If
;precedente funzione di loop tra i nodi,ora inglobata all'interno di muovi_alieno()
If b\current_path=max_path_points-1 Then; se il nodo corrente e 9 (per simulare un percorso ciclico...)
b\pathx[max_path_points-1]=b\pathx[0]
b\pathy[max_path_points-1]=b\pathy[0]
b\cx=b\pathx[0] ; setta le coordinate del rettangolo al primo path-point
b\cy=b\pathy[0]
b\current_path=0; setta il percorso corrente al primo che e stato dichiarato
End If
Next
.uscita3
End Function
Function muovi_alieno()
For a.alieno=Each alieno
draw_path_points()
a\angolo#=0 ;setto l'angolo a zero
If a\current_path < a\path_counter Then;cosi facendo siamo sicuri che il nodo corrente sia minore di quello massimo consentito
;nell'array
a\angolo=ATan2(a\pathy[a\current_path+1]-a\pathy[a\current_path],a\pathx[a\current_path+1]-a\pathx[a\current_path])
;calcola l'angolo tra il nodo corrente e il prossimo nodo
a\cx=a\cx+Cos(a\angolo)*a\velocita;aumenta le coordinate x del rettangolo formato dal nodo e dall'origine,cioe quel rettangolo
;che si viene a formare se tracciassimo i lati dal punto di origine delle coordinate
;dello schermo a quelle del punto dove risiede il nodo
a\cy=a\cy+Sin(a\angolo)*a\velocita;aumenta le coordinate y del rettangolo formato dal nodo e dall'origine,cioe quel rettangolo
;che si viene a formare se tracceremo i lati dal punto di origine delle coordinate
;dello schermo a quelle del punto dove risiede il nodo
Color 100,200,100; cambia il colore di disegno
Rect a\cx-3,a\cy-3,6,6; disegna il rettangolino centrale alle sue coordinate
If Abs(a\cx-a\pathx[a\current_path+1]) < a\precisione And Abs(a\cy-a\pathy[a\current_path+1]) < a\precisione Then
;se le coordinate del famoso rettangolo (costruito tramite i punti di origine e del nodo...)sono entro TOT pixel
;di distanza dal PROSSIMO nodo (questa e una sorta di approssimazione,cioe e come una campo di forza che attrae
;l'oggetto...se il campo di forza e piccolo l'oggetto prosegue con l'angolatura che aveva prima e se ne
;infischiera dei nodi obbligatori...)
a\current_path=a\current_path+1; setta il nodo corrente come il prossimo nodo contenuto nell'array
a\cx=a\pathx[a\current_path]; setta le coordinate del famoso rettangolo (formato da BLA BLA BLA...)a quelle del nodo corrente
a\cy=a\pathy[a\current_path];idem come sopra con le coordinate y
;tutto questo viene calcolato con la variabile "precisione"
End If
End If
;If current_path => path_counter Then current_path=0
a\angolo2=ATan2( a\cy - a\posizioney, a\cx - a\posizionex ); calcola l'angolo tra le coordinate del nodo e quelle dell'oggetto che si vuole muovere
a\distanza=Sqr( (a\posizionex-a\cx)*(a\posizionex-a\cx)+(a\posizioney-a\cy)*(a\posizioney-a\cy) ); calcola la distanza tra loro due
DebugLog dist
DebugLog a\velocita ;apre la finestra di debug con i valori della distanza in real-time
a\posizionex=a\posizionex+(Cos(a\angolo2)/1)*(a\distanza / a\smoothness); muovi l'oggetto ad una velocita relativa alla distanza...il parametro "smoothness" e la
; "morbidezza" della curva che fara l'oggetto da muovere...piu e morbida la curva
;piu sara lenta
a\posizioney=a\posizioney+(Sin(a\angolo2)/1)*(a\distanza / a\smoothness);idem come sopra per la coordinata y
DrawImage enemy,a\posizionex,a\posizioney; disegna l'oggetto
a\path_counter=a\path_counter+1; incrementa il contatore dei nodi
;precedente funzione set_path() ora inglobata all'interno di muovi_alieno()
If a\path_counter>max_path_points-1 Then ; se il contatore dei nodi e piu grande del numero massimo di nodi resettalo a 1
a\path_counter=max_path_points-1
End If
;precedente funzione di loop tra i nodi,ora inglobata all'interno di muovi_alieno()
If a\current_path=max_path_points-1 Then; se il nodo corrente e 9 (per simulare un percorso ciclico...)
a\pathx[max_path_points-1]=a\pathx[0]
a\pathy[max_path_points-1]=a\pathy[0]
a\cx=a\pathx[0] ; setta le coordinate del rettangolo al primo path-point
a\cy=a\pathy[0]
a\current_path=0; setta il percorso corrente al primo che e stato dichiarato
End If
Next
End Function
Function draw_path_points()
For loop=0 To a\path_counter; fai un loop tra tutti i nodi
Color 100,100,200
Rect a\pathx[loop],a\pathy[loop],2,2
If loop<a\path_counter Then;fai questo loop solo se il nodo corrente e piu basso del numero massimo di nodi
Rect a\pathx[loop+1]-1,a\pathy[loop+1]-1,2,2; disegna un rettangolo sul nodo
Color 50,50,150; cambia il colore di disegno
Line a\pathx[loop],a\pathy[loop],a\pathx[loop+1],a\pathy[loop+1]; disegna una linea tra il nodo corente e il prossimo
End If
Next
End Function
Function draw_current_path()
For loop=0 To b\path_counter; fai un loop tra tutti i nodi
Color 100,100,200
Rect b\pathx[loop],b\pathy[loop],2,2
If loop<b\path_counter Then;fai questo loop solo se il nodo corrente e piu basso del numero massimo di nodi
Rect b\pathx[loop+1]-1,b\pathy[loop+1]-1,2,2; disegna un rettangolo sul nodo
Color 50,50,150; cambia il colore di disegno
Line b\pathx[loop],b\pathy[loop],b\pathx[loop+1],b\pathy[loop+1]; disegna una linea tra il nodo corente e il prossimo
End If
Next
End Function
Function read_path() ;funzione che carica da file i dati dei nodi
file=ReadFile(try$) ;apro il file creato precedentemente per la lettura
If file=0 Then Goto uscita ;se non ho aperto nessun file o se il file non esiste esci dalla funzione
pointer=0 ;puntatore al movimento nel file...aumenta di 4 in 4 siccome per un valore nei
;file vengono allocati automaticamente 4 byte di dati (numeri,stringhe ecc ecc)
pointer2=0 ;puntatore al valore che,incrementando,fa si che leggo i valori nell'array ciclicamente
For x=1 To 10 ;scorre tutti e 10 i valori
SeekFile (file,pointer) ;mi muovo all'interno del file cosi
a\pathx#[pointer2]=ReadFloat (file) ;leggo il valore x ,un float-number dentro il primo valore nell'array
pointer=pointer+4 ;mi sposto al prossimo dato dentro il file
a\pathy#[pointer2]=ReadFloat (file) ;leggo il valore y
pointer2=pointer2+1 ;passo ai prossimi due valori nell'array
pointer=pointer+4 ;mi sposto ancora al prossimo dato nel file
Next
CloseFile (file) ;chiudo il file
.uscita
End Function
Function write_path_nodes()
Locate 0,570 ;mi sposto quasi alla fine dello schermo con il cursore
nomefile$=Input("Digita il nome del file da salvare:") ;digito il nome del file da salvare,ricordarsi di mettere .txt
fileout=WriteFile (nomefile$) ;scrivo il file con il nome che ho digitato sopra,se esiste gia con quel nome lo sovrascrive
try2=0 ;questo mi serve per scorrere tra il numero di nodi in modo da usare un for--next
;per leggerli tutti
For a.alieno=Each alieno ;questo va fatto per tutti i type "alieno",cioe gli oggetti che muoverò
For x=1 To 10 ;scrivi solo da x=1 a x=10,cioe scrivi 10 volte
WriteFloat (fileout,a\pathx#[try2]) ;il try tra parentesi e la variabile che contiene
WriteFloat (fileout,a\pathy#[try2]) ;il numero del nodo corrente dell'array!!!
try2=try2+1 ;incremento di uno...cioe dico che il nodo e il prossimo dell'array
Next
Next
CloseFile (fileout) ;chiudo il file
End Function
Function setpath(x,y)
path_counter=path_counter+1; incrementa il contatore dei nodi
If path_counter>max_path_points-1 Then; se il contatore dei nodi e piu grande del numero massimo di nodi resettalo a 1
path_counter=0 ;percorso ancora da iniziare
pathx(path_counter)=MouseX() ;resetto anche le coordinate x e y del primo nodo
pathy(path_counter)=MouseY()
Else; altrimenti
pathx(path_counter)=x;memorizza le coordinate x e y del nodo
pathy(path_counter)=y
End If
End Function
Function draw_current_path2()
For loop=0 To path_counter; fai un loop tra tutti i nodi
Color 100,100,200
Rect pathx(loop),pathy(loop),2,2
If loop<path_counter Then;fai questo loop solo se il nodo corrente e piu basso del numero massimo di nodi
Rect pathx(loop+1)-1,pathy(loop+1)-1,2,2; disegna un rettangolo sul nodo
Color 50,50,150; cambia il colore di disegno
Line pathx(loop),pathy(loop),pathx(loop+1),pathy(loop+1); disegna una linea tra il nodo corente e il prossimo
End If
Next
End Function
Function read_drawn_path()
If creapath=0 Then Goto uscita2 ;se non e stato premuto precedentemente il pulsante crea esci dalla funzione
punt=0
For trigger=1 To 10
b\pathx#[punt]=pathx(punt)
b\pathy#[punt]=pathy(punt)
punt=punt+1
Next
.uscita2
End Function
;******************************************************************************
;M A I N
;codice delle finestre
While Not uscita=1 ;fino a che uscita non e uguale a 1
SetBuffer BackBuffer():Cls
WaitTimer(fps_timer)
;DrawImage puntatore,MouseX(),MouseY()
provapath=0 ;devo dichiararlo sempre all'inizio altrimenti memorizza il valore anche se l'ho premuto precedentemente...
mouse1=MouseHit(1)
mouse2=MouseHit(2)
If startdrawing=1
If mouse2=True
pathx(current_path)=MouseX() ;resetto anche le coordinate x e y del primo nodo
pathy(current_path)=MouseY()
setpath(MouseX(),MouseY()) ;disegno i path-points premendo il tasto "esc"
EndIf
If pathx(9)<>pathx(0)
pathx(9)=pathx(0) ;queste due routine sono una specie di autocorrezione dell'ultimo nodo
EndIf ;facendolo diventare uguale al primo
If pathy(9)<>pathy(0)
pathy(9)=pathy(0)
EndIf
draw_current_path2()
creapath=1
EndIf
GUI()
Select EV_RELEASE()
Case Button1 ;disegno un percorso nuovo
startdrawing=1
Case Button2 ;carico un percorso
try$=IO_FileRequest$("Load path:",".txt|")
percorso=1
caricapath=0
Case Button3 ;salvo il percorso appena disegnato,non quello caricato!
write_path_nodes() ;lo salva nella directory di esecuzione del programma
salvapath=0
Case Button4 ;provo il percorso caricato
If percorso=1
crea_alieno(5,15,10)
provapath=0
percorso=0
EndIf
Case Button5 ;provo il percorso appena disegnato
crea_alieno_drawn(5,15,10)
testcurrent=0
creapath=0
startdrawing=0
Case Button6 ;decido il numero di nodi del percorso che voglio creare
Locate 0,570
num=Input("How many path nodes?:")
npath=0
Case Button7
;qui inseriremo il codice che gestisce la velocita
Case Button8
;qui quello della precisione
Case Button9
;quello della morbidezza della curva
Case Button10
enemy=LoadImage (IO_FileRequest$("Load object image:",".bmp|"))
MidHandle enemy
alieno_creato=1
;quello che sceglie l'oggetto da disegnare
Case Button11
;quello che sceglie lo sfondo
Case Button12
For a.alieno=Each alieno
Delete a
Next
For b.alieno=Each alieno
Delete b
Next
puntator=0
clearpath=0
path_counter=0
creapath=0
current_path=0
movement_started=0
percorso=0
provapath=0
startdrawing=0
Case Button13
uscita=1
Default
End Select
SetFont caratteri
If alieno_creato=1
muovi_alieno()
muovi_alieno_drawn()
EndIf
Color 200,200,200; il colore di disegno
Flip
Wend
GUI_FREEWIN(Window)
End
;E N D M A I N
I hope you don't have problem with the include files....
ps:i have run the debugger a while...but i have don't see anything strange....the speed valor is always correct....ArGh