How to make Asteroids in an hour or so
BlitzMax Forums/BlitzMax Tutorials/How to make Asteroids in an hour or so
| ||
A "step by step" guide on how to make a simple game. Contains: - Short on gamedesign and planing - Code structure - Vector Physics (you can always copy N paste it) Dowload ZIP with source,images, pdf and doc here: How to make Asteroids in an hour or so! html version see post below Feel free to post your suggestions, improvements, questions and comments. |
| ||
I tried adding <code> </code> tags around your code but that blew the margins out so have tried with <codebox> instead which I don't really like either, this one's a mix of the two: A "step by step" guide on how to make a simple game by Wave. Contains: - Short on gamedesign and planing - Code structure - Vector Physics (you can always copy N paste it) Dowload ZIP with source,images, pdf and doc here: How to make Asteroids in an hour or so! And in crappy html, without tabs because they don't copy?!: How to make asteroids in an hour or so This is a step by step example of how to make a simple asteroids clone. I’ll be simple and should show a good practical example for people new to BlitzMax. First we need a plan, a design plan to be exact. Asteroids are a simple game so it’s not going to be very long. The design part is one of the most important steps in making a game. Without it or if it lacks in detail you’ll have to remake and change stuff which in turn will result in a longer production time. Overview Design Visual (Design) • Explain how it would be to play the game • The goal of the game • Draw sample images of the game in action Technical (Programming) • Types Overview • Methods/functions Overview • Image/sound files In a bigger game this would be much more complicated and involve many more steps. Start your stopwatch (on your mobile) and get ready to make asteroids in an hour or so. Asteroid Wars – Design Overview Overview – what’s the game about? This game is similar to the classic asteroids. This version will be simple, fast-paced and difficult. Controls – How does the player interact? The player can rotate this ship, clockwise and counter-clockwise with the left and right keys. He can control his thrust with up and reverse thrust (80%) by pressing down. The player can fire in the direction of their ship by pressing space. Game play – What does the player do? The game is played in levels and the goal of each level is to destroy stones. Stones come in three sizes, small, medium and large. You start each level with one ship. When you hit a stone it breaks into smaller stones except small stones that evaporate into dust. The first level you meet one medium stone, as you progress through levels the starting stones increases in numbers while getting larger. The game has infinite levels. If you hit a stone you will destroy your ship = game over. One life only... Goal The long term goal of the game is to get the highest score possible. That was the design part of our game plan. At “Game Play” you should draw on paper some ideas of the “look and feel” so that the game gets easier to visualize later on when you are making the graphics. I skipped that part this time... Now it’s time for the technical stuff. We are using BlitzMax so let’s get down to the types we want to use and what graphics we require. Data structures: TShip, TShot, TRock each inherit TSpaceObject I have decided each of these should have their own file named “NameofType.bmx” This is actually not redundant in this simple game, it will give your code more structure and in the end it will save us time. See it as good practice. I’ll have one file called AsteroidWars, in which the actual game loop will be and from which the game is going to be run. The methods and functions of SpaceObject are: Create – Function, New, Update, UpdateAll – Function, Destroy, Draw The rest I’ll make when I see they are required. Start to code Ok let’s get down to programming, start by creating all bmx-files we need. Open the new and empty “TSpaceObject.bmx” The first thing to do would be to define the Type’s fields. We need: X and Y for position Direction for rotation Thrust for speed in current direction. Implement the methods, they should be empty for now. Keep this file open so that you can easily check back later. TSpaceObject.bmx Type TSpaceObject Field X#,Y# Field XSpeed#,YSpeed# Field Direction Function Create() EndFunction Function UpdateAll() EndFunction Method New() EndMethod Method Update() EndMethod Method Destroy() EndMethod Method Draw() EndMethod End Type Create the files TShip.bmx, TRock.bmx, TShot.bmx and AsteroidWars.bmx. Have them all open at the same time. Go to main and import TSpaceObject, TShip, TRock and TShot. AsteroidWars.bmx Include "SpaceObject.bmx" Include "Ship.bmx" Include "Shot.bmx" Include "Rock.bmx" Jump to TShip, because now we are going to get things moving. Create the Type (guess the name yourself) and extend it from (guess again). TShip.bmx Type TShip Extends TSpaceObject End Type So far so good, when you are making you own game try using a similar approach with multiple files. If this game would have been made in one file it would have been much harder to get a good overview. As soon as you have several types you should jump to several files. Our type TShip might look very empty but don’t get fooled by that! TShip extends TSpaceObject therefore it contains every field and method that TSpaceObject contains. I’ll start with Create() – It needs to spawn a new Ship type and add that type to a list. We need someplace to keep this list so create a global in the TShip Type called List, it need to be of the TList Type. We also need to create the list the first time it is used. We are only going to have one ship so I don’t really need to add it to a list, but I want to be open in case someone wants to add more players, AI, enemies or perhaps even multiplayer support and it makes the example more general. We also want to setup some default values, startX and startY. Make a method New() and set the default values of X and Y. New() is called when you create a new instance of the type it lies in. TShip.bmx Type TShip Extends TSpaceObject Global List:TList Global Image:Timage Function Create() Ship:TShip = New TShip If List = Null List = CreateList() List.AddLast Ship 'Add Ship Last in List EndFunction Method New() X = 300 Y = 400 EndMethod End Type Time for a break... This part can take forever but I’m confident that if you focus you can make it within 20min and 30sec. Open up your favorite paint/graphics program. With favorite I mean the program you are best at. How you make the graphics are up to you, this is just the guide lines. Make a new picture at a good ship-size, I’ll make it 25x25 pixels. Paint a high-tech space ship in this small image while using black as your background color. Save as.. ”ship.png” if you can’t save as png try jpg or bmp. We got two more images we need, shot and rock. Make a new image 20x10, this is going to be our shot or missile. Use black as background. I saved it as ”missile.png” in the same folder. Next image is the rock. It need to be much bigger than our ship. I’ll make only one rock and then I will scale it to the smaller sizes. Make it 100x100 and fill it with a stone texture or something. Now load our ”ship.png” image in the Function create() you will also have to center the image using MidHandleImage( Image ). Our image is set to a global; all ships will look the same. Make a new method called Draw(). In draw we want to set image rotation to our ship’s rotation, and then draw it at our current position. TShip.bmx Type TShip Extends TSpaceObject Global List:TList Global Image:Timage Function Create() Local Ship:TShip = New TShip If List = Null List = CreateList() List.AddLast Ship 'Add Ship Last in List If Not Image Image = LoadImage("ship.png") MidHandleImage( Image )'Center EndIf EndFunction Method New()'Starting Values X = 300 Y = 400 EndMethod Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod End Type Now we are going to fix the update method and the updateAll function. In update we want to update the movement and controls and finally draw the ship. Just so that we can do a test-run let’s put in the method Draw() in method Update. In updateAll() we want to loop every ship we have, we only got one, but in case, if we ever add more of them then no extra code will be required. Make an eachin-loop with the global List and make each object run its Update() method. TShip.bmx Type TShip Extends TSpaceObject Global List:TList Global Image:Timage Function Create() Local Ship:TShip = New TShip If List = Null List = CreateList() List.AddLast Ship 'Add Ship Last in List If Not Image Image = LoadImage("ship.png") MidHandleImage( Image )'Center EndIf EndFunction Method New()'Starting Values X = 300 Y = 400 EndMethod Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod Method Update() Draw() 'To add later: 'GetInput, Controls 'Update physics, Movement EndMethod Function UpdateAll() For Ship:TShip = EachIn List Ship.Update() Next EndFunction End Type Everything clear? No questions? Are you wondering if there could have been ”another way” to do it? Don’t hesitate to ask in the forum! Feedback = Good. Questions = Better. Asking = Learning. Let’s see what we got so far. Jump to your main file. Setup a graphicsmode, I choose 800,600,0. Call the function Create() in TShip. Remember that to access a function that lies inside a type you need to access the function from the type; Type.Function() – or in our case - TShip.Create(). Create a basic loop and exit when someone presses Esc. Run the function UpdateAll() in the middle of it and before the end of the loop call Flip and Cls. AsteroidWars.bmx Include "TSpaceObject.bmx" Include "TShip.bmx" Include "TShot.bmx" Include "TRock.bmx" Graphics 800,600,0 TShip.Create() 'Main Loop Repeat' - - - - - - - - - - - - - - - - - TShip.UpdateAll() Flip Cls Until KeyDown(Key_Escape)'- - - - - - - - Build and Run! You can’t do anything except watch your pretty ship but it’s a start and we’ve built a solid base for years to come, or more exact ~42min. Now we need interactivity. Jump to TShip again. We are going to implement the actual physics, the control feeling of the ship. This part is an important and a bit advanced, I’ll try to explain it as simple as thorough as possible. Still you need to know some about vectors to get it, or I’ll have to explain vectors to, but I won’t, not this time. Nothing strange with vectors there it’s just out-of-scope for this guide. So here is the code for method Update, Step One: In file TShip.bmx Method Update() Draw() 'Possible Actions Local Up,Down,Left,Right,Fire 'Controls affect actions If KeyDown(Key_Up) Up = True If KeyDown(Key_Down) Down = True If KeyDown(Key_Left) Left = True If KeyDown(Key_Right) Right = True If KeyDown(Key_Space) Fire = True ' P H Y S I C S '--------------------------------------- 'Alter these to alter the ships movement Local Acceleration# = 0.04 Local Friction# = 0.014 Local TopSpeed# = 2.0 Local TurnAcceleration# = 0.18 Local TurnFriction# = 0.06 Local TurnMax# = 3 '--------------------------------------- What I do when I set Left,Right,Up,Down and Fire is to separate the actions from the keys. It’s not required in this game unless we want to add more players or AI. That wasn’t that hard, was it? I hope not because the actual physics/trouble is yet to come, Step Two: In file TShip.bmx in method Update() Before you try to understand this and before you go any further I would strongly suggest you try the above addition. Compile and run. Test. So what is this all about, with one word: Vectors. Vectors it the key to physics. Vectors work in 2D and 3D. Without telling you what a vector is I’m going to explain what I did, the problem is that… well you’ll find out. When we press Up or Down we want our thruster to give us a push forward. One could refer to this push over time as force. What is a force then? A force is something that accelerates things. You have probably seen the equation: Force = Mass x Acceleration. This means that our thruster will accelerate a heavier ship (bigger mass) much slower than a light one. Acceleration = Force / Mass. In this game I have set Mass = 1 and it was never provided in the equations. So in this game our thruster gives a force equal to the acceleration. Let’s look at the code: If Up XSpeed:+ Cos(Direction)*Acceleration YSpeed:+ Sin(Direction)*Acceleration EndIf XSpeed and YSpeed is the values of our speed vector. Acceleration in this case is the Ship-thruster’s “push” value. I take this value and assume it’s a vector in the direction of the ship and add it too the speed-vector. If I had been using a vector library/module the above could have looked something like this: If Up Local Thruster:Vector = NewVector() Thruster.SetLength( Acceleration ) Thruster.SetDir( Direction ) Speed.Add( Thruster ) EndIf To be able to reduce our speed we need to reduce the speed-vectors length and not the values directly. To get the length we use Pythagoras Theorem. Local SpeedVectorLength# = Sqr(XSpeed*XSpeed + YSpeed*YSpeed) Friction is applied to our SpeedVectors length like this: If SpeedVectorLength > 0 XSpeed:- (XSpeed/SpeedVectorLength)*Friction YSpeed:- (YSpeed/SpeedVectorLength)*Friction EndIf The calculation (XSpeed/SpeedVectorLength) creates a unit vector of the speed vector. This means I set the length of the speedvector to one but I keep the direction. When I then multiply this unitvector with Friction I create a vector with the same direction as our speedvector but with the length of our friction value. Then I substract this vector from the speed vector. With a vector library it would have looked something like this: Speed.Sub( Speed.Unit().Multiply(Friction) ) Or Speed.Decrease( Friction ) We also need to keep a speed limit. This speed limit would in a real-world be dependant on friction, in space we don’t have any friction. In my asteroids-world I dictate the physics and I use both friction and a speedlimit, both without breaking the laws of physics, I merly bend them. If SpeedVectorLength > TopSpeed XSpeed:+ (XSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) YSpeed:+ (YSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) EndIf If our speed surpasses a certain limit I will substract the speed with the amount that it was surpassed, (TopSpeed - SpeedVectorLength). It’s the same as friction only that the amount of friction I add is depending on the speed. Vector Lib equvivalent: If Speed.Length() > MaxSpeed Then Speed.SetLength( MaxSpeed ) The last part is to update your position based on your speed X:+ XSpeed Y:+ Yspeed In a vector lib that would have been: Position.Add( Speed ) The rotation part is easier and I assume it don’t need much futher explination. Please go ahead and change any/all of the six values and try for different physics behaviors. This model could be used for most topdown games to give a fair feel. If you have a race game I suggest having a higher turn acceleration to get more responsive controls, the turn friction would in a car game be equvivalent to the grip of the tires. Test and try for your self. TShip.bmx so far Type TShip Extends TSpaceObject Global List:TList Global Image:Timage Field TurnSpeed# Function Create() Local Ship:TShip = New TShip If List = Null List = CreateList() List.AddLast Ship 'Add Ship Last in List If Not Image Image = LoadImage("ship.png") MidHandleImage( Image )'Center EndIf EndFunction Method New()'Starting Values X = 300 Y = 400 EndMethod Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod Method Update() Draw() 'Possible Actions Local Up,Down,Left,Right,Fire 'Controls affect actions, Player 1 If KeyDown(Key_Up) Up = True If KeyDown(Key_Down) Down = True If KeyDown(Key_Left) Left = True If KeyDown(Key_Right) Right = True If KeyDown(Key_Space) Fire = True ' P H Y S I C S '--------------------------------------- 'Alter these to alter the ships movement Local Acceleration# = 0.04 Local Friction# = 0.014 Local TopSpeed# = 2.0 Local TurnAcceleration# = 0.18 Local TurnFriction# = 0.03 Local TurnMax# = 5 '--------------------------------------- 'M O V E M E N T P H Y S I C S '-------------------------------------- ' If Up 'Create a Acceleration Vector and 'add it to the Speed Vector XSpeed:+ Cos(Direction)*Acceleration YSpeed:+ Sin(Direction)*Acceleration EndIf If Down 'Create a Acceleration Vector and 'substract it from the Speed Vector XSpeed:- Cos(Direction)*Acceleration YSpeed:- Sin(Direction)*Acceleration EndIf 'Calculate the length of the Speed Vector Local SpeedVectorLength# = Sqr(XSpeed*XSpeed + YSpeed*YSpeed) If SpeedVectorLength > 0 'Decrease Speed with Friction if we are moving XSpeed:- (XSpeed/SpeedVectorLength)*Friction YSpeed:- (YSpeed/SpeedVectorLength)*Friction EndIf If SpeedVectorLength > TopSpeed 'If we are going beyond the speed barrier then reduce our speed 'with the amount in which it surpases TopSpeed XSpeed:+ (XSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) YSpeed:+ (YSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) EndIf 'Move X:+ XSpeed Y:+ YSpeed 'Rem 'Visualize the vectors SetRotation 0 SetColor 255,0,0 'Red DrawLine X,Y,X,Y + YSpeed*50 SetColor 0,255,0 'Green DrawLine X,Y,X+XSpeed*50,Y SetColor 0,0,255 'Blue 'This is the SpeedVector's Length 'Note that this vector is built by 'Adding the Red and the Green DrawLine X,Y,X+XSpeed*50,Y+YSpeed*50 SetColor 255,255,255 'EndRem 'R O T A T I O N P H Y S I C S '-------------------------------------- ' If Left TurnSpeed:-TurnAcceleration If Right TurnSpeed:+TurnAcceleration 'Limit TurnSpeed If TurnSpeed > TurnMax TurnSpeed = TurnMax If TurnSpeed < -TurnMax TurnSpeed = -TurnMax Direction:+TurnSpeed If Direction > 360 Direction:- 360 If Direction < 0 Direction:+ 360 'Apply Friction To Rotation If TurnSpeed > TurnFriction TurnSpeed:- TurnFriction If TurnSpeed < -TurnFriction TurnSpeed:+ TurnFriction 'If Friction is Greater than Speed then Stop If TurnSpeed < TurnFriction And TurnSpeed > -TurnFriction TurnSpeed = 0 EndMethod Function UpdateAll() Local Ship:TShip For Ship = EachIn List Ship.Update() Next EndFunction End Type Now I’m going to add shots. Open up Tshot.bmx and create a TShot type that extends TSpaceObject. We are going to need a list for the shots. Make the create method similar to the ship’s create method. We’ll load the image we made, shot.png. TShot.bmx Type TShot Extends TSpaceObject Global List:TList Global Image:TImage Function Create() Local Shot:TShot = New TShot If List = Null List = CreateList() List.AddLast Shot 'Add Ship Last in List If Not Image Shot.Image = LoadImage("shot.png") MidHandleImage( Shot.Image ) EndIf EndFunction Function UpdateAll() EndFunction Method Update() EndMethod Method Destroy() EndMethod Method Draw() EndMethod EndType Now we can create shots, but where will the shots appear? The shots should always be created at the front of the ship who fired it. This requires us to add some parameters to create(). Function Create( X, Y, Direction, XSpeed, YSpeed ) Local Shot:TShot = New TShot If List = Null List = CreateList() List.AddLast Shot 'Add Ship Last in List Shot.X = X Shot.Y = Y Shot.Direction = Direction Shot.XSpeed = XSpeed Shot.YSpeed = YSpeed If Not Image Shot.Image = LoadImage("shot.png") MidHandleImage( Shot.Image ) EndIf EndFunction Let’s fix Update() and UpdateAll(), I copied what I have in these methods in TShip.bmx and altered them to fit our shot. This is what came out of it: Type TShot Extends TSpaceObject Global List:TList Global Image:TImage Function Fire( X, Y, Direction, XSpeed, YSpeed ) Local Shot:TShot = New TShot If List = Null List = CreateList() List.AddLast Shot If Not Image'First Time Image = LoadImage("missile.png") MidHandleImage( Image ) EndIf Local ShotSpeed#= 8 Shot.X = X Shot.Y = Y Shot.Direction = Direction 'Add Shot Start Speed Shot.XSpeed= Cos(Direction)*ShotSpeed + XSpeed Shot.YSpeed= Sin(Direction)*ShotSpeed + YSpeed EndFunction Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod Method Update() Draw() X:+ XSpeed Y:+ YSpeed If X > 800 Or Y > 600 Or X < 0 Or Y < 0 Destroy() EndMethod Function UpdateAll() If Not List Return Local Shot:TShot For Shot = EachIn List Shot.Update() Next EndFunction Method Destroy() List.Remove( Self ) EndMethod EndType The code above should say most just by itself, except: Shot.XSpeed= Cos(Direction)*ShotSpeed + XSpeed Shot.YSpeed= Sin(Direction)*ShotSpeed + YSpeed Here is the vector code again =) It’s the same as when we thrust forward. The shots in this game are not affected by friction and they can’t rotate so the update code is therefore much more simple than that in TShip.bmx. To fire a shot we need to add one line to our Ship’s Update method: If Fire TShot.Fire( X, Y, Direction, XSpeed, YSpeed ) Ok cool we can move around and fire. Now we need some targets – rocks. But before that I’ll add a border so that if you go out on one side you appear on the other. Add to TShip.bmx in the update method: If X > 800 X = 0 If Y > 600 Y = 0 If X < 0 X = 800 If Y < 0 Y = 600 Jump to TRock.bmx. This type is very similar to Tshot. We have to take into account that the rocks come in different sizes, I added one field Size and one called Rotation. Type TRock Extends TSpaceObject Global List:TList Global Image:TImage Field Size Field Rotation# I will also add three constants. Whenever I want to refere to a size I could write Size = 1 or 2. With constants It would be: Size = SMALL or MEDIUM. To have constants in all caps is just very common in programming and it’s not required by BMax. Const LARGE = 3 Const MEDIUM = 2 Const SMALL = 1 Instead of Create I call this function Spawn, it does almost the same thing as create in Shot and Ship. Function Spawn( X, Y ,Size ) Local Rock:TRock = New TRock If Not List List = CreateList() List.AddLast Rock If Not Image'First Time Image = LoadImage("rock.png") MidHandleImage( Image ) EndIf Local RockSpeed# = 0 Select Size Case LARGE'Large RockSpeed = 0.2 Case MEDIUM'Medium RockSpeed = 0.5 Case SMALL'Small RockSpeed = 1 EndSelect Rock.X = X Rock.Y = Y Rock.Direction = Rand(360) Rock.Rotation = Rock.Direction Rock.Size = Size 'Add Rock Start Speed Rock.XSpeed= Cos(Rock.Direction)*RockSpeed Rock.YSpeed= Sin(Rock.Direction)*RockSpeed EndFunction The above code should speak for itself, the rocks start with a constant speed that it keep aslong as it stays alive. Method Draw() Select Self.Size Case LARGE SetScale 2,2 Case MEDIUM'Medium SetScale 1,1 Case SMALL'Small SetScale 0.5, 0.5 EndSelect SetRotation( Rotation ) Rotation:+0.5 DrawImage( Image,X,Y ) SetScale 1,1 EndMethod Note the collision() method below, I will come to that in a moment. Method Update() Draw() X:+ XSpeed Y:+ YSpeed Collision() If X > 800 X = 0 If Y > 600 Y = 0 If X < 0 X = 800 If Y < 0 Y = 600 EndMethod Function UpdateAll() If Not List Return For Local Rock:TRock = EachIn List Rock.Update() Next EndFunction Method Destroy() List.Remove( Self ) EndMethod Until now the rock would just tumble around in space. We want it to interact with the shp and your shots, so that they pose a threat and can be destroyed. Method Collision() Local Radius Select Size Case LARGE Radius = 100 Case MEDIUM'Medium Radius = 50 Case SMALL Radius = 20 EndSelect 'If a rock hit a ship If TShip.List For Local Ship:TShip = EachIn TShip.List If Distance( X, Y, Ship.X, Ship.Y ) < Radius Ship.Destroy()'Ship = Dead EndIf Next EndIf Collision Rock versus Ship. I use the simple fact that if the ship ever gets closer to the rocks center than the rocks radius then it will collide with the rock. The rock is round so this should work very good. The same goes for the shots, if they are close enought to the rock the rock is hit. 'If a shot hit a rock If Not TShot.List Return For Local Shot:TShot = EachIn TShot.List If Distance( X, Y, Shot.X, Shot.Y ) < Radius Shot.Destroy() Select Size Case LARGE Destroy()'Destory the rock Spawn( X, Y , MEDIUM ) Spawn( X, Y , MEDIUM ) Case MEDIUM Destroy() Spawn( X, Y , SMALL ) Spawn( X, Y , SMALL ) Case SMALL Destroy()' EndSelect EndIf Next EndMethod If the rocks is Large we destroy the large and spawn two medium. This part of the code is very easy to follow. This is the great about max, some part of the programs almost becomes trival. And of course you need a way to calculate the Distance from the Rock to whatever. I made a quick function for that: Function Distance#( X1, Y1, X2, Y2 ) Local DX# = X2 - X1 Local DY# = Y2 - Y1 Return Sqr(Dx*Dx + Dy*Dy) EndFunction Dx is the Distance from X1 to X2. Dy is the distance from Y1 to Y2. I want to know the diagonal length of these and therefore use pythogeras again. You’ll need to know some basic math to get this. Now that’s about it. Now it’s a good time to tweak the game. Alter the ships physics and the rock speed and size. Try to make everything fit together as smooth as possible. Time to make a game out of this engine. Here is what we need for that: 1. Introduction Screen with controls – Press Space to Start Game , Q Quit– 2. If you kill all rocks spawn a new level 3. Keep track of your score. Only small rocks give score, 1point each. 4. If the player dies, tell them their score. Restart game with R, Quit Q. To implement this we need to go to our main file, AsteroidWars.bmx First I create a global called Mode, and then three constants, one for each mode. Intro, Death and Playing. Also a global for Score and one for highest Score. Const Intro = 1 Const Death = 2 Const Playing = 3 Global Mode = Intro Global Score, HighestScore Now I added the main stuff, nothing really special but it required a lot of tweaking. Therefore I can’t write it step by step. Instead I’ll finnish off by giving you the complete source. I recommend that you make your own version. Use this as a base. Tweak it, add features. My gamepley for this game sucks. It’s an example and nothing more. I hope it prove a good base for anyone wanting to try out game programming. Have fun with it! AsteroidWars.bmx Feel free to post your suggestions, improvements, questions and comments. Next I'm going to make a vector physics tutorial. But it's a long long time until next time. |
| ||
Thanks wave and racer! |
| ||
very very nice guys !! Cant wait to see what you do next ! |
| ||
Haven't had a chance to go through it yet. Thanks guys for helping us less experienced understand this. |
| ||
Thanks a million for the tutorial. Very well done. I'v used it as a reason to learn about BMax bitmap collisions. Slows things down a bit on my machine though. I'm thinking of just using bounding rectangles for a nearness check and then use ImagesCollide for a final check. Seems that would be quicker as it only needs to do the bitmap check on images that MAY be colliding. Does that make sense? |
| ||
Not had a chance to look at it yet, but thanks a lot. Exactly the kind of thing I've been looking for. |
| ||
Thanks for the respone, any suggestions for improvements are also welcome. If you need pixel perfect collision then using bounding box or a range check before bitmap collisions should save a lot of CPU, so that would certainly make sense even for a low number of objects. Last time I tested the bitmap collide it was way slow to be used all the time. But if you manage to find a good use for it then please share. |
| ||
Just to help with any confusion for absolute beginners, at the start of the tutorial when you import the files into AsteroidWars.bmx, there is an error in the example...Include "SpaceObject.bmx" Include "Ship.bmx" Include "Shot.bmx" Include "Rock.bmx" should read... Include "TSpaceObject.bmx" Include "TShip.bmx" Include "TShot.bmx" Include "TRock.bmx" Sorry to be picky, but this is for beginners, yes? |
| ||
I would like to thank Wave and Skidracer as this solved one of my problems with Acceleration in the game I am working on! Let me know how you want to be shown in the credits. Right now it will be as "Wave" and "Skidracer". Thanks! |
| ||
@Phil, Thanks I'll correct that. This should be for beginners, please suggest if you come up with more improvements or tips. Second, Skidracer simply made codeboxes, he is not a part of the credits. He did not help me or Co-wrote this in any way. I feel there is a misconception about that. Please Skidracer, change your post and if you have admin rights paste it into my first post (so I can edit). I'll give you credit for the translation to forum code ofcourse. |
| ||
Wave, no problem, just saw Skidracer on most of the stuff :-) |
| ||
This looks like a pretty good tutorial so far, I'll have a proper look later. Should be excellent for getting me started into BlitzMAX, eh? |
| ||
Okay, I can't get the source code provided in the zip file to comile. It says Compiller Error: Identifier "AppTitle" not found. I guess it's refering to the second line of AsteriodWarz.bmx, I dunno. AsteriodWarz.bmx is still the main, root, primary file we're supposed to Compile and Run in order to build the EXE that coumes with the zip file, right? Yes, I'm new. Very very new. That's why I need bug-free code to learn from. The code provided produces a mysterious error that I don't know enough to know how to fix. I guess lots of people with a little BMX experience have gotten this example to run, because nobody else complains of an error. Can anybody tell me how to make it work? Thanks. |
| ||
this works perfectly for me.. |
| ||
Great tutorial. I started off my BlitzMax education with this tutoral. I then built off of it to include the following: 1. Different asteroid types. 2. Basic ImageCollision function 3. Option/Preference screen for key mapping 4. Shields 5. UFO (animated sprite) 6. Fonts (using true type fonts) 7. Basic Sounds The result is available here. http://www.foolishgames.zoomshare.com/files/AsteroidDefenderSource.zip |
| ||
I'm really impressed. It looks very professional. Great work. |
| ||
Thanks much. I appreciate you taking the time to check it out. |
| ||
This tutorial should be stickied? |
| ||
Thanks, Wave, very useful tutorial. Here's version russified by Maniak_dobrii: http://blitzetc.boolean.name/articles/asteroids.htm |