Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

2D All the way! / space invader clone

Author
Message
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 31st May 2005 05:31
This is my first attempt at a game with DarkBasic Classic. I have managed to muddle through getting the rows of invaders on the screen and my ship. I can not seem to figure out how to get the rows of invaders to move side to side.
Any other suggestions would be greatly appreciated as well.



thanks
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 2nd Jun 2005 11:53
Hi David_M.

I sort of skimmed over your code. You might want to use sprites with images instead of bitmaps. That way you can easily do checks for collision, and animate your invaders and ship.

Below is a demo that I threw together to show you how you might tackle this issue. It doesn't have any shooting or animation, but it does give you an idea of how to move your ship and the invaders.

If you need any more help, just let me know...

David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 3rd Jun 2005 08:55
Thanks for the post. Hopefully I will get to examine it soon.

thanks agian
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 3rd Jun 2005 13:17
Thanks again for the help.
I have switched from bitmaps to sprites. The problem I am still having is that I can't seem to convert your cool little demo to constantly moving side to side and never stopping, instread on a set number of times like in your demo. I also dont understand why you use functions in some places and gosubs in others.

Thanks again,
David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 4th Jun 2005 11:00
Okay... What do you mean by constantly moving? What I did in the demo was every time the invaders try to exceed the edges of the screen, they reverse direction and drop down 4 pixels. You could change the yoffset variable in the invader subroutine to say 1 or 2 pixels. This would increase the time the invaders would take to reach the ship. You could also use the TIMER() function to slow them down.

Functions are great for a lot of things, but you can't expect to write everything exclusively with them. There are several reasons for this. Any variables inside of the FUNCTION/ENDFUNCTION in DBC are considered to be local with the exception of arrays. This way you can reuse variable names without effecting your main program variables. Once you create a function, you can treat them just like any other command in the language. Even with the code inside of a function being written with the language in question, everything inside the function declaration can be considered internal. Every time the function is executed within a loop, the variables are initialized within the function before any calculations are done. Try changing my code so all of the subroutines are functions. You will see what I mean.

Yes, you can pass values from variables to a function and also return them from a function. In small programs they can work quite nicely or at least with limited variable usage passed to them, but with larger more sophisticated programs with many variables, things can get quit hairy. Try to keeping track of twenty or more passed to each function for example. Especially in instances where you are using the same variable names for the main code as in one or more of the functions. DBPro allows you to define variables as local or global. This tends to make things a little easier when dealing with functions with that version.

I guess what I am trying to say is, use functions for tasks which do not involve keeping track of global variables like in the case of my demo. You can use them to set things up for main program code like clearing the screen and placing graphics in certain locations or calculating a value and then returning the result. Get the drift? The more you get accustom to using functions, the more you will know you can get away with.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 4th Jun 2005 13:55
Thanks for the extra clarification. I think I understand it better now. I will be going out of town this weekend, so it may be a few days before I get to play with it very much.

Thanks again,
David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 8th Jun 2005 10:45
Just a little after thought about functions:

I am not trying to steer you away from using functions. It is possible to write the Invader Demo code above and make more use of functions. Here again, you will have to use some kind of variable update system in the main code or some kind of constant source of data.

When I develope code for a task, I usually keep most things as subroutines, except for some obvious function usage, then I optimize and revise. During the later part of program developement, is when things can be finalized. It depends on what works better, faster, and also what is good for future expandabilty and/or upgrading. This is my way of programming. I think its a resonable method of approach. Each to their own on methodology I guess.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 9th Jun 2005 12:39
Thanks for the further info, it is much appreciated.
I have another question. What in the world does the error "Bob does not exist" mean????? I know it probably depends on what my code says, but I have no idea at all what it is refering to, syntax, improper code format, or what???

Thanks again
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 9th Jun 2005 16:30
Hello again,
Here is my latest changes. Thanks again D Ogre so much for the demo code. I have some more questions.
1. When the invaders move side to side look like they are vibrating as they move side to side?
2. Why does my ship move sooooo jumpy?

Thanks again
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 10th Jun 2005 09:44 Edited at: 10th Jun 2005 10:02
Try changing your ship movement subroutine to the following. It should get rid of that annoying jitter. The reason is that you were trying to reset the ship to orginal location instead of just placing an actual limit (300) on Y axis.



I noticed that you are using two different sprites for your invaders. You don't have to make two different row update routines. You can still use one.



observe the Y+1 in the sprite command. It will give you your first image on the first pass (0+1=1) of the y loop, and the second image on the sceond pass (1+1=2) of the y loop.

As far as the vibration goes, you can minimize this by decreasing the movement variable and increasing the frame rate. Unfortunately, you won't be able to get rid of this totally. What you are seeing is latency in redrawing all the invaders to the screen in the FOR/NEXT loop.

The routine above gives you and option of using pixel perfect collision and flexiblity to change. If the vibration seems to be annoying for you, you could draw all your invaders to a bitmap in the wave pattern you want, and then grab that as one big image and just move that instead. You would have to then use a custom box collision routine to check if a portion of the big image was hit. This would simulate hitting individual invaders. If you like this idea I could help you with it.

Oh, about the error message, it seems to be informing you that some sort of entity isn't presently existing. If memory serves, I think its referring to a sprite. I know sprites are also known as MOBs (Movable Object Blocks) though. I would assume that you might have accidently made referenced to a sprite that wasn't defined in your code.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 12th Jun 2005 13:29
Thanks again D Ogre, my code has made leaps and bounds.
My problem now is getting the fireing to work. I can fire, the laser moves, I can not fire until the laser disapears off the screen (desired), I can even fire again, but the problem is that after the second time to fire, the laser does not move from its origninal creation location.
BTW After putting in the stars, you dont notice the vibration of the invaders very much. The ship movement is still jerky though. Any ideas? I dont mind giving you credit for helping me in my code or credits of the game, if you want.

Thanks

D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 14th Jun 2005 09:08
I haven't tested your code yet. I forgot that you are using DBC. How fast is your computer? If you are using the mouse to control your ship, it might seem jerky if your computer is slow. DBC is a interpreted language. It doesn't compile to machine code like DBPRO does. On slower machines, you will notice sluggishness with the mouse under DBC.

I will check out your shooting routine and see what can be done with it. As far as mentioning me in your game, it doesn't matter, I'll leave it up to you.
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 14th Jun 2005 10:30
I managed to do a little tinkering with your shooting code. Try this snippet below.

David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 14th Jun 2005 12:03
Thanks D Ogre, that worked. The PC I was using is a PIII 700 MHz. I tried it on my P4 1.8 GHz and it runs great, actualy almost too fast.
If you dont mind, I would really like to learn from the code and not just cut and paste.
Two questions:
1. why didn't my code work?
2. doesn't just hideing the sprite still use system resources because the sprite still exist, just not displayed. Why not delete it?

Thanks again,
David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 15th Jun 2005 10:49 Edited at: 15th Jun 2005 11:47
Your right, it does use a small amount of the system resources, but not enough to make a real difference with one sprite. You can keep the sprite active so you can make collision checks in the game loop. This also depends on how you employ the collision check of course.

I didn't mean to take over your project. Sometimes I get carried away with helping and over-step the boundries. It is better to strike out on your own. You will learn a lot that way. If you need any more help, just let me know.

Your code actually did work. The problem is using the mouse to control your sprite. Even though you are placing limits on the sprite movement for your ship, it only does this once in any given pass of the game loop. The mouse pointer is always polling data from your mouse. If you quickly move the mouse, it has a chance of exceeding your x and y limits in the ship subroutine (remember: your just shadowing the mouse pointer). Because the code is executed linearly, this could happen between the ship movement subroutine and the firing subroutine. Once it reaches your firing code, the mouse pointer has fallen below your y limit in the firing routine. So, only the first half of the firing code is the implemented thus creating the sprite and nothing else. The screen is then updated, and everything starts over again in the loop. You won't actually see this happen because the graphics are being double buffered.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 15th Jun 2005 12:22
No problem at all. I dont feel that you were "taking over my project", and I very much appreciate your help.
And since you offered again, I have yet another problem. Hmmmm, isn't that novel.
I have added a check_collision subroutine. It kinda works. It will check for collision and hides the sprite the laser hits. Cool!!
The problem is that since the sprite is just hidden it continues to hide invaders as it travels. Whipping out numerous invaders at a time. And also, since the invaders are only hidden, if the laser hits a hidden sprite, the laser gets hidden as well and appears to quit traveling. I cant delete the sprite, because the routine that checks for each sprite gets and error is one of the sprites no longer exist. I think I will need to start using arrays, but Im not sure exactly sure what to do with them. I hope this makes sence. Here is my code.
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 15th Jun 2005 12:52
Okay... Both of our codes posted here where not setup originally with collision in mind. I wrote my examples to only address the problem at hand. I didn't want to jump to far ahead on you.

I see you are catching on. Yes, you will have to use an array of some sort to make the collision work, and some changes will have to be made to the original code to implement it. I will try to do this without making too many drastic changes.

Its getting kind of late for me here, so I can't explain everything in very much detail. I guess I will post the new snippet now, and you can ask me the how, what, where, and the why of it. That way I am not wasting to much time in one area or another on the topic.

Here's the new code:



Of course, this is not a final solution, but it works for now...
Robot
20
Years of Service
User Offline
Joined: 27th May 2004
Location:
Posted: 15th Jun 2005 16:23 Edited at: 15th Jun 2005 16:23
you could delete it and then put something like

if sprite exist(invader)=1
check collision and anything else you want to do
endif

The happenings of tommorow are behind us now
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 16th Jun 2005 08:45
Thanks for the input Robot.
D Ogre, I may not get to it for a few days, but glancing over the code really excites my.

Thanks,
David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 16th Jun 2005 11:57
Dave,

I'm sure after you've tested out the code. You will find and obvious fault. If you hold the button down when shooting (especially when the ship is closest to the invaders), the laser seems to pass thru some of the invaders when a hit invader explodes. The reason for this is that the collision/explosion sunroutine can only handle one invader at a time. To keep things simple, I only used one array for the collision. The code could be re-written to handle any amount of invaders that were hit. You could also lockout the firing routine until the invader finishes exploding by adding a check in the firing subroutine (i.e. IF EXPLODE = 0 THEN "fire"). I didn't know what you wanted so I kind of left it up to you. Remember, this is your project...
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 17th Jun 2005 12:24
I couldn't help it. I just had to play around with this project. I fixed the ship movement and firing code. I also added some sound to the project and a level complete message. You will have to substitute the wave files for the sounds with your own.

HERE IS THE LASTEST CODE:

David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 17th Jun 2005 14:23
WOW!!!
I am still trying to understand the previous set of code.
There are two main things that I am having trouble with:
1. ship(i)=1, ship(i)=2, etc, stuff. sprite 1 thru 6 = 1, sprite 7 thru 13 = 2, huh.... what does that do???
2. the timer()+30 stuff
Timer for what??

I think I understand the destroy subroutine. The sprite number that got hit goes through several variables like hit, reckage and frame. This in effect makes the sprite number's image number increment from 4 to 8 to replace the invaders image with the explosion images.
Correct????

That is really cool how you made it a multi level game.
This weekend I will try to catch up with where you are at.

Thanks again
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 18th Jun 2005 07:56 Edited at: 18th Jun 2005 09:26
Alright Dave, I'll give you the scoop on the code and what it does.
I will try to keep things linear in my explaination. I will walk you thru the entire thing.

ORDER OF PROGRAM OPERATION:

1. Initialize program. You know the standard issue sync on, hide, mouse, and all the other obvious setups stuff for the program.

2. Load media. Load your images, bitmaps, and sounds. Easy to understand right?

3. Dimension invader ship array. This is to keep track of your images, and explosions for the space invaders. The program is using basically a tile matrix for the invader subroutine. We could use a two dimensional array here, but a single will do because of the way the subroutine was written. I try to work things out so little code as possible is needed. Anyways, the data that is stored in that array is the actual image number for each ship (1 = image 1, 2 = image 2, 3 = image 3, 4 = first frame of explosion, ect., ect.).

4. Define or initialize important game variables.

5. Setup sprites. This part of the code could actually be placed right after the load media code. This is to assign the initial images for each sprite in the game as well as transparency, backsave state and all the other things needed.

The SHIP array is defined here just for convience and the values for each invader image is stored in it appropriately. I would change the Setup sprites loops to one FOR/NEXT loop setting them all up at once, and I would probably write an image array definition loop (possibly using RESTORE/READ/DATA) separately and keep it within the "BIG GAME LOOP". This way you could call it before the action loop to reset or change the invader images for the sprites.

I've used this method for a good reason. Say you wanted to change your invader images on the next level, and each row can have many different invaders! You can simply re-define them in the SHIP array. This also allows you to change the wave formation with out hard coding it. Remember, in the code I mentioned that you have to use a blank image for the last frame for the explpsion. This can be used to skip spaces in the wave formation. Part of the collision checks for this, but more on that later.

6. Start the game action loop. Self explanatory.

7. Sub. background. Same as above.

8. sub. invader matrix. The only change here is that I implemented the SHIP array in the SPRITE command instead of Y+1. The invader variable indexes the array and recalls the image number for each ship (or blank spaces) in the matrix.

9. The ship controls. I simply combined the firing and movement. There was no since in keeping them separate. They both concern the ship so you can keep them together. It also remedied a problem with the firing. Remember what I said about the mouse pointer. It is always recieving input from the mouse, and not just once during each pass of the loop, but all the time. Placing a limit on mx and my in the ship movement subroutine didn't limit the lsry and lsrx variables in the laser subroutine. This is why you had problems with the firing controls, when you were checking the SPRITE Y(101) in the IF statement orginally.

10. Check Collision. The variable HIT gets a value between 0 (nothing was hit) and 18 (total amount of invaders). This is then checked by and IF/ENDIF statement (IF HIT > 0). Inside that statemnet I had to set things up for the explosion animation.

Heres the breakdown:

A. I had to shut down the laser firing with lsry = 0. This fooled the firing subroutine into thinking that the bullet made it off the screen when in reality it hit an invader. This also made sure that the laser got hid (in this case off screen), and the FIRE variable was reset. We don't need it on the screen anymore do we? Yes, I suppose we could change it back to SHOW/HIDE sprite. I doesn't matter, it worked didn't it? This got ride of at least one command out of the loop. (Think optimizingly.)

B. RECKAGE is now defined with the value stored in hit. We have to use some sort of temp variable to recall which invader was hit. If we didn't do this. HIT will become zero on the next pass of the loop, thus losing are sprite number.

C. FRAME is set to 4. This is the start of our explosion animation.

D. EXPLODE = 1. Okay now we are armed with what we need to do the animation. Go ahead an do the nasty...

E. Play sound. KA-BOOMMMM!!! You need to place it here. Don't try and put it in the actual explosion loop. It will just sound like a buzzing noise of some sort. That's because each time a sound command is executed it resets itself to the beginning of the sound data. You get the idea.

F. Delay. I am getting the current time before the explosion occurs plus 60 (this has been adjusted from 30) from the system clock. This is in milliseconds. I like to use the TIMER() function rather than simply adding two numbers. I think it makes things a little easier to visualize as far as measuring a time delay, and I think its more acurate too.

G. IF EXPLODE = 1 THEN SHIP(RECKAGE) = FRAME number 4. Remember that reckage is the temp variable with the current invader sprite number in it.

H. Check current time and see if it is greater than the start time. If not, return from subroutine, else add a one to the frame number. Check to see if FRAME exceeded the last frame of the animation (8; blank). If it does exceed that last frame, then the explosion is finished.

I. Start the loop over. Ship(RECKAGE)=4; new image for the invader. Now, the invader subroutine will make use of that new image for which ever invader sprite was hit. During this phase in the loop, the firing controls are temporarily disabled until the explosion is finished. This eliminates the possibilty of another ship getting hit and messing up our orginal hit and explosion. The laser collision routine is designed to only handle one hit at a time for now.


The collision function checks for two things. One, to see if the laser hit an invader. Two, to see if the image number is actually a ship image and not an explosion or a blank space. If you plan to use more images, you will have to change the 4 after the SPRITE IMAGE(enemies) to your last invader sprite image plus 1. I would also keep the explosion images after the invaders.

I hope this helps you out, Dave...

One more thing... The TIMER() is used to produce a delay between the frames (images) used for the explosion. The sync command gives you a certain FPS for everything, but to make adjustments to a specific thing , we use a timimg loop. In this case we are using about 60 ms per frame.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 19th Jun 2005 18:04
Thanks again D Ogre. You are one cool DarkBasic dude.
I understood most of your explanation. This part I did not get though.
"I would change the Setup sprites loops to one FOR/NEXT loop setting them all up at once, and I would probably write an image array definition loop (possibly using RESTORE/READ/DATA) separately and keep it within the "BIG GAME LOOP". This way you could call it before the action loop to reset or change the invader images for the sprites."
I did however figure out how to "change the Setup sprites loops to one FOR/NEXT loop setting them all up at once".
I have also added score keeping and title. I also added lives and a game over sub, but can not test it since I dont have any way for my ship to get destroyed yet.
I also noticed that sometimes the laser will pass right through the first row ship, totally ignoring it, and blowup the second row ship behind it. It only seems to do it on the first row.
This is getting really cool!!!!!!
Here is my modified code:


Thanks once again
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 20th Jun 2005 08:49 Edited at: 20th Jun 2005 09:20
What I was trying to say about defining the image array is that you can create some sort of data table for your invader waves, or levels. I just made a suggestion off the kuff about possibly using a data table with DATA statements and storing them in the SHIP(x) array using the READ command. RESTORE is to reset the pointer back to the first data element in the DATA statements. This could be done before the game play loop, made up as a sunroutine, or even a function (Remember arrays are global and can be accessed easily within a function with out passing them). If your confident enough, you could store the levels as data files too. It is really up to you how you want to set the data up.

Generic Example Code:



If you called the FOR/NEXT loop each time for a new level before the game play loop, the internal data pointer would be pointing to the next current available element in the DATA statements. The first time would read the first 18 ship images for level #1 (starting at 1), and then the next time it would read level #2 (starting at 19) and so on. The only thing that you will need to keep track of is when you reach the last data set. You must RESTORE the pointer back to that first set of data (18), or you will get an OUT OF DATA ERROR in line xxx in the compiler. You could use IF level*18 = 216 THEN RESTORE to check for when to restore. This depends on how you want it. 216 would be indicating level 12 for example (12 x 18 = 216). This would be done only if you want to have more levels beyond 12 using the same wave formations as the first 12. You may have to store the level variable in a temp variable so you could reset every 12 levels and not lose the actual level number to do the check. Does this make sence to you?

I haven't tried your revision of the code yet. Without further investigation, I would suspect that there might be an image reference number error in the collision function. Is the image number 110 the last invader or is it the start of the explosion? If it's not the start of the explosion, and the bottom row happens to be the image for the invaders (possibly 110), then make sure it's the first frame of your explosion. So you would want to make it 111. Like I said, I haven't studied your changes to know if this is the case.

Just a quick hint about making the invaders bomb your ship. You could use a random number to pick an invader that would bomb the ship. You could make a check to see which invader was picked, grab the current location on x and y for the invader, do the offsets and create a firing routine for it. You would also have to make a collision check too. Arrays could work nicely here. This way you can have more than one invader picked to fire at the same time for multiple attacks. More on this later...

One last thing, when you finish your game. Try to find ways of optimizing things and possibly making the code into functions. If you do it the way we are writting it now (as mostly subroutines), you can figure out better what things can be converted, and what can't because the data structure is now visualized and in place. It's just a matter of doing the mods at this point.
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 20th Jun 2005 11:59 Edited at: 21st Jun 2005 09:22
This is my second post since you posted last, Dave. So, make sure you read the one that is above this one too. I went over your code changes, but because you are using your own media, I couldn't actually run it. I would need to use my own media for that, and I didn't feel like fooling with it at the moment. I just kind of proof read it.

Looking at the code, my suspicions look to be correct about the check image problem. I didn't see any real problems with the collision other than that. I made some of my own mods to show you what might be done. I tried to comment on certain things that were important right in the code. Hopefully, you can understand it.

After Tuesday, I won't be able to help you. I will be out of town until next Sunday. So, you got me until after Tuesday night. I would like to see how this game comes out for ya!

Just keep at it, you'll get it!

D Ogre

<edited post>

Below is your orginal code with my comments and a few changes in place.
Don't know if it runs because I don't have the media.



This next snippet is an update. It is a VERY, very, very rough draft of a somewhat complete project. You can run this one right now. There is no media required. It makes its own graphics. I did this because I don't know if I will have any more time to help you work it out methodically in stages this week. Play around with it and try to figure it out on your own for now. I will pick up where we left off next week.



See ya later...
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 22nd Jun 2005 09:03
Thanks, I will check it out.
My spare time is very spuratic.

See ya later.
David
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 22nd Jun 2005 09:05
BTW: I did manage to get my invaders to speed up every level. A small thing, but I did it by myself.

David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 25th Jun 2005 17:39
Hello D Ogre,
Not to be critical, but the code does not work. It says "you can only increment a variable". I was able, after much head banging on brick wall, to fix the error. I put the line invlsry=bomby(invader) and that fixed the error. But it still does not work. The invaders fire, but the laser never moves after being fired. As you can see from the post it is pretty late. At this point I have banged my head so much to get the lasers to move I think I have brain damage.
Here is my code and media:
I hope this makes sence, I feel kinda loopy right now.

Attachments

Login to view attachments
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 27th Jun 2005 05:54
I go the invader bombing to work. Instread of using the invlsry=bomby(invader) and incrementing invlsry I just did a line bomby(invader)=bomby(invader)+10.
Now I need to get the ship explosion working. It takes about 10 seconds for the ship to explode after it is hit.

This is really cool.

Thanks,
David
Here is my latest code, for reference:
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 27th Jun 2005 09:53
Oops! The problem is that my internet computer only has DBPRO loaded on it. All of my code snippets are done in DBPRO (although should work fine in DBC). The INC problem is not associated with DBPRO. Classic doesn't like the use of INC for arrays. Sorry, my fault here. I was also in a hurry before I left for vacation this last week. I will try an test the code under DBC an see what its doing.

I did see one error in your code. You need to change the variable KILLER to KILLED under the ships collision. I am not sure if this is why the 10 second delay before the ship explosion. This variable disables the entire ship and laser control while the ship explodes.

I have a question for you. How much of the code do you understand at this point?
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 27th Jun 2005 15:01
Glad to see you back, D Ogre.
I hope you had a nice vacation.
I did manage to fix the delay after the ship explodes,the line status=4(this was for your sprite numbers, my sprites are numbered differently, I forgot to change it to 110)
I am glad you asked how much I understand. I do understand the vast majority of it, I think. I could not really help someone else, but I can follow the code (most of it). Could you give me a few days, or so, to mull it over before making anymore changes? I want to try to change a few other things on my own to make sure I understand what I think I know.

Thanks again for your help and patience. I can be a little slow sometimes.

David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 29th Jun 2005 08:30
Just like anything, it takes time to learn. Slow or fast, the end result will be the same if you work at it.

I will let you comb over the code for a while. I wish I would have had more time to document it for you. I also know it is a little messy, but hopefully now it works.

Again, if you have any questions, concerns, or comments, just post'em.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 29th Jun 2005 11:18
I'm back. I guess I did not understand as well as I thought.
I have managed to allow you to restart the game by pressing enter after game over, although the bombs that were in midair will continue to fall when game restarts.
I would like for all bombs on the screen to disappear when the ship gets hit, so the ship does not get hit by a bomb immedialty behind the one that just hit you. I have tried two different pieces of code inserted at various places, but I can not get it to work.
Thanks again

Here is the two pieces of code:

Here is my corrent working code:
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 1st Jul 2005 09:47 Edited at: 1st Jul 2005 10:03
I believe you have two problems by reading your last post, Dave. The first problem is resetting the invader bombs, and the second problem is restarting the game after a "GAME OVER".

To tackle the first question, I need to explain some of the coding first. Once you fully understand the code you will probably realize the answer(s) yourself. Don't worry, I wont leave you hanging...

Below is the code we need to break down and learn:



This is obviously the tile matrix for the space invaders. We would call this a nested loop meaning one loop sits inside of another (in this case it would be two FOR/NEXT loops). Some parts of this loop you should already know. We will be dealing with just the new parts here for the explaination.

You will notice the addition of several new IF/ENDIF statements within the nested loop. These statements are responsible for the bombing attacks by the space invaders. I am making use of 3 new array variables to help with this task.

Here is the breakdown:

1A. The first IF/ENDIF statement uses a random number to trigger invader bombing. The computer returns a random number and we check it against a known value. Both the RND() value and the constant can be changed to control the firing frequency of the space invaders. You could use some variables that are modified before each level for part of the difficulty.

1B. The next check here (bomber(invader)=0) is to see if the invader currently picked for bombing hasn't already been picked. The first initial pass of this code all the invaders are eligable to do the bombing because the array for bomber(x) is intialized to zero at this point. After this, the code in this loop keeps track of the values for the bomber(s).

1C. The third part of the check makes sure that your ship hasn't blown up the invader picked hence checking for an appropriate ship image excluding everything else like explosions or blank spaces. Pretty much the same as the collision function at the end of the program.

1D. If all of the conditions are correct (75=75, 0=0, image<1 to max. invader images+1) then grab the current X Y of the invader and set the offsets for the bomb origin and stick it in bombx(invader) and bomby(invader). The value of 1 is stashed in bomber(invader). Invader is the element for the arrays bomber, bombx, and bomby.

2. Now that the bomber has been picked, we can go ahead and draw the bomb at its origin and then add a value to the bomb's Y location for the next pass of this subroutine (after we SYNCed the screen).

3A. Now that the bomb is being drawn to the screen, we can perform a collision check to see if it hit the ship. We are also checking to see if the ship hasn't already blown up by another bomb. That is why we are checking the ships image to make sure its not an explosion or blank space.

3B. If The bomb actually did hit the ship, we can now hide the bomb. (Since the bomb reached its target.) The bomber(invader) is eligable for bombing again. Just like the ship, each invader can only fire once until either the bomb hits the your ship or makes it off the screen.

3C. Now that we know the ship is hit, we can disable the ships controls that is what KILLED=1 is for. Disabling the controls only makes perfect sense. How can you control a ship that is in a million pieces, right?

3D. Now we get the current time for the ships explosion.

4. If the collision doesn't return a value for a hit, then we check to see if the bomb had made it off screen. This is the ELSE part of this code statement.

When this subroutine is called in the game action loop, the nested loop makes checks and updates for the bombs accordingly. The reason why you would use indexed arrays is to eliminate making 18 different IF/ELSE/EDIFs for the ships. You can use the same array variable, but with a different element each pass. This is the power of arrays!

Another thing, you will notice I am using sprites 19-36 for the bombs, that is why you see invader+18 in the code. The answer to your first question is here. You will have to zero the bomber array and place the bombs off screen. This can be done in the "GET READY!" part of the code and before the next level. FOR/NEXT loops could work here. I would put the bombs below the bottom of the screen, because this is where they end up anyways. I am not going to do it for you. Think about it for a little bit, and then try to make the changes yourself. Don't worry I'll help you if you get stuck.

I hope that made some kind of sense to you...

Your second question is better shown than explained.



Programming takes critical thinking. This means that you have to explain everything in detail, otherwise chaos will be the end result. Once you become more familiar with the language, try reading the code to yourself and methodically figure out the paths that can be taken within the program. Try giving the variables values, and plug them into the programs logic (repeat:until,while,endwhile,do,loop,if/then,if/else/endif,ect.) statements. Make each expression both true and false to see what happens. Some people even use block diagrams to map program flow. Everyone has there own personal aids or technics. Once you have achieved this, you will have the key to programming.

Keep it up Dave! It will come.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 2nd Jul 2005 12:42
Cool D Ogre, I got it to work.
Thanks a million for all your help.
I will have to think about what I want it to do next.
Here it is:
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 4th Jul 2005 00:26
You will probably want to do the bomber initialization before the "New_Game_Level" as well. This would make sure that the bombs where zeroed before a new level. Because there is two points in the program where you would do this, you could possibly write a function for this. Also, you don't need to use an additional variable for the loop for zeroing (INVADER). Use the actual variable of the FOR/NEXT loop to index the array.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 4th Jul 2005 08:07
When you say to use the actual variable are you saying;
instead of this

Do something like this:


I made a function out of it and it works except that the bullets dont go off the sceen at the bottom, they go to the top of the screen where you can see them just sit there until they get shot.
Thanks again.
Here is my code:
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 7th Jul 2005 07:26 Edited at: 7th Jul 2005 10:38
Your getting the idea. You don't need another variable to increment the array element like in your first example snippet. All your wanting to do is access the arrays (ships) by their elements.

I did it the way your first example is for the invader subroutine because I needed a linear incrementation for the array element within the nested loop. The loop variables X and Y handled the positions for the actual sprites. The Y loop is used for the number of rows, and the X loop is for the columns of invaders. The variable INVADER is the element index for the ships.

y = 0 - 2; 3 rows
x = 0 - 5; 6 columns
invader = array element for the ships (3 x 6 = 18)

The reason why your function puts the bombs at the top of the screen is simple. Remember, except for arrays, a function can not make use of main program variables unless they are passed to the function as a parameter or defined globally.

I would like to point out that functions don't remember what they did the last time they were called upon. They don't retain the contents of the local variables used inside of them after they finished doing a task.

There is something else you need to know. You can make use of media and other functions without passing any parameters. This means that you can make references to loaded media like bitmaps, images, sprites, 3D objects, sounds, and music directly. The use of other functions would mean you might grab the screen size with SCREEN WIDTH() and SCREEN HEIGHT(), or check collision of sprites with SPRITE HIT(sprite1,sprite2) for example. You could even call other "user-defined functions" as well. Other than arrays, anything with () after it can be considered a function, either built into the language or user defined.

Depending on what your planning to do with the function, you can use them with or without parameters. They can return a result as well, but only one value can be returned per function.

I am going to leave you with this information and a quote from myself...

Quote: " One last thing, when you finish your game. Try to find ways of optimizing things and possibly making the code into functions. If you do it the way we are writting it now (as mostly subroutines), you can figure out better what things can be converted, and what can't because the data structure is now visualized and in place. It's just a matter of doing the mods at this point."


If you want more information on how to use functions, here is a link that will help you out:
http://www.thegamecreators.com/data/newsletter/newsletter_issue_27.html
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 8th Jul 2005 03:27
I got it. Instead of using screeny+1 I just used a real value for the Y coordinate.
Now to see what else I can do to make it more fun, like power ups and stuff. It may be a bit before I get back to it, but Im sure you will hear from me again.

Thanks again
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 8th Jul 2005 11:53
Hey, that's great your now getting a real grasp of things!

I know you have some work to do for a while. When you get a chance to read this, I am just poking in with some suggestions on coding the game here.

When you get the game play working the way you want it, you could put all the subroutines inside of the game action loop. What I mean is don't call them with gosubs anymore just put the code right in the loop. First, the background, then the invaders, then the ship, and whatever else you come up with. Of course, leave the actual function definitions out at the end of the program.

What I am getting at here is the actual game engine can be portioned out as a function. This way you can write other parts like menus, high score, ect, ect. as individual function blocks too. Each one could also be independant files and INCLUDE them in a main program file. The main file could control and call each function when needed. This way you could update different sections indiviually instead of sifting through one large program to make the code changes.

When you get back, I will fill you in on the details. Maybe help you in the process of structuring the code this way.

D Ogre
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 9th Jul 2005 14:11
I'm back again with some more info. You don't have to check to see if any of the sprites exist. Once the sprites are created, they are always present. I set up the code so that it would be universal and it will take care several things at once.

Reasons Why:

1. You don't have to recreate each sprite when they explode off the screen, and use more code to check to see if they exist or not.

2. You can customize your wave formations for the invaders by using a transparency image map (rgb 0,0,0) in the rows and colums. You can use the same invader routine without making different routines for each wave formation.

To make use of this, you will have to use a count variable for the invaders destroyed. Let's say you wanted just nine invaders in the wave (with a max. of 18 in the nested loop). You would have to make a variable that stored how many ships where supposed to be hit on that level (until destroyed=shipcount or lives=0; where shipcount=9). The other nine sprites would be assigned a blank trans. image.

3. You can use alternate images instead of the ones checked for the collision part of the code. This could be useful for implementing shields for either the ship or the invaders. Just make a new image of whatever ship gets a shield, but make the image with say a bubble around it and assign it to the appropriate sprite. Just make sure that those image numbers aren't checked in the collision part of the code. You could also use it for power-ups too. (some additional code may be required).

That is why I set the program up this way. It makes things a lot easier to handle. Pretty neat, huh?

Have Fun!

D Ogre
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 9th Jul 2005 23:29
Nice to see you again.
I presume you are talking about the resetbomber function "You don't have to check to see if any of the sprites exist"?
I did remove the checking to see if sprite exist.
It was this:

Now it is this:


I am neck deep in putting in a rapid fire power up, so I did not really try to implement what the rest of your post was talking about. I will try to tackle that after I get the rapid fire.
I managed to randonly create (very frequent for testing purposes) a power up that falls from the top of the screen off the bottom and does it again at a random x location. I can catch it with the ship as well. I want to try to get this one working with a minimum of help. I really appreciate your help, but I want to struggle with this a bit more before I get help.

Thanks again
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 12th Jul 2005 09:13
Hey, no problem. Sounds like you got a handle on it. I was just giving you some suggestions. What you do with the info is up to you.
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 18th Jul 2005 11:59
Well, I struggled. I am back for more help. sigh.....
I really wanted to get it figured out on my own. Oh well.
I want to be able to have up to 10 lasers from the ship on the screen at one time. I am sure I have to make an array for the sprite number of each laser and an array for the x and y coordinate of the laser sprites. I was going to modify the fireing of the single laser, but make a for/next to move all lasers that are actually on the screen. I can not seem to figure out a way to keep track of what lasers(sprite numbers) are on and off the screen and tell the program to use the next number in line to put that sprite number on screen to get fired next.
I hope this makes sence, I have managed to totally confuse myself.

Thanks again
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 27th Jul 2005 09:29
Any one out there that can help?
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 27th Jul 2005 09:37 Edited at: 28th Jul 2005 06:49
Sorry about the long delay, Dave. I have been very busy with my own projects. I see your having some problems with your game powerups using multiple lasers.

You will have to be a little patient with me here. I will have to go back to the code and look at it. Give me a day or two to prepare my next volley of information. All I can say is that your on track by using arrays.

Don't worry, I told you I wouldn't keep you hanging...

----------------------------------------------------------------------

Day 2: (Edited Post)

Okay, Dave I got some code changes ready for you. This code will allow you to have as many shots fired as you want within reason of course. The changes includes everything even the collision part.

Here are the all the arrays used so far:


You will notice a new variable in the ship firing routine (powerup).
Use this variable to tell the ship how many times to fire. If you make powerup=1 then the ship fires normally.

Here is the INVADER Subroutine:


Here is the SHIP Control Subroutine:


You may have to play around with the code a little bit. I didn't know how you wanted the ship to fire, so I quessed on that part.

What happens in the ship subroutine is pretty much the same as before, but it can make multiple checks on the mouse button allowing up to as many lasers as you want to fire. Each laser either has to make it off the screen or hit an invader before it can be fired again.

You will also notice that there is a variable expression used in the trigger part of the laser code that looks like this:



This is to space out the lasers, if they are in a straight line. (Meaning just holding the mouse button and not moving the ship.) Each pass of the SHOT loop is computed into the start position of the laser in question.
Play around with this. You could simulate a big laser with it. Just minimize the spacing offset so each laser touches each other. This could be a different kind of powerup. Lots of possibilities here!

I hope this helps you. Again, sorry about the wait...

D Ogre

Oops!!! I almost forgot...The mods on the invader collision function.
Here it is:

D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 30th Jul 2005 03:51
Earth to Dave... Is there anybody out there? I hope you didn't give up on me.

If you do come back, I just wanted to say that you may have to edit some of the code to work with DBC again. I used the old example code I wrote in DBPro. Just look for anything concerning INC arrays and change them to array(x)=array(x)+1 instead of INC array(x), value. You know what I mean.

I hope you didn't bash your head into the wall again!

See ya later, I think?

D Ogre
David_M_
19
Years of Service
User Offline
Joined: 27th May 2005
Location:
Posted: 30th Jul 2005 15:03
Whoa, am I glad to see you. I guess I missed the email notification of your post on the 27th. I am sure glad I did not miss the notice for your post on the 29th. I have been busy on a non program project on live streaming video, and will be working on changeing my van alternator and kids birthday parties. Hopefully I will be able to check out your post in detail this weekend sometime.
Again, Im glad to see you again.

Later,
David
D Ogre
21
Years of Service
User Offline
Joined: 19th Nov 2003
Location:
Posted: 1st Aug 2005 05:44
Good to see you haven't lost your head on your project, Dave. Sometimes the trials and tribulations of life can swamp you. I had to put an exhaust system on my truck this weekend. Joy! I know how things can get in the way.

I've been working on a 2D fighter engine for DBPro between my other non-computer related projects. I seem to be juggling my time lately too.

Like I said before, you will have to play around with my mods. The code is probably not 100% for what you have in mind, but I'm sure it will pull you out of the mess somewhat. The problem area might be the firing trigger of the ship code. I sort of fudged it in a hurry.

If you have any more troubles, I will be around here somewhere...


D Ogre

Login to post a reply

Server time is: 2025-05-17 19:08:17
Your offset time is: 2025-05-17 19:08:17