![]() |
Forum Index : Microcontroller and PC projects : Help with using Sprite for the first time
Author | Message | ||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 369 |
Hi all I am attempting to use SPRITEs for the first time (as a number geek I only every program for fun in "text" mode with the output normally being numbers or similar). I have ported some old code to simulate the trajectory of a ballistic shell: Const dt=.1 'timsslice, smaller = more accurate,but slower Const v_int = 700 'muzzle velocity. Rifle = 600m/s Tank = 1500 Const angle= 37 'launch angle in degrees Const theta = angle*PI/180 ' convert degrees to radians Const A_m = 0.00004 ' expeimental drag factor from Bennett Const nmax = 10000 ' number of iterations Const A_m2 = 0.004 ' surface area of projectile Const wind =-35 'wind speed. 40 = hurricane -ve means headwind Const rho = 1.2 ' density of air Const wind_force = (0.5*A_m2*rho*wind^2*dt) max_x = 25000 max_y = 9000 mode 1,8 cls Function round(num,dp) ' provids proper rounding exp= 10^dp n = num* exp If n >= 0 then n = sgn(n) * (abs(int(n+0.5))) ElSE n= sgn(n) * (abs(int(n-0.5))) End if round = n / exp End function Dim x(nmax), y(nmax) ' arrays to stor x and y positon Sub calculate x(1) = 0 y(1) = 0 vx = v_int * cos(theta) vy = v_int * sin(theta) for i = 2 to nmax x(i) = x(i-1)+(vx*dt) 'calculate new x based on previous y(i) = y(i-1)+(vy*dt) f=A_m*sqr(vx^2+vy^2) vy = vy - (9.8*dt)-(f*vy*dt) vx = vx - (f*vx*dt)+(wind_force*sgn(wind)) if y(i) <=0 then index=i exit for end if if y(i) > max_height then max_height = y(i) next i xrange = (x(i)+x(i-1))/2 print "Range = " round(xrange,0) "m" print "Max Height = " round(max_height,0) "m" print "Index = " index end sub calculate() axes() draw() sub axes() line 0,0,0,600,3 line 0,550,650,550,3 end sub sub draw() for i = 1 to index pixel((x(i)/25000)*650)+3,(550-((y(i)/max_height)*550)) next i End sub Text 700,100,"Range "+ str$(round(xrange,0)) The code takes drag and wind into account. Very rough at the moment. How would I go about adding a SPRITE animation that follows the trajectory as it is drawn -- a cannon ball would be easiest as there would be no orientation issues at the top of the trajectory. Total newbie with regard to this - will poke around the programs posted here to get insight from their code. Any help greatly recievd. Cheers Nim Entropy is not what it used to be |
||||
capsikin Guru ![]() Joined: 30/06/2020 Location: AustraliaPosts: 341 |
There's 4 main parts: Loading the sprite graphics, drawing the sprite the first time, moving the sprite, erasing the sprite at the end. It's relatively simple since you don't need overlapping sprites or to change the background underneath the sprite. Loading the sprite graphics, it may be easiest to draw it somewhere on screen with the CIRCLE command, then use SPRITE READ to read the sprite graphics from the screen. Drawing the sprite for the first time, and moving the sprite, both can be done with the SPRITE SHOW command. Erasing the sprite at the end, if you want to do this, can be done with the SPRITE HIDE command. For moving the sprite, an alternative is SPRITE NEXT then SPRITE MOVE. You don't need this for just a single sprite, but examples you find may do this as it caters better for multiple overlapping sprites. More details on the uppercase commands I've listed are in the manual (and of course others are welcome to chime in with more info) additional: if you want a better graphic for the sprite than just circles, SPRITE LOAD is a good option, to load it from a text file. The format's not detailed in the manual, so you can check out "Graphics Programming on the CMM2" and/or example programs that use it. Or it's specified in the original Colour Maximite MMBasic Language Manual, apparently. additional: I linked to Graphics Programming on the CMM2 from the wiki Edited 2020-08-25 00:27 by capsikin |
||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 369 |
Thank you @capsikin >> good pointers. I used that (and a look at the Lander prog listed before) and have this -- it works fine, but the cannon ball "tears" as is moves across the screen. What techniques can I use to make it smoother? Sorry for the really basic Q's Const dt=.5 'timsslice, smaller = more accurate,but slower Const v_int= 700 'muzzle velocity. Rifle = 600m/s Tank = 1500 Const angle= 45 'launch angle in degrees Const theta = angle*PI/180 ' convert degrees to radians Const A_m = 0.00004 ' expeimental drag factor from Bennett Const nmax = 10000 ' number of iterations Const A_m2 = 0.004 ' surface area of projectile Const wind =-35 'wind speed. 40 = hurricane -ve means headwind Const rho = 1.2 ' density of air Const wind_force = (0.5*A_m2*rho*wind^2*dt) max_x = 25000 max_y = 9000 mode 1,8 cls page write 2 load png "cball.png" 'load sprite from file image resize 0,0,110,111,0,0,20,20,2 'make it smaller -- should resize the file sprite read 1,0,0,20,20,2 'read into sprite 1 page write 0 'sprite show 1,0,0,1 Function round(num,dp) ' provids proper rounding exp= 10^dp n = num* exp If n >= 0 then n = sgn(n) * (abs(int(n+0.5))) ElSE n= sgn(n) * (abs(int(n-0.5))) End if round = n / exp End function Dim x(nmax), y(nmax) ' arrays to stor x and y positon Sub calculate x(1) = 0 y(1) = 0 vx = v_int * cos(theta) vy = v_int * sin(theta) for i = 2 to nmax x(i) = x(i-1)+(vx*dt) 'calculate new x based on previous y(i) = y(i-1)+(vy*dt) f=A_m*sqr(vx^2+vy^2) vy = vy - (9.8*dt)-(f*vy*dt) vx = vx - (f*vx*dt)+(wind_force*sgn(wind)) if y(i) <=0 then index=i exit for end if if y(i) > max_height then max_height = y(i) next i xrange = (x(i)+x(i-1))/2 print "Range = " round(xrange,0) "m" print "Max Height = " round(max_height,0) "m" print "Index = " index end sub calculate() axes() draw() sub axes() line 0,0,0,600,3 line 0,550,650,550,3 end sub sub draw() sprite show 1,0,599,1 'put sprite onto screen for i = 1 to index sprite next 1,((x(i)/25000)*650)-10,(550-((y(i)/max_height)*550)-10) pause 5 sprite move next i End sub Text 700,100,"Range "+ str$(round(xrange,0)) Entropy is not what it used to be |
||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 369 |
Thanks for the link to the graphics guide - rtfm!! Entropy is not what it used to be |
||||
capsikin Guru ![]() Joined: 30/06/2020 Location: AustraliaPosts: 341 |
One technique is to render to a separate page (PAGE WRITE to choose the page), then copy to page 0 (PAGE COPY) at screen blanking time (MODE to set the screen blanking interrupt). Lunar lander does the rendering to a separate page but not the screen blanking timing. matherp recently posted a demo that does it. tennis.zip from here: https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=12600#153265 Another idea I had is to skip the SPRITE MOVE commands when the area around the sprite is being output to the display. Could use GETSCANLINE "This will report on the line that is currently being drawn on the VGA monitor. Using this to time updates to the screen can avoid timing effects caused by updates while the screen is being updated". |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1121 |
Lunar Lander does use screen blank timing. The command "PAGE COPY <source>,0,B" is key. (Note the manual indicates "TO" between the source and destination, but a comma works just as well.) The idea is to do all your drawing on a non-visible page. Only page 0 is visible. When you have finished drawing, you copy the image page to page 0. The extra parameter "B" indicates to pause your program until the next vertical blanking, then perform the copy and finally release execution back to your program. The manual gives a couple of other options for the PAGE COPY command too. The key is to absolutely not be changing the source image while the page copy is happening if you are not using the "B" parameter. Visit Vegipete's *Mite Library for cool programs. |
||||
capsikin Guru ![]() Joined: 30/06/2020 Location: AustraliaPosts: 341 |
Sorry, my mistake, I only checked for SETTICK and MODE interrupts. |
||||
x4nd Newbie ![]() Joined: 05/07/2020 Location: United KingdomPosts: 11 |
An alternative to perhaps look at is to use the MODE command with a function that gets run in the vblank period. That function would do your calculation for the next frame. As long as it was quick, you'd get it all ready for the next screen refresh and so suffer no screen tear. If only there were more hours in the day.. |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |