Object movement question
BlitzPlus Forums/BlitzPlus Programming/Object movement question
| ||
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... |