Advice on a Game

I am making a simple shooter and have a question about collision detection. The player can shoot bullets at a fast rate so there can be many bullets on the screen at any given time. Also, there are a number of enemy ships on the screen at the same time. So,
on every frame I need to check if any of the bullets have collided with any of the enemy ships. What is the best way to do this?

I use duplicateMovieClip to make new bullets and enemy ships…
They have names like b1, b2, b3…
and
e1, e2, e3…

Best to have the named like:

duplicateMovieClip(whatever, whatever+i, i)

and then you do i++ after each time…I’ve never tried it but thats what i’ve heard :slight_smile:

see this

http://www.kirupaforum.com/forums/showthread.php?threadid=31327

Yeah about the names. That’s what I did(b1, b2, b3…).
I need to know about multiple collision detections.

ahmed,
that wasnt much help, but thanks.

Also, that would’nt work because there are multiple bullets.

ok ive done this… so lemme see if i can explain it alright…

you need to set limits for your different sets of objects

your bullets say are one set and your enemies another

you need to set ranges that can be looped through to check each set against each other… so say make each set have a range of 100 objects… your ships bullets will be 100-199 and your enemy ships will be 200-299.

so when you use the variables to duplicate your things they will be named for example:

b100, b101… b198… b199 and e200, e201… 298, e299.

so now you will have a variable for each range, initialized to their beginning values:

say in your ship MC you put the code for duplicate so in the load you declare

var bullets = 100;

and say you have a mc off to the side or however you want to generate your enemies… declare

var enemies = 200;

now for your bullets you know how to duplicate:

_root.bullet.duplicateMovieClip(“b”+bullets,bullets);
then you would increment bullets;

bullets ++;

now to keep your range add


if(bullets > 199)
{
bullets = 100;
}

this will make sure your bullets are ALWAYS named between b100 and b199

the same will go for your enemies…


_root.enemyShip.duplicateMovieClip("e"+enemies,enemies);
enemies ++;
if(enemies > 299)
{
enemies = 200;
}

so now you know for sure that your bullets are always b100-b199 and your enemies are e200-e299

now for the collision code
either put this in the mc of the enemy you are duplicating or the bullets you are duplicating
i would choose the bullet, but since you have your ranges set it doesnt really matter

so say you choose your bullet
in your bullet mc on enter frame put


for(i=200;i<=299;i++)//loops through the range of the enemy ships
{
if(this, hitTest(_root["e"+i]))
{
this.removeMovieClip();//this can be substituted with playing a destruction animation or whatever you want
_root["e"+i].removeMovieClip();
}
}

and that should be it…

to recap: set ranges for each set of items you check against eachother

in the mc being duplicated of one of the sets, check against each of the other set

its pretty easy once you get the hang of it… i did all this off the top of my head and its kinda late so i hope i didnt mess any code up, and i hope i explained it alright… if there are any questions feel free to ask

hope it helps

[edit]
oh yeah almost forgot… just make sure your ranges are set so your stuff can always be on the screen… say your range for enemies is 100-150… when it gets to 150 you set it back to 100… but… if #100 is still there from before… then it will disappear and a new 100 will be generated… they overwrite eachother so make sure you dont overwrite too fast and make stuff just randomly disappear from your screen or whatever
[/edit]

I’d do it much simpeler, listen to this:

When shooting a bullet, I’d push() its name into an Array on the _root. That way you always have reference to all the fired bullets.
Ofcourse, the bullet contains a loops which check if it should be destroyed. And if it should, it does that itself (this.removeMovieClip()) and splices itself from the Array.

The targets, or aliens, ships whatever, they should loop through the bullet array and check if it collides with anything.
I’d let the target manage its own health and destruction.

Would you like me to make you an example?

An example would be cool. Your way was how I thought I’d do it, but I was unsure about the array management issues…

thanks

I had something in mind like the following code. Test it, and if you like it, check the attached .zip file for a more structured version with commentry!!

It took me about an hour to make this, so I hope this is what you are looking for. I know I let my imagination run wild, but theres enough left for you to do. Have fun, and let me know what you think.

Gr Eric :slight_smile:


// ************************* //
// DEFINE CONSTANT VARIABLES //
// ************************* //
Stage 		= {width: Stage.width, height: Stage.height};
bullet_fps	= 200;
bullet_maxn = 5;
alien_space = 20;
alien_rows  = 3;
alien_cols  = 9;

// ************************* //
//   CREATE STATIC OBJECTS   //
// ************************* //
//____________ Object #1: The ship!
_root.createEmptyMovieClip("fighter", ++d).beginFill(0x000000, 100);
fighter.c = [
{x: 0,  y: 0},
{x: 5,  y: 15},
{x: -5, y: 15},
{x: 0,  y: 0}
             ];
//____________ Object #2: The bullet!
_root.createEmptyMovieClip("bullet", ++d).lineStyle(2, 0x000000, 100);
_root.bullet.lineTo(0.5, 0.5); _root.bullet._visible = false;

//____________ Object #3: The invader!
_root.createEmptyMovieClip("invader", ++d).beginFill(0x000000, 100);
invader.c = [
{x: 0,   y: -10},
{x: 10,  y: -10},
{x: 10,  y: -20},
{x: 16,  y: -14},
{x: 16,  y: -10},
{x: 20,  y: -10},
{x: 10,  y: 0},
{x: 8,   y: 10},
{x: 8,   y: 2},
{x: 0,   y: 0},
{x: -8,  y: 2},
{x: -8,  y: 10},
{x: -10, y: 0},
{x: -20, y: -10},
{x: -16, y: -10},
{x: -16, y: -14},
{x: -10, y: -20},
{x: -10, y: -10},
{x: -10, y: -10}
			 ];

//____________ Object #3: The scoreboard!
_root.createTextField("score", ++d,Stage.width-50,Stage.height-30,50,30);
score.text = "0";

// ************************* //
//      CREATE  CLASSES      //
// ************************* //
//____________ Object #1: The key processor!
key_processor	= new Object();

//____________ Object #2: The bullet processor!
bullets			= new Object();
bullets.onstage = new Array();

// ************************* //
//   FUNCTIONS & PROTOTYPES  //
// ************************* //
Array.prototype.removeItem = function(item)
{
     for (var n = 0; n<this.length; n++)
     {
          if (this[n] == item)
          {
               this.splice(n, 1);
               return;
          }
     }
};

MovieClip.prototype.drawPoints = function( points )
{
	this.moveTo(points[0].x, points[0].y);
	
	for (i=1; i<points.length; i++) 
	  this.lineTo(points*.x, points*.y);
};

// ************************* //
//       DEFINE CLASSES      //
// ************************* //
// BULLETS CLASS - BULLETS CLASS - BULLETS CLASS - BULLETS CLASS - BULLETS CLASS - BULLETS CLASS 
bullets.onEnterFrameEvent = function(src)
{
	if (src._y < 0)
	{
			_root.score.text = Number(_root.score.text) - 1;
			this.kill(src);
	}
	src._y--;
	updateAfterEvent();
}

bullets.kill = function(src)
{
	clearInterval(src.interval);
	this.onstage.removeItem(src);
	src.removeMovieClip();
}

bullets.fire = function()
{
	if (this.onstage.length >= bullet_maxn)
	{
		this.kill(this.onstage[0]);
		//this.onstage.shift();
	}
	b = _root.bullet.duplicateMovieClip("bullet" + d, ++d, {_visible: true, _x: fighter._x, _y: fighter._y});
	b.interval = setInterval(this, "onEnterFrameEvent", 1000/(bullet_fps+2), b);
	this.onstage.push(b);
}

// FIGHTER CLASS - FIGHTER CLASS - FIGHTER CLASS - FIGHTER CLASS - FIGHTER CLASS - FIGHTER CLASS
fighter.create = function()
{
	this.drawPoints(this.c);
	this.interval	= setInterval( this, "onEnterFrameEvent", 25);
	this._y			= Stage.height - this._height;
	this._x			= Stage.width / 2;
}

fighter.onEnterFrameEvent = function()
{
	if (Key.isDown(Key.LEFT)) x_speed -= 0.2;
	if (Key.isDown(Key.RIGHT)) x_speed += 0.2;
	this._x += x_speed;
	x_speed *= 0.96;

	updateAfterEvent();
}

// INVADER CLASS - INVADER CLASS - INVADER CLASS - INVADER CLASS - INVADER CLASS - INVADER CLASS
invader.create = function()
{
	this.drawPoints(this.c);
	this._visible = false;
}

invader.draw = function(x,y,h)
{
	if (!h) h = 1;

	b = this.duplicateMovieClip("invader" + d, ++d, {_visible: true, _x: x, _y: y});
	b.shield   = h;
	b.hitsleft = h;
	b.interval = setInterval(this, "onEnterFrameEvent", 25, b);
	this.onstage.push(b);
}

invader.kill = function(src)
{
	_root.score.text = Number(_root.score.text) + (src.shield * 10);
	clearInterval(src.interval);
	this.onstage.removeItem(src);
	src.removeMovieClip();
}

invader.onEnterFrameEvent = function(src)
{
	for(i=0; i<bullets.onstage.length; i++)
	{
		if (src.hitTest(bullets.onstage*._x, bullets.onstage*._y))
		{
			_root.score.text = Number(_root.score.text) +2;
			bullets.kill(bullets.onstage*);
			src._alpha -= 100/src.shield;
			src.hitsleft--;

			if (src.hitsleft == 0) this.kill(src);
		}
	}
	updateAfterEvent();
}

// KEY CLASS - KEY CLASS - KEY CLASS - KEY CLASS - KEY CLASS - KEY CLASS - KEY CLASS - KEY CLASS
key_processor.onKeyDown = function() 
{
    pressed_key = Key.getCode();
	switch (pressed_key) 
	{
		case 32: // SPACE
			bullets.fire();
			break;
	}
};

Key.addListener(key_processor);
fighter.create();
invader.create();
for(y=0; y<alien_rows; y++)
	for (x=0; x<alien_cols; x++)
	{
		xpos = 35 + (x*(alien_space+invader._width));
		ypos = 35 + (y*(alien_space+invader._height));
		invader.draw( xpos,ypos, alien_rows-y );
	}

come on … did I write all that code to not even get a response :S