Computer Science Canada Programming C, C++, Java, PHP, Ruby, Turing, VB   Username:   Password: Wiki   Blog   Search   Turing   Chat Room  Members
[tutorial] spaceship movement: asteroids style
Author Message
zylum

Posted: Mon Feb 16, 2004 6:03 pm   Post subject: [tutorial] spaceship movement: asteroids style

This tutorial is meant to teach you how to program an image to respond to key input and to create an effect of movement in space ie you keep moving it the same direction even if you aren't pressing the throttle key...

to start off, here's the full source:
 code: setscreen ("offscreenonly") var spaceship : int := Pic.FileNew ("spaceship.bmp") Pic.Draw (spaceship, 15, 20, picMerge) spaceship := Pic.New (0, 0, Pic.Width (spaceship) + 30, Pic.Height (spaceship) + 20) const rotX := Pic.Width (spaceship) div 2 const rotY := 35 const forwardSpd := 0.3 const backwardSpd := 0.2 const turnSpd := 5 const decay := 0.99 var x : real := maxx div 2 var y : real := maxy div 2 var ax, ay : real var vx, vy : real := 0 var spd : real := 0 var ang : int := 0 var ship : int var move : array char of boolean procedure moveShip     if x > maxx - rotX then         x := -rotX     elsif x < -rotX then         x := maxx - rotX     elsif y > maxy - rotY then         y := -rotY     elsif y < -rotY then         y := maxy - rotY     end if     ax := cos (ang * (Math.PI / 180)) * spd     ay := sin (ang * (Math.PI / 180)) * spd     vx += ax     vy += ay     vx *= decay     vy *= decay     x += vx     y += vy     ship := Pic.Rotate (spaceship, ang - 90, rotX, rotY)     Pic.Draw (ship, round (x), round (y), picMerge)     Pic.Free (ship) end moveShip procedure getKeyStrokes     Input.KeyDown (move)     if move (KEY_UP_ARROW) then         spd := forwardSpd     elsif move (KEY_DOWN_ARROW) then         spd := -backwardSpd     else         spd := 0     end if     if move (KEY_LEFT_ARROW) then         ang += turnSpd     elsif move (KEY_RIGHT_ARROW) then         ang -= turnSpd     end if end getKeyStrokes loop     drawfillbox (0, 0, maxx, maxy, black)     getKeyStrokes     moveShip     View.Update     delay (10) end loop

lets look at the first bit of code:

 code: var spaceship : int := Pic.FileNew ("spaceship.bmp") Pic.Draw (spaceship, 15, 20, picMerge) spaceship := Pic.New (0, 0, Pic.Width (spaceship) + 30, Pic.Height (spaceship) + 20)

in the above code, we store the image "spaceship.bmp" in a variable for later use. next we draw the spaceship on the screen and store the picture in the same variable. there is a reason for this... this time when we store the image we select and area greater than the actual image which leaves a border of nothingness around it. this is important since later when we rotate the ship, some clipping occures at the edge of the picture. with the edge being further away, the cliping doesnt occure.

 code: const rotX := Pic.Width (spaceship) div 2 const rotY := 35 const forwardSpd := 0.3 const backwardSpd := 0.2 const turnSpd := 5 const decay := 0.99

this chunk of code controls all the characteristics of the movement such as the speed of the ship when its accelerating forwrad or how fast the ship turns. the constants rotX and rotY is where the ship will pivot when it's being rotated.

 code: procedure moveShip     if x > maxx - rotX then         x := -rotX     elsif x < -rotX then         x := maxx - rotX     elsif y > maxy - rotY then         y := -rotY     elsif y < -rotY then         y := maxy - rotY     end if     ax := cos (ang * (Math.PI / 180)) * spd     ay := sin (ang * (Math.PI / 180)) * spd     vx += ax     vy += ay     vx *= decay     vy *= decay     x += vx     y += vy     ship := Pic.Rotate (spaceship, ang - 90, rotX, rotY)     Pic.Draw (ship, round (x), round (y), picMerge)     Pic.Free (ship) end moveShip

this is the procedure which controls all the movements of the ship...

 code: if x > maxx - rotX then     x := -rotX elsif x < -rotX then     x := maxx - rotX elsif y > maxy - rotY then     y := -rotY elsif y < -rotY then     y := maxy - rotY end if

this is where we check whether the ship has reached the edge of the screen, if so, we "rollover" the ship to the other side of the screen.

 code: ax := cos (ang * (Math.PI / 180)) * spd ay := sin (ang * (Math.PI / 180)) * spd vx += ax vy += ay vx *= decay vy *= decay x += vx y += vy

since this type of movement is a bit more complex than the tradition point and go movement, we need a few more variables.... the ax and ay variables store the value of the acceleration upon that axis. this value is calculated with a bit of trig

 code: cos (ang * (Math.PI / 180)) sin (ang * (Math.PI / 180))

this returns a value betwee 0 and 1 depending on the angle spcified. the angle is converted into radians by multiplying it by PI/180. this number is then multiplied by the speed and you end up with your acceleration values.

 code: vx += ax vy += ay vx *= decay vy *= decay x += vx y += vy

this bit is fairly self explanitory especially if you've taken physics. it adds the acceleration vectors to the velocity vectors and then the velocities are added to the x and y coordinates of the spaceship.

 code: ship := Pic.Rotate (spaceship, ang - 90, rotX, rotY) Pic.Draw (ship, round (x), round (y), picMerge) Pic.Free (ship)

here we rotate our original spaceship image around the rotX and rotY coordinates (the pivot point) by the specified angle and then we draw it and free the memory. we free the image from the memory because that's the only time we will use it -> the next loop will update it.

 code: procedure getKeyStrokes     Input.KeyDown (move)     if move (KEY_UP_ARROW) then         spd := forwardSpd     elsif move (KEY_DOWN_ARROW) then         spd := -backwardSpd     else         spd := 0     end if     if move (KEY_LEFT_ARROW) then         ang += turnSpd     elsif move (KEY_RIGHT_ARROW) then         ang -= turnSpd     end if end getKeyStrokes

this simply checks which keys are pressed and alters the appropriate variables accordingly.

 code: loop     drawfillbox (0, 0, maxx, maxy, black)     getKeyStrokes     moveShip     View.Update     delay (10) end loop

finally we put the two procedures together in a loop.
everytime it loops, we erase our old screen by drawing a blackbox over it. then we check which keys are being pressed by calling the getKeyStrokes procedure. then we move and draw the space ship by calling the moveShip procedure. finally we update the screen and add a delay to control the speed of the game.

phew!!! that took some time! hope you guys enjoy this tutorial

-zylum

by the way here's the graphic for the spaceship:

zylum

Posted: Mon Feb 16, 2004 6:05 pm   Post subject: (No subject)

the graphic:

 can't seem to get the bmp to attach... is bmp a valid file type???
here's a url to the image:
http://zylum1.tripod.com/spaceship2.bmp
[/edit]
Cervantes

Posted: Mon Feb 16, 2004 6:18 pm   Post subject: (No subject)

just change it to a jpg file.
zylum

Posted: Mon Feb 16, 2004 6:25 pm   Post subject: (No subject)

damn...
try to copy and paste the url into your browser if that doesnt work here's the jpg:
AsianSensation

Posted: Mon Feb 16, 2004 6:31 pm   Post subject: (No subject)

i like it, add to this some FPS, add some nice gfx, and you can have a nice and easy asteroid game.

one thing though, when you were doing this:
 code: ship := Pic.Rotate (spaceship, ang - 90, rotX, rotY) Pic.Draw (ship, round (x), round (y), picMerge) Pic.Free (ship)
just like the cosine-sine problem you had with the 3d thingie, it's not as fast as generating all the pictures and then call them when you needed it.

here, have some bits for your effort.

+25 bits

Edit: it seems the donate and the +- bits option are messed, I'll owe you 25 bits for now, remind me later.
Cervantes

Posted: Mon Feb 16, 2004 6:35 pm   Post subject: (No subject)

niiiice...
This is really similar to Asians tutorial but meh, still good

This brings up memories of comet busters
zylum

Posted: Mon Feb 16, 2004 6:41 pm   Post subject: (No subject)

what do you mean by:
"just like the cosine-sine problem you had with the 3d thingie, it's not as fast as generating all the pictures and then call them when you needed it. "

my 3d engine doesnt draw pics, it draws polygons... further more, it just has to generate 1 pic every frame which isnt that bad.

btw i already made an asteroids game and it runs just fine... i'll post it tomorrow since the latest draft is stored there, but for now heres a basic version:
AsianSensation

Posted: Mon Feb 16, 2004 6:43 pm   Post subject: (No subject)

I meant that instead of generating on the spot and then freeing the picture memory, it's faster to pre-generate everything and then call on the appropriate picture. Much like instead of generating sine and cosine values, it's faster to pre-generate a table and then call it instead of calling it on the spot. The difference being Pic.Rotate takes up alot of time, so when you have asteroid flying all over, it's going to lag the game down very badly.

zylum

Posted: Mon Feb 16, 2004 6:47 pm   Post subject: (No subject)

well, i'd have to store 72 images if i wanted im increment of 5 degrees while turning -_- i think one Pic.Rotate isn't that bad (the asteroids themselves dont rotate)
Cervantes

Posted: Mon Feb 16, 2004 7:18 pm   Post subject: (No subject)

An increment of 10 looks fine. that's 36 different images. If you think about it, that's a lot. It wouldn't look all that smooth if the image you were rotating was a long thin line, but with a small fat ship like that (jk it looks really cool) you don't really notice it.
AsianSensation

Posted: Mon Feb 16, 2004 7:27 pm   Post subject: (No subject)

I was assuming that you were also rotating the asteroid, then you would need to generate pics pre-hand. Also, from my experience, 10 degree increments would look fine on most pictures (not extremely large ones)

but generating pictures and storing them won't take up that much memory at all, if you want, you could even declare them as const int instead of int.

Posted: Wed Feb 18, 2004 10:25 am   Post subject: (No subject)

a cool program
Jodo Yodo

Posted: Tue Mar 02, 2004 10:53 pm   Post subject: (No subject)

How come when I use Math.PI, it says it's not an export of 'Math'?
zylum

Posted: Tue Mar 02, 2004 10:59 pm   Post subject: (No subject)

you need version 4.0.5 to use Math.PI... you can always replace that with 3.14159 if you dont want to update

-zylum
Paul

Posted: Sat Jan 08, 2005 9:44 am   Post subject: (No subject)

Sorry for bringing this old one up, but I'm making one right now. Basically what I've got so far is your code (but I made it myself from understanding every part of your code first). And a second picture for when the ship is thrusting, it has exhaust. But there are still a couple of things I don't understand:
 code: AccX := cos (angle * (Math.PI / 180))*speed AccY := sin (angle * (Math.PI / 180))*speed

since I haven't learnt radians yet, how does "cos (angle * (Math.PI / 180))*speed" give you the component of acceleration for x, similarly for y. Could you possibly explain this in non-technical terms?
also: why "angle - 90"? why 90? I think this also has something to do with not knowing radians.
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

Page 1 of 2  [ 16 Posts ]
Goto page 1, 2  Next
 Jump to:  Select a forum  CompSci.ca ------------ - Network News - General Discussion     General Forums   -----------------   - Hello World   - Featured Poll   - Contests     Contest Forums   -----------------   - DWITE   - [FP] Contest 2006/2008   - [FP] 2005/2006 Archive   - [FP] 2004/2005 Archive   - Off Topic     Lounges   ---------   - User Lounge   - VIP Lounge     Programming -------------- - General Programming     General Programming Forums   --------------------------------   - Functional Programming   - Logical Programming   - C     C   --   - C Help   - C Tutorials   - C Submissions   - C++     C++   ----   - C++ Help   - C++ Tutorials   - C++ Submissions   - Java     Java   -----   - Java Help   - Java Tutorials   - Java Submissions   - Ruby     Ruby   -----   - Ruby Help   - Ruby Tutorials   - Ruby Submissions   - Turing     Turing   --------   - Turing Help   - Turing Tutorials   - Turing Submissions   - PHP     PHP   ----   - PHP Help   - PHP Tutorials   - PHP Submissions   - Python     Python   --------   - Python Help   - Python Tutorials   - Python Submissions   - Visual Basic and Other Basics     VB   ---   - Visual Basic Help   - Visual Basic Tutorials   - Visual Basic Submissions     Education ----------- - Student Life   Graphics and Design ----------------------- - Web Design     Web Design Forums   ---------------------   - (X)HTML Help   - (X)HTML Tutorials   - Flash MX Help   - Flash MX Tutorials   - Graphics     Graphics Forums   ------------------   - Photoshop Tutorials   - The Showroom   - 2D Graphics   - 3D Graphics     Teams ------ - dTeam Public

 Style: Appalachia blueSilver eMJay subAppalachia subBlue subCanvas subEmjay subGrey subSilver subVereor Search: