Using an Array with collision detection
Author |
Message |
vapour99
![](http://compsci.ca/v3/uploads/user_avatars/11560994674845da5b2e45a.png)
|
Posted: Wed Jun 11, 2008 8:13 am Post subject: Using an Array with collision detection |
|
|
My spaceshooter game uses arrays to create bullets and falling meteors. If I implement simple collision detection, it seems to use the x/y vars of the most recently created meteor (possibly due to the "upper" command?)
side notes:
-I haven't fine tuned collision detection do to the entailed problem
-Asteroids and Meteors produce the same "falling meteor" effect but each use different arrays.
-asteroids are slightly smaller than the meteors and are grey.
Any help is much appreciated!
here is the code:
code: | View.Set ("graphics:400;640,offscreenonly,") % screen will be offscreen only, 400x and 640y, and support graphics
%%%%%%%%%%%%%%%%%%%
% Array Records %
%%%%%%%%%%%%%%%%%%%
type bullet : % defines variables (x/y coordinates) to be contained in the array
record
x, y : real
end record
type asteroid :
record
x2, y2 : real
end record
type meteor :
record
x3, y3 : real
end record
%%%%%%%%%%%%%%%%%%%
% Variables %
%%%%%%%%%%%%%%%%%%%
var buttonnumber, buttonupdown, buttons : int
var As1, As2, x3, y3, x2, y2, x, y, btn, shot, sopt : int
var exits : boolean := false
var firing, playing : boolean %defines wether or not the ship is firing
var time_last : real := -400 %times used to govern the first shot(can shoot right away)
var time_last2 : real := -400
var time_last3 : real := -400
var chars : array char of boolean %used for keys (pressed or not)
var bullets : flexible array 1 .. 0 of bullet %flexible array that determines the amount of bullets.
var asteroids : flexible array 1 .. 0 of asteroid
var meteors : flexible array 1 .. 0 of meteor
var back : int := Pic.FileNew ("e:/bckspace2.bmp")
var title : int := Pic.FileNew ("e:/spacegame title2.bmp")
var endtitle : int := Pic.FileNew ("e:/spacegame endtitle2.bmp")
var ship : int := Pic.FileNew ("e:/BattleCruiser.gif")
var font1, font2, win : int
%%%%%%%%%%%%%%%%%%%
% Sound Procs %
%%%%%%%%%%%%%%%%%%%
process bckgrnd % turing wont play .midi for some reason
Music.PlayFile ("e:/DesertStrike.mid")
end bckgrnd
process shootsnd
Music.PlayFileReturn ("e:/laser.mp3")
end shootsnd
%%%%%%%%%%%%%%%%%%%
% Game Procs %
%%%%%%%%%%%%%%%%%%%
proc input %the input procedure
Mouse.Where (x, y, btn) %monitors the mouse position and buttons
shot := 0
if btn > 0 and Time.Elapsed - time_last > 400 then %if the mouse button is pressed, there will be a 400 millisecond delay between each shot
new bullets, upper (bullets) + 1 %creates new values in the array
bullets (upper (bullets)).x := x %X value for a bullet in the array
bullets (upper (bullets)).y := y % Y value for a bullet in the array
time_last := Time.Elapsed %resets the timer for another half second
shot := 1
end if
Input.KeyDown (chars) % if ESC key is presses; the program exits the loop
if chars (KEY_ESC) then
exits := true %value "exits" is used outside of the loop
end if
end input
proc astrds
if Time.Elapsed - time_last2 > 400 then
y2 := 640
randint (x2, 0, 401)
new asteroids, upper (asteroids) + 1
asteroids (upper (asteroids)).x2 := x2
asteroids (upper (asteroids)).y2 := y2
time_last2 := Time.Elapsed
end if
end astrds
proc meteorz
if Time.Elapsed - time_last3 > 400 then
y3 := 640
randint (x3, 0, 399)
new meteors, upper (meteors) + 1
meteors (upper (meteors)).x3 := x3
meteors (upper (meteors)).y3 := y3
time_last3 := Time.Elapsed
end if
end meteorz
proc update %the procedure for moving the bullets
for i : 1 .. upper (bullets)
bullets (i).y += 6 %bullet speed value 1 for home; 6 for school (changes according to computer speed)
end for
end update
proc update2
for j : 1 .. upper (asteroids)
asteroids (j).y2 -= 8
end for
end update2
proc update3
for k : 1 .. upper (meteors)
meteors (k).y3 -= 8
end for
end update3
proc draw %draws the ship
x := x - 40
y := y - 50
Pic.Draw (ship, x, y, picMerge)
end draw
proc drawastrds
for j : 1 .. upper (asteroids)
drawfilloval (round (asteroids (j).x2), round (asteroids (j).y2), As1, As1, grey)
end for
end drawastrds
proc drawmeteors
for k : 1 .. upper (meteors)
drawfilloval (round (meteors (k).x3), round (meteors (k).y3), As2, As2, brown)
end for
end drawmeteors
proc drawbullets
for i : 1 .. upper (bullets) % draws the bullets using the array information
drawfilloval (round (bullets (i).x), round (bullets (i).y), 5, 5, 32)
end for
end drawbullets
proc maxxy
if x > 400 then
x := 400
elsif x < 0 then
x := 0
elsif y > 640 then
y := 640
elsif y < 0 then
y := 0
end if
end maxxy
%proc soption % sound option for shooting
% Input.KeyDown (chars)
% if chars ("q") then
% sopt := 1
% elsif chars ("w") then
% sopt := 0
% end if
%end soption
proc sounds
if shot > 0 then
fork shootsnd
end if
%if shot > 0 and sopt = 1 then
% Music.PlayFileReturn ("e:/elite-1.wav")
%end if
end sounds
proc Acollide %seems to use the x2 var of the most recent asteroid
if x + 10 <= x2 + 10 and x - 10 <= x2 - 10 and
y + 10 <= y2 + 10 and y - 10 <= y2 - 10 then
Music.PlayFileReturn ("e:/elite-1.wav")
end if
end Acollide
proc Mcollide %seems to use the x2 var of the most recent asteroid
if x + 10 <= x3 + 10 and x - 10 <= x3 - 10 and
y + 10 <= y3 + 10 and y - 10 <= y3 - 10 then
Music.PlayFileReturn ("e:/elite-1.wav")
end if
end Mcollide
process levels %will change the size of the asteroid according to how much time you have played (30 second intervals)
As1 := 15
As2 := 20
% put " level 1 "
% put " START "
% delay (1000)
% cls
delay (30000)
As1 := 20
As2 := 25
delay (30000)
As1 := 25
As2 := 30
delay (30000)
end levels
%%%%%%%%%%%%%%%%%%%
% Menu process %
%%%%%%%%%%%%%%%%%%%
loop %title screen
font1 := Font.New ("serif:12")
font2 := Font.New ("serif:18:bold")
Pic.Draw (title, 0, 0, picMerge)
buttonwait ("down", x, y, buttonnumber, buttonupdown) %waits for the mouse to be pushed
Font.Draw ("Get ready!", 175, 450, font1, green)
exit
end loop
%%%%%%%%%%%%%%%%%%%
% Main loop %
%%%%%%%%%%%%%%%%%%%
btn := 0 %avoids an accidental laser sound to be played
%fork bckgrnd %wont play .mid
fork levels
loop % the procedures are called to run the game
Pic.Draw (back, 0, 0, picMerge)
input
astrds
meteorz
maxxy
update
update2
update3
draw
drawbullets
drawastrds
drawmeteors
%Acollide
%Mcollide
%soption
sounds
View.Update
cls
exit when exits = true % if exits is true, it exits the loop
end loop
Music.PlayFileStop % stops background music
Music.PlayFileReturn ("e:/c4_explode1.wav") %exit screen
Pic.Draw (endtitle, 0, 0, picMerge)
View.Update
|
|
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Insectoid
![](http://compsci.ca/v3/uploads/user_avatars/13760332514cbd0ce972eaa.jpg)
|
Posted: Wed Jun 11, 2008 3:20 pm Post subject: RE:Using an Array with collision detection |
|
|
It would be nice if you'd make it an attatchment, so that we have the pictures as well. I can't help until then.
|
|
|
|
|
![](images/spacer.gif) |
vapour99
![](http://compsci.ca/v3/uploads/user_avatars/11560994674845da5b2e45a.png)
|
Posted: Wed Jun 11, 2008 6:02 pm Post subject: Re: Using an Array with collision detection |
|
|
Here you are
-You may have to nil-out (with %) some other sounds I threw in but are unused in this version (elite-1.wav)
Description: |
here is the .rar'ed game with .bmp's and the shooting sound. |
|
![](http://compsci.ca/v3/pafiledb/images/icons/clip.gif) Download |
Filename: |
game.rar |
Filesize: |
176.51 KB |
Downloaded: |
91 Time(s) |
|
|
|
|
|
![](images/spacer.gif) |
riveryu
![](http://compsci.ca/v3/uploads/user_avatars/196991102647ae2debe0bf0.jpg)
|
Posted: Wed Jun 11, 2008 10:41 pm Post subject: Re: Using an Array with collision detection |
|
|
vapour99 wrote:
My spaceshooter game uses arrays to create bullets and falling meteors. If I implement simple collision detection, it seems to use the x/y vars of the most recently created meteor (possibly due to the "upper" command?)
-I haven't fine tuned collision detection do to the entailed problem...
To solve your problem, all you need to do is to for loop through the array of your meteors or asteroids arrays and check each one.
I assume that you already know how to do it according to your coding habit that im seeing, but heres an example. Hope this helps you, sry if its too obvious.
Also, when I ran your program from your posted attachement, it didnt work because "illegal picture ID number".
if you didnt know already, you dont have to put the directory "e:/picFileName.pic" if you have your turing file in the same directory, you can just put "picFileName.pic" if the turing file is also in "e:/".
This makes it easier when you want to move your files, so you dont have to keep editing your loading dir.
Turing: |
var AnArray : flexible array 1 .. 0 of int
for i : 1 .. 10
new AnArray, upper (AnArray ) + 1
AnArray (i ) := i %just to initialize this array
end for
for i : 1 .. upper (AnArray )
if AnArray (i ) mod 2 = 0
then
put AnArray (i )
end if
end for |
|
|
|
|
|
![](images/spacer.gif) |
vapour99
![](http://compsci.ca/v3/uploads/user_avatars/11560994674845da5b2e45a.png)
|
Posted: Thu Jun 12, 2008 8:24 am Post subject: Re: Using an Array with collision detection |
|
|
Sorry about the pictures and propable sound errors from my previous attachement
Im just looking at "riveryu's" suggestion and am attempting to implementing it now (im a tad busy with exams)
Unfortunatly, flexible Arrays are a relatively new skill to me, as is the use of "mod" can anyone shed light on precisely what is going on inside of the for loops (it would be a great help as i'm relatively new to coding)
thanks for the quick replies!
Here is the most recent version of my game with all the necessary files (it dosen't have riveryu's for loops implemented yet)
Description: |
|
![](http://compsci.ca/v3/pafiledb/images/icons/clip.gif) Download |
Filename: |
Spaceshooter V3.2.zip |
Filesize: |
1.06 MB |
Downloaded: |
94 Time(s) |
|
|
|
|
|
![](images/spacer.gif) |
vapour99
![](http://compsci.ca/v3/uploads/user_avatars/11560994674845da5b2e45a.png)
|
Posted: Thu Jun 12, 2008 7:22 pm Post subject: Re: Using an Array with collision detection |
|
|
sorry about myself replying again; here is another update of the source code (now has crude options for the speed of computer the program is run on, it changes projectile speeds accordingly)
Description: |
|
![](http://compsci.ca/v3/pafiledb/images/icons/clip.gif) Download |
Filename: |
Pauls_space_shooterV3.2.t |
Filesize: |
7.7 KB |
Downloaded: |
90 Time(s) |
|
|
|
|
|
![](images/spacer.gif) |
Insectoid
![](http://compsci.ca/v3/uploads/user_avatars/13760332514cbd0ce972eaa.jpg)
|
Posted: Thu Jun 12, 2008 7:37 pm Post subject: RE:Using an Array with collision detection |
|
|
Instead of reposting you new copy, you can edit your last one and click 'update attachment' after you click on 'posted attatchments'. Save some bandwidth, make less reading.
|
|
|
|
|
![](images/spacer.gif) |
riveryu
![](http://compsci.ca/v3/uploads/user_avatars/196991102647ae2debe0bf0.jpg)
|
Posted: Thu Jun 12, 2008 9:01 pm Post subject: Re: Using an Array with collision detection |
|
|
Im busy with them damned exams too actually. If this is reply is not late...
- you can add a loading screen before the picture loading. Ex. insert the line put "loading ..." right before loading pictures, so the user sees the load screen while program loads pictures.
- the for loop explaination...read the comments...
Turing: |
var AnArray : flexible array 1 .. 0 of int %declares array
for i : 1 .. 10
new AnArray, upper (AnArray ) + 1 %we are creating 1 new element each loop starting from 0 (the upper limit of the array), everytime we add one to the current upper limit.
AnArray (i ) := i %assigns i to array(i), say i is 1, then integer 1 is assigned to AnArray (1), this goes on to 10 as the for loop is set to 10 .
end for
for i : 1 .. upper (AnArray ) %detects the upper limit of array to loop through every element.
if AnArray (i ) mod 2 = 0 %dont worry about mod that much, its just to show you the if statement structure checking all elements of the array.
then %when i = 1, it checks AnArray(1), if it meets the condition execute "put AnArray(i)" or currently AnArray(1).
put AnArray (i )
end if
end for |
mod, or modulo operator returns the remainder of a number. Ex. 4 mod 2 yields 0 , 4 divided by 2 does not have remainder, therefore 0. Another case, 5 mod 2 yields 1, because 2 goes into 5 two times, 5 - 4(from 2*2) = 1.
|
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
vapour99
![](http://compsci.ca/v3/uploads/user_avatars/11560994674845da5b2e45a.png)
|
Posted: Sun Jun 15, 2008 3:13 pm Post subject: Re: Using an Array with collision detection |
|
|
well, I now have the for loop checking all the asteroids that are created (im starting with clooision detection on the asteroids) but I have ran into another problem; it seems it checks EVERY asteroid or meteor that has been created; this means that it will collide even if the Asteroid/meteor is long gone... not good. is there a way to check for the asteroids/meteors that are currently on the screen? (possibly remove the asteroids/meteors that have exceeded the max y value of the window from the array?)
here is the procedure code that has to do with collision detection in asteroids:
code: |
proc Acollide %seems to use the vars of all previous asteroids addded in the flexible array
for i : 1 .. upper (asteroids)
if asteroids (i).x2 + As1 < x + 15
%and asteroids (i).x2 - As1 > x - 15 % I plan to configure each one sequentially
%and asteroids (i).y2 + As1 >= y + 15
%and asteroids (i).y2 - As1 <= y - 15
then
colde := true
end if
end for
end Acollide
|
NOTE:
-the most recent version uses a small flashing box in the lower left corner to show that it is colliding instead of a sound
- is set to a sort of "debug mode" so that only one asteroid is created every 8 seconds
Description: |
|
![](http://compsci.ca/v3/pafiledb/images/icons/clip.gif) Download |
Filename: |
Pauls_space_shooterV3.3.t |
Filesize: |
11.21 KB |
Downloaded: |
76 Time(s) |
|
|
|
|
|
![](images/spacer.gif) |
riveryu
![](http://compsci.ca/v3/uploads/user_avatars/196991102647ae2debe0bf0.jpg)
|
Posted: Sun Jun 15, 2008 9:07 pm Post subject: RE:Using an Array with collision detection |
|
|
Sry but, you should bundle your posts with pictures so we dont have to look at your previous ones and search for pics when we want to SEE it.
For the checking for collison part, you should only allow a set number of meteors on screen maybe increase with level or difficulty.
Recycle your array elements, when the asteroids are off screen, reasign them to a new position as if they are new asteroids.
Heres a non-working code to show you the structure.
Turing: |
%here assigns the initial values of each meteor
for i : 1.. 5
meteorX (i ):= randint(0, maxx)
meteorY (i ):=maxxy
end for
%here moves the meteors and checks their position to see if they are offscreen
%if they are then assign them to an initial position(wont be same b/c of Rand.Int).
for i : 1.. 5
meteorY (i ) - = 5
if meteorY (i ) < 0 then
meteorX (i ):=Rand.Int (0, maxx)
meteorY (i ):=maxxy
end for |
|
|
|
|
|
![](images/spacer.gif) |
|
|