Hi to all.
I'm making some movement function (i call them when i whant the alien in my game move...);now i have some basic movement (like straight direction[easy to code],zig-zag[easy to code,it's basically two straight direction at once :P] but if i want to implement some complex movement (like clockwise move)or some path movement.....what's the best way to do this?
I ear of precalculated table and so on....but i don't figured out how to do it yet :(
Is also difficult to make some sort of line movement like this?(in precalculated path,like i draw a line and they follow that line)
Example:follow this path from O to X
O------------
\ |---------|
\ | |
\ | |
---------- |
|
|
|
|----------------|
|
|
X
Thanks
Hi
To move something in a circular motion, try somat like this:
; ----------------------------------------------------------
Graphics 640, 480, 32, 2
Global x#, y#, t#
Repeat
Cls
x = 100 * Sin(t)
y = 100 * Cos(t)
Text 320 + x, 240 + y, "@"
Flip
t = t + 1
Until MouseHit(1) = True
; ----------------------------------------------------------
to change the direction and speed of the rotation adjust the code:
t = t + 1
to change the shape of the circle motion adjust the '100 *' bit of code:
x = 100 * Sin(t)
y = 100 * Cos(t)
Hope this helps
Mr Brine
Hi Again
this code moves things along a line, click any where in the window and the "@" symbol will move their. escape quits
Notes:
- SQR function is pretty processor intensive.
- to change the speed of the movement alter the speed parameter of the calcgradient function, in the program loop.
;---------------------------------------------------------------------
Graphics 640, 480, 32, 2
Type gradient
Field sx#, sy#
Field fx#, fy#
Field xg#, yg#
End Type
Global g.Gradient = New Gradient
Function CalcGradient(fx, fy, speed#)
Local xd#, yd#
Local length#
g\fx = fx
g\fy = fy
xd = fx - g\sx
yd = fy - g\sy
length = Sqr(Float(xd * xd + yd * yd))
g\xg = xd / length * speed
g\yg = yd / length * speed
End Function
Function AddGradient()
g\sx = g\sx + g\xg
g\sy = g\sy + g\yg
End Function
Repeat
Cls
If(MouseHit(1) = True)
CalcGradient(MouseX(), MouseY(), 1)
Else
Text g\sx, g\sy, "@"
AddGradient()
End If
Flip
Until KeyHit(1) = True
;---------------------------------------------------------------------
hope this helps also
Mr Brine
Thanks
Yes,for circular movements only works(but i see that flicker too much....the object make jump instead of pixel movement..)
Here's the code of your suggestion:
Graphics 640, 480, 32, 2
player=LoadImage("jet6.TGA")
Global x#, y#, t#
Repeat
Cls
x = 100 * Sin(t)
y = 100 * Cos(t)
DrawImage player,50+x,200+y
Flip
t = t + 1
Until MouseHit(1) = True
if you run it do you understand what i'm saying (sorry for bad translation)
I have made this code copying the Krylar code in tutorials...but don't work!
And i think it's related to types...and types variables but i don't know why,what and where :)
Here's the code:
(\code)
Graphics 640,480,32,1
SetBuffer BackBuffer()
giocatore=LoadImage("jet6.TGA")
Global nemico=LoadImage("alien1.TGA")
Global missile=LoadImage("missile.BMP")
frametimer=CreateTimer(60)
;inizio codice rotazione
Const iNumRotations=36
; next we need an array to hold the images
Dim ObjectFrames(iNumRotations)
; now we need two arrays so we can pre-computed our
; Sin/Cos tables...helps speed things up
Dim XSinTable#(iNumRotations)
Dim YCosTable#(iNumRotations)
; now actually call the function that pre-computes
PrecomputeSinCosTables()
; Load the Object and do the rotations
LoadObject("alien1.tga", iNumRotations)
; initialize the Object to point north
Global ObjectDir = 0
; This controls the Object so it doesn't shake about
; when it gets close to the target. You can adjust
; this, but it seems that .01 is working well.
Global Smoothness# = .02
; initialize the X,Y locations of the Object
Global X# = 400
Global Y# = 300
; initialize the Speed# used
Global Speed# = 4
Global XTarget# = 500
Global YTarget# = 450
;fine codice rotazione
MidHandle giocatore
MidHandle nemico
MidHandle missile
Global jetx,jety
Global nem.nemico
Type proiettile
Field posizioneX
Field posizioneY
Field durata
Field velocita
Field aspetto
Field potenza
End Type
Type nemico
Field movimento
Field velocita
Field vitalita
Field aspetto
Field potenza
Field esplosione
Field punteggio
Field posizioneX
Field posizioneY
Field utile
Field negativo
Field positivo
;aggiunte al type
Field XTarget#
Field YTarget#
Field ObjectDir
Field X#
Field Y#
;Field Speed#
;fine aggiunte al type
End Type
;main
Repeat
Cls
WaitTimer(frametimer)
If MouseHit(2)
crea_nemico(2,300,50,3,nemico,100)
EndIf
muovi_nemico()
jetx=MouseX()
jety=MouseY()
DrawImage giocatore,jetx,jety
If MouseHit(1) Then crea_proiettile()
muovi_proiettile()
VWait
Flip
Until KeyHit(1)=1
End
;end main
Function crea_proiettile()
bullet.proiettile=New proiettile
bullet\posizioneX=MouseX() ;the x position of missile creation is the mouse coords(the same coords of my jet of course)
bullet\posizioneY=bullet\posizioneY+MouseY()-45 ;the missile creation start a bit up to the jet(for simulating the launch-bay hehe)
bullet\velocita=5 ;the speed of the missile
bullet\durata=300 ;the starting value of the animation
End Function
Function muovi_proiettile()
For bullet.proiettile=Each proiettile
DrawImage missile,bullet\posizioneX,bullet\posizioneY
bullet\posizioneY=bullet\posizioneY-bullet\velocita ;this move the missile up
bullet\durata=bullet\durata-bullet\velocita ;this start the counter of the missile course
If bullet\durata=<0 Then Delete bullet
Next
End Function
Function crea_nemico(moto,partenzaX,partenzaY,velocita,immagine,vita)
nem.nemico=New nemico
nem\movimento=moto
nem\velocita=velocita
nem\vitalita=vita
nem\aspetto=immagine
nem\potenza=nem\potenza ;da aggiungere in seguito
nem\esplosione=nem\esplosione ;da aggiungere in seguito
nem\punteggio=nem\punteggio ;da aggiungere in seguito
nem\posizioneX=x#
nem\posizioneY=y#
nem\utile=partenzaX
nem\negativo=-velocita
nem\positivo=+velocita
;inizializzazione del nemico
nem\XTarget# = MouseX() ;quello che puntera il nemico
nem\YTarget# = MouseY() ;quello che puntera il nemico
nem\ObjectDir = AngleToTarget(nem\X#,nem\Y#,nem\XTarget#,nem\YTarget#, Speed#,CurrentObjectDir, iNumRotations,Smoothness#)
nem\X# = nem\X# + (xSinTable#(ObjectDir) * Speed#)
nem\Y# = nem\Y# + (yCosTable#(ObjectDir) * Speed#)
;fine inizializzazione
End Function
Function muovi_nemico()
For nem.nemico=Each nemico
CurrentDistance# = GetDistance#(X,Y,XTarget,YTarget)
If CurrentDistance < 1
nem\X# = nem\X# - (xSinTable#(ObjectDir) * Speed#)
nem\Y# = nem\Y# - (yCosTable#(ObjectDir) * Speed#)
Speed# = 0
nem\ObjectDir = CurrentObjectDir
Text 0,84,"Hit Target!"
Else
Speed# = 2
EndIf
DrawImage(ObjectFrames(ObjectDir),nem\X#,nem\Y#)
;DrawImage nem\aspetto,nem\posizioneX,nem\posizioneY
;If nem\movimento=1 Then moto_verticale()
;If nem\movimento=2 Then moto_sindes()
;If nem\movimento=3 Then moto_centrato()
If nem\vitalita=<0
Delete nem
Exit
EndIf
;If nem\posizioneY=>500
; Delete nem
; Exit
;EndIf
Next
End Function
Function moto_verticale()
nem\posizioneX=nem\posizioneX
nem\posizioneY=nem\posizioneY + nem\velocita
End Function
Function moto_sindes()
nem\posizioneY=nem\posizioneY + (nem\positivo / 2) ;movimento verso il basso a meta velocita
nem\posizioneX=nem\posizioneX+nem\velocita ;movimento verso destra inizio
If nem\posizioneX => nem\utile+100 ;se fa cento passi a sin cambia direzione
nem\posizioneX = nem\posizioneX - nem\velocita ;e va verso destra
nem\velocita = nem\negativo ;il movimento sara ora negativo!!!
EndIf
If nem\posizioneX <= nem\utile -100 ;se fa cento passi a destra cambia direzione
nem\posizioneX = nem\posizioneX + nem\velocita ;e va verso destra come all'inizio
nem\velocita = nem\positivo ;il movimento ora ritorna positivo!!!
EndIf
End Function
Function PrecomputeSinCosTables()
Local iAngle# = 0
; run through the full rotation cycle, and use Sin and Cos
; at 10-degree increments
Multiplyer = 360/iNumRotations
For iAngle = 0 To iNumRotations-1
xSinTable#(iAngle) = Sin(iAngle*Multiplyer)
yCosTable#(iAngle) = -Cos(iAngle*Multiplyer)
Next
End Function
Function AngleToTarget(X#, Y#, XTarget#, YTarget#,Speed#, ShipDir, Rotations,Smoothness#)
; Calculate what the next x,y position of the ship would be
; if it kept moving in its current direction
StraightX# = nem\X# + (xSinTable#(ShipDir) * Speed#)
StraightY# = nem\Y# + (yCosTable#(ShipDir) * Speed#)
; Calculate what the next x,y position of the ship would be
; if it turned one unit left and moved forward from there
LeftShipDir = ShipDir - 1
If LeftShipDir < 0
LeftShipDir = Rotations - 1
EndIf
LeftX# = nem\X# + (xSinTable#(LeftShipDir) * Speed#)
LeftY# = nem\Y# + (yCosTable#(LeftShipDir) * Speed#)
; Calculate what the next x,y position of the ship would be
; if it turned one unit right and moved forward from there
RightShipDir = ShipDir + 1
If RightShipDir > Rotations - 1
RightShipDir = 1
EndIf
RightX# = nem\X# + (xSinTable#(RightShipDir) * Speed#)
RightY# = nem\Y# + (yCosTable#(RightShipDir) * Speed#)
; using our above calculated projections, let's see what
; the distance is between the target and each projection
StraightDist# = GetDistance#(StraightX,StraightY,nem\XTarget,nem\YTarget)
LeftDist# = GetDistance#(LeftX,LeftY,nem\XTarget,nem\YTarget)
RightDist# = GetDistance#(RightX,RightY,XTarget,nem\YTarget)
; if the Left distance is less than the Straight and the
; Right distances, the the best direction to turn would
; be left. That will bring us closer to the target.
If LeftDist < StraightDist And LeftDist < RightDist
; see if there is enough of an angle to warrant
; changing the dir...if this was left out the ship
; will shake madly when it gets close to the target
If StraightDist - LeftDist > Smoothness
; change the ship dir accordingly
ShipDir = LeftShipDir
EndIf
EndIf
; if the Right distance is less than the Straight and the
; Left distances, the the best direction to turn would
; be Right.
If RightDist < StraightDist And RightDist < LeftDist
; see if there is enough of an angle to warrant
; changing the dir...if this was left out the ship
; will shake madly when it gets close to the target
If StraightDist - RightDist > Smoothness
; change the ship dir accordingly
ShipDir = RightShipDir
EndIf
EndIf
; return the appropriate direction
Return(ShipDir)
End Function
Function GetDistance#(XSource#,YSource#,XTarget#,YTarget#) ; find the difference between the source and target
XDist# = nem\XTarget - XSource
YDist#= nem\YTarget - YSource
; use a little math
TotalDist# = Sqr#((XDist * XDist) + (YDist * YDist))
; return the value
Return (TotalDist)
End Function
Function LoadObject(ObjectName$,Rotations)
; tell BB to handle the centering of our images
AutoMidHandle True
; Load the player image and point to it with "imgTemp"
imgTemp = LoadImage(ObjectName$)
; see if the image was loaded successfully
If imgTemp = 0
Text 100,100,"Invalid Image!"
Else
; set it's mask (transparent color)
MaskImage imgTemp,0,0,0
; now run through the loop and rotate the image
For iLoop=0 To Rotations-1
; first copy the original image into the current frame
ObjectFrames(iLoop)=CopyImage( imgTemp )
; rotate the frame the appropriate number of degrees
RotateImage ObjectFrames(iLoop), iLoop*360/Rotations
Next
EndIf
End Function
(\endcode)
Thanks.
ps:your last example is what i'm thinking [but has the same jump movement of the previous example...sorry but don't know how to improve it!]
ARGHHHHHHHHHHHH what an idiot that i'm!
I forgot to digit "setbuffer backbuffer()" so it's why your examples flicker!
Excuse for my hemm.....newbie error.
But i'm not able to understand why my code doesn't work...