Page 1 of 1

Making flash games for the non-flash developer Part IV Continues to discusses how to start developing games using Flex 3 and

#1 coden4fun  Icon User is offline

  • if(coden4fun.NotTired){ ContinueToCode(); }
  • member icon

Reputation: 27
  • View blog
  • Posts: 696
  • Joined: 27-February 09

Posted 14 March 2009 - 08:20 PM

Preface and a Follow up
This is part 4 of an 8 part series of writing a finished flash game using Flex and ActionScript 3. Here I will discuss precisely what was mentioned in step 4 for our Current Goals in completing this project, and in great detail discuss how I got there. Upon completing this tutorial you will have learned how to make an abstract enemy class, all enemies (that are not bosses) that will extend from that class, a bullet class for the player to use to shoot the enemies and the collision of the bullet to the player. We will discuss why it is important to have an abstract enemy class ( a base class for all enemies) on top of having the base class for all entities, but it might not make sense until we discuss the artificial intelligence for the game in the next tutorial.

This is actually going to be our shortest tutorial, and I'm sure after the last tutorial this is actually something you want to hear. In fact, it is because of our abstract code that we want to reuse, and the magical programming feature of polymorphism that let's us save a lot of time when we have to make many different game entities that just happens to share similarities with other game entities, which in turn let's us organize these similarities and make a base class that all entities extend, so we don't have rewrite code. So without further a due let's start coding.

The Abstract Enemy Class

Below is the base class for all entities. The initEnemies will pass a specific graphic to the abstract class AbstractEntity that we made in our last tutorial, and create an entity of that specific kind. This class actually hasn't changed at all from the AbstractEntity class except we have our own initEnemies function we have our enemies that extend AbstractEntity to utilize gracefully.
package
{
	import flash.geom.Point;
	
	public class AbstractEnemy extends AbstractEntity
	{
		
		//constructor
		public function AbstractEnemy()
		{
			super();
		}
		
		//initialize the enemies
		public function initEnemies(graphics:GraphicsResource):void
		{
			super.init(graphics, new Point(Math.random()*Constants.width, Math.random()*Constants.height));
		}
		
		//shutdown the enemy entity
		override public function shutdown():void
		{
			super.shutdown();
		}
		
		//update the enemies.  
		override public function update(seconds:Number):void
		{
			super.update(seconds);	
		}
	}
}


initEnemies() - Each enemy will call this as the initiate, and will pass to the a unique graphic, which then in turn this base class will make them go to a random point on the screen within the width and height of the application.

shutdown() update() - These are the same as the abstract class that it extends, and it is left blank for now, but when we get real dirty with each enemy moving in a specific formation, and creating what is a Galaga we'll write that specific code in this update function, and of course add to this class as we need to, but for now to just get enemies on the screen at a random spot and shoot them this is all that is needed.

So this abstract class may not look much, and at first glance you probably don't see the reason to have an abstract class that extends the abstract class of AbstractEntity but I promise you will in the next tutorial, so for now let's just understand that it will be needed, and change form that of AbstractEntity, but for now it's all we need.

Now I didn't know what specific names each of the enemies were, so I called them respectively by either what insect I could clearly define them as, or by the color of the bug.

So we now we can look at our enemies.

Our Enemies
I played an arcade version of this game already, and from what I gathered there were 4 main non-boss enemies, which were bees, a smaller bug, and then a green and blue bug, and well those are the names that I gave them, and I started with the bees first, so let's look at the Bee's class, and then just list the rest, since they are all exactly the same for this lesson.

Killer Bees
package
{
	public class Bees extends AbstractEnemy
	{
		
		public function Bees()
		{
			super();
		}
		
		//initiate the Bee's
		public function initBee():void
		{
			super.initEnemies(ResourceManager.BeeGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Small Bugs
package
{
	public class SmallBug extends AbstractEnemy
	{
		
		public function SmallBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initSmallBug():void
		{
			super.initEnemies(ResourceManager.BugGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Blue Bugs
package
{
	public class BlueBug extends AbstractEnemy
	{
		
		public function BlueBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initBlueBug():void
		{
			super.initEnemies(ResourceManager.BlueBugGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



and finally

The Green Bugs

package
{
	public class GreenBug extends AbstractEnemy
	{
		
		public function GreenBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initGreenBug():void
		{
			super.initEnemies(ResourceManager.GreenBugGraphics);
		}
		
		//update the green bug.  later this is where the AI will go.  Leave this blank for collision detection.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Now if you have kept up with these tutorials that I have written, and you're sweating over there's a lot of classes, and how am I going to instantiate all of these then... Calm down! All of the classes for now are precisely the same and just like the player class (except no keyDown event), and their names, and specific Graphic they pass to the AbstractEnemy, which passes that graphic to the AbstractEntity are different, but besides the class name, and the specific graphic they pass they're all the same.

They call the initEnemies with their specific initNameofClass function, and pass to that a graphic, and then in turn the AbstractEnemy does the first global function that it will do only to all enemies and that is place them randomly on the screen. (This will be changed when we work on the AI in the next tutorial), and then that's it.

So without the names, and the specific graphics resource we give that specific instance it's no different than the player class.

now for the bullet class.

The Bullet Class
Since the bullet class is not an enemy, but just another entity like the player then we can still just use the AbstractEntity class, and extend it to save time and lines of code. Doing so we get the following class below;
package
{
	import flash.geom.Point;
	
	public class Bullet extends AbstractEntity
	{
		public function Bullet()
		{
			super();
		}
		
		//initialize the bullet
		public function initBullet(position:Point):void
		{
			super.init(ResourceManager.BulletGraphics, position, 0);
		}
		
		//shutodwn the bullet
		override public function shutdown():void
		{
			super.shutdown();
		}
		
		//update the bullet if we collide with an entity delete this bullet, and that specific entity
		override public function update(seconds:Number):void
		{
			position.y -= 10;
			
			if(position.y < 0) shutdown();
			
			if(super.Collided(this, EntityManager.Instance.greenBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.greenBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.blueBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.blueBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.smallBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.smallBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.bees))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.bees);
			}
			
			super.update(seconds);
		} 
	}
}



The following code above is precisely the same as the player class, and I'm hoping you guys and girls can see a pattern now, and see why having abstract classes are not only important but are a good thing! Saves me time! ;)

Now the only code we're really going to have to discuss here is the update function that we override from the AbstractEntity class.

We check for a collision and if we have a collision then we must remove the 2 that has collided, which will always be the bullet entity, and the entity that checks the collision on.

We use the removeEntity() function that we made in the EntityManager class, and now I'm sure you can realize why we named it the EntityManager class... ha ha... let's continue....
//update the bullet if we collide with an entity delete this bullet, and that specific entity
		override public function update(seconds:Number):void
		{
			position.y -= 10;
			
			if(position.y < 0) shutdown();
			
			if(super.Collided(this, EntityManager.Instance.greenBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.greenBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.blueBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.blueBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.smallBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.smallBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.bees))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.bees);
			}
			
			super.update(seconds);
		} 



Woo! What is this...

super.Collided(this, Entity.Instance.blueBugs)



It's simply a class we added in the AbstractEntity class, and we simply pass it this specific entity the bullet entity with all 4 entities of the enemies. Now why do we do it here in the bullet class? Well, I have this huge crunch over saving time, money, and lines of code and realizing that we only need to check for collision with bullet and all enemies, and the player and all enemies instead of having a global class to check for a possible collision of an entity that doesn't exist we do it here only when it does exist. Does that make sense? :blink:

OK, when the bullet is instantiated it then goes through this cycle of update each time we redraw the screen, but when it no longer exist not only are we checking on a null entity that doesn't exist for a collision if we have this in another global class, but it's not needed, and possibly we can create an error, so what do we do?

We check to see when the collision check is needed. We then put the collision check function in a class that all entities will be using Hint: the AbstractEntity class and then we only check for the collision when we the bullet exist.

Now for the quick add of this collision detection that is in the AbstractEntity class.

Updated AbstractEntity Class
The only code we add is the function that checks for the collision, which is below.
//check for a collision between 2 entities.  Let the specific entities check this only when they're not null
		public function Collided(entityA:AbstractEntity, entityB:AbstractEntity):Boolean
		{
			var leftA:int = entityA.position.x;
			var leftB:int = entityB.position.x;
			var rightA:int = entityA.position.x + entityA.graphics.bitmap.rect.width;
			var rightB:int = entityB.position.x + entityB.graphics.bitmap.rect.width;
			var topA:int = entityA.position.y;
			var topB:int = entityB.position.y;
			var bottomA:int = entityA.position.y + entityA.graphics.bitmap.rect.height;
			var bottomB:int = entityB.position.y + entityB.graphics.bitmap.rect.height;
			
			if( (bottomA <= topB ) || ( topA >= bottomB ) || ( rightA <= leftB ) ||( leftA >= rightB )) return false;
			
			else 
			 return true; 
		}



The code above simply gets the precise points and sizes of 2 entities that is dealing with. We put these values in variables that describe what they are pertaining to a collision with that specific entities graphic. (i.e. why it's labeled leftA, leftB, ... bottomA, and bottomB respectively).

Then instead of checking for a collision, let's just check when there's not a collision that is when we know a collision can't possibly occur. if any of these return then we return false, for we are not colliding, else we can safely assume that a collision has been made, and we must clean up accordingly.

Now that we have all enemies, and bullets. Let's create this instances.

Instantiating Enemies
First we declare the variables
				//we create a variable like we did with the player.  
				public var player:Player;
		public var bees:Bees;
		public var smallBugs:SmallBug;
		public var greenBugs:GreenBug;
		public var blueBugs:BlueBug;
		public var bullet:Bullet;



and then we create an instance of each class.

					   //we create the instance of all enemies where we created the instance of the player  
					   player = new Player();
			bees = new Bees();
			smallBugs = new SmallBug();
			greenBugs = new GreenBug();
			blueBugs = new BlueBug();
			bullet = new Bullet();



and then we initialize those entities that are needed soon as the game start. Note: we do not initialize the bullet. No need for it.

					   //we then initialize all enemies when we initialize the player  
					   player.initPlayer();
			bees.initBee();
			smallBugs.initSmallBug();
			greenBugs.initGreenBug();
			blueBugs.initBlueBug();



NOTICE: We don't initialize the bullet in this class. That's because it's not needed, for it's only initialized when we need it, which is when the player hit's the spacebar key


now let's add the final piece for this tutorial that will bring this project to life. We must now edit the player class just a little, and create an instance of the bullet when we hit the spacebar key.

Edit Player Class
//give the player some movement
		public function keyHandler(event:KeyboardEvent):void
		{
			if(event.keyCode == 37) position.x -= 20;
			if(event.keyCode == 39) position.x += 20;
			if(event.keyCode == 32) 
			{
				EntityManager.Instance.bullet = new Bullet();
				EntityManager.Instance.bullet.initBullet(new Point(position.x, position.y - graphics.bitmap.rect.height));
			}
		}



When we hit the keycode of 32, which is the spacebar key we create an instance of bullet, and then we initialize it by passing it a position which is equivalent to our players specific position at that instance.

OK, we're done!

See what you have created now!
Posted Image

Conclusion

We have created the base class of all enemies, all enemies that are not bosses, put them on a random point on the screen, created the bullet class, and once the player hits the spacebar key we initialize that bullet and as it's existing and updating we check for a collision between that bullet and all enemies. If we collide with that bullet and any of the enemies we then remove those 2 specific entities, which collided. Well that is it for now I'm afraid, but no worries I can assure you that the next tutorial will be at least 2x as long as the previous tutorial, for we'll be working on special algorithms, and level ups, so be sure to tune in for the next tutorial in this series, but until then...

Happy Coding!

Source Code
Source Code

Is This A Good Question/Topic? 0
  • +

Replies To: Making flash games for the non-flash developer Part IV

#2 jkennedy  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 13-March 09

Posted 20 March 2009 - 02:09 PM

View Postcoden4fun, on 14 Mar, 2009 - 07:20 PM, said:

Preface and a Follow up
This is part 4 of an 8 part series of writing a finished flash game using Flex and ActionScript 3. Here I will discuss precisely what was mentioned in step 4 for our Current Goals in completing this project, and in great detail discuss how I got there. Upon completing this tutorial you will have learned how to make an abstract enemy class, all enemies (that are not bosses) that will extend from that class, a bullet class for the player to use to shoot the enemies and the collision of the bullet to the player. We will discuss why it is important to have an abstract enemy class ( a base class for all enemies) on top of having the base class for all entities, but it might not make sense until we discuss the artificial intelligence for the game in the next tutorial.

This is actually going to be our shortest tutorial, and I'm sure after the last tutorial this is actually something you want to hear. In fact, it is because of our abstract code that we want to reuse, and the magical programming feature of polymorphism that let's us save a lot of time when we have to make many different game entities that just happens to share similarities with other game entities, which in turn let's us organize these similarities and make a base class that all entities extend, so we don't have rewrite code. So without further a due let's start coding.

The Abstract Enemy Class

Below is the base class for all entities. The initEnemies will pass a specific graphic to the abstract class AbstractEntity that we made in our last tutorial, and create an entity of that specific kind. This class actually hasn't changed at all from the AbstractEntity class except we have our own initEnemies function we have our enemies that extend AbstractEntity to utilize gracefully.
package
{
	import flash.geom.Point;
	
	public class AbstractEnemy extends AbstractEntity
	{
		
		//constructor
		public function AbstractEnemy()
		{
			super();
		}
		
		//initialize the enemies
		public function initEnemies(graphics:GraphicsResource):void
		{
			super.init(graphics, new Point(Math.random()*Constants.width, Math.random()*Constants.height));
		}
		
		//shutdown the enemy entity
		override public function shutdown():void
		{
			super.shutdown();
		}
		
		//update the enemies.  
		override public function update(seconds:Number):void
		{
			super.update(seconds);	
		}
	}
}


initEnemies() - Each enemy will call this as the initiate, and will pass to the a unique graphic, which then in turn this base class will make them go to a random point on the screen within the width and height of the application.

shutdown() update() - These are the same as the abstract class that it extends, and it is left blank for now, but when we get real dirty with each enemy moving in a specific formation, and creating what is a Galaga we'll write that specific code in this update function, and of course add to this class as we need to, but for now to just get enemies on the screen at a random spot and shoot them this is all that is needed.

So this abstract class may not look much, and at first glance you probably don't see the reason to have an abstract class that extends the abstract class of AbstractEntity but I promise you will in the next tutorial, so for now let's just understand that it will be needed, and change form that of AbstractEntity, but for now it's all we need.

Now I didn't know what specific names each of the enemies were, so I called them respectively by either what insect I could clearly define them as, or by the color of the bug.

So we now we can look at our enemies.

Our Enemies
I played an arcade version of this game already, and from what I gathered there were 4 main non-boss enemies, which were bees, a smaller bug, and then a green and blue bug, and well those are the names that I gave them, and I started with the bees first, so let's look at the Bee's class, and then just list the rest, since they are all exactly the same for this lesson.

Killer Bees
package
{
	public class Bees extends AbstractEnemy
	{
		
		public function Bees()
		{
			super();
		}
		
		//initiate the Bee's
		public function initBee():void
		{
			super.initEnemies(ResourceManager.BeeGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Small Bugs
package
{
	public class SmallBug extends AbstractEnemy
	{
		
		public function SmallBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initSmallBug():void
		{
			super.initEnemies(ResourceManager.BugGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Blue Bugs
package
{
	public class BlueBug extends AbstractEnemy
	{
		
		public function BlueBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initBlueBug():void
		{
			super.initEnemies(ResourceManager.BlueBugGraphics);
		}
		
		//update the bee's.  later this is where the AI will go.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



and finally

The Green Bugs

package
{
	public class GreenBug extends AbstractEnemy
	{
		
		public function GreenBug()
		{
			super();
		}
		
		//initiate the Bee's
		public function initGreenBug():void
		{
			super.initEnemies(ResourceManager.GreenBugGraphics);
		}
		
		//update the green bug.  later this is where the AI will go.  Leave this blank for collision detection.
		override public function update(seconds:Number):void
		{
			super.update(seconds);
		}
		
		//shutodwn the bee
		override public function shutdown():void
		{
			super.shutdown();
		}
	}
}



Now if you have kept up with these tutorials that I have written, and you're sweating over there's a lot of classes, and how am I going to instantiate all of these then... Calm down! All of the classes for now are precisely the same and just like the player class (except no keyDown event), and their names, and specific Graphic they pass to the AbstractEnemy, which passes that graphic to the AbstractEntity are different, but besides the class name, and the specific graphic they pass they're all the same.

They call the initEnemies with their specific initNameofClass function, and pass to that a graphic, and then in turn the AbstractEnemy does the first global function that it will do only to all enemies and that is place them randomly on the screen. (This will be changed when we work on the AI in the next tutorial), and then that's it.

So without the names, and the specific graphics resource we give that specific instance it's no different than the player class.

now for the bullet class.

The Bullet Class
Since the bullet class is not an enemy, but just another entity like the player then we can still just use the AbstractEntity class, and extend it to save time and lines of code. Doing so we get the following class below;
package
{
	import flash.geom.Point;
	
	public class Bullet extends AbstractEntity
	{
		public function Bullet()
		{
			super();
		}
		
		//initialize the bullet
		public function initBullet(position:Point):void
		{
			super.init(ResourceManager.BulletGraphics, position, 0);
		}
		
		//shutodwn the bullet
		override public function shutdown():void
		{
			super.shutdown();
		}
		
		//update the bullet if we collide with an entity delete this bullet, and that specific entity
		override public function update(seconds:Number):void
		{
			position.y -= 10;
			
			if(position.y < 0) shutdown();
			
			if(super.Collided(this, EntityManager.Instance.greenBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.greenBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.blueBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.blueBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.smallBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.smallBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.bees))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.bees);
			}
			
			super.update(seconds);
		} 
	}
}



The following code above is precisely the same as the player class, and I'm hoping you guys and girls can see a pattern now, and see why having abstract classes are not only important but are a good thing! Saves me time! ;)

Now the only code we're really going to have to discuss here is the update function that we override from the AbstractEntity class.

We check for a collision and if we have a collision then we must remove the 2 that has collided, which will always be the bullet entity, and the entity that checks the collision on.

We use the removeEntity() function that we made in the EntityManager class, and now I'm sure you can realize why we named it the EntityManager class... ha ha... let's continue....
//update the bullet if we collide with an entity delete this bullet, and that specific entity
		override public function update(seconds:Number):void
		{
			position.y -= 10;
			
			if(position.y < 0) shutdown();
			
			if(super.Collided(this, EntityManager.Instance.greenBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.greenBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.blueBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.blueBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.smallBugs))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.smallBugs);
			}
			
			else if(super.Collided(this, EntityManager.Instance.bees))
			{
				EntityManager.Instance.removeEntity(EntityManager.Instance.bullet);
				EntityManager.Instance.removeEntity(EntityManager.Instance.bees);
			}
			
			super.update(seconds);
		} 



Woo! What is this...

super.Collided(this, Entity.Instance.blueBugs)



It's simply a class we added in the AbstractEntity class, and we simply pass it this specific entity the bullet entity with all 4 entities of the enemies. Now why do we do it here in the bullet class? Well, I have this huge crunch over saving time, money, and lines of code and realizing that we only need to check for collision with bullet and all enemies, and the player and all enemies instead of having a global class to check for a possible collision of an entity that doesn't exist we do it here only when it does exist. Does that make sense? :blink:

OK, when the bullet is instantiated it then goes through this cycle of update each time we redraw the screen, but when it no longer exist not only are we checking on a null entity that doesn't exist for a collision if we have this in another global class, but it's not needed, and possibly we can create an error, so what do we do?

We check to see when the collision check is needed. We then put the collision check function in a class that all entities will be using Hint: the AbstractEntity class and then we only check for the collision when we the bullet exist.

Now for the quick add of this collision detection that is in the AbstractEntity class.

Updated AbstractEntity Class
The only code we add is the function that checks for the collision, which is below.
//check for a collision between 2 entities.  Let the specific entities check this only when they're not null
		public function Collided(entityA:AbstractEntity, entityB:AbstractEntity):Boolean
		{
			var leftA:int = entityA.position.x;
			var leftB:int = entityB.position.x;
			var rightA:int = entityA.position.x + entityA.graphics.bitmap.rect.width;
			var rightB:int = entityB.position.x + entityB.graphics.bitmap.rect.width;
			var topA:int = entityA.position.y;
			var topB:int = entityB.position.y;
			var bottomA:int = entityA.position.y + entityA.graphics.bitmap.rect.height;
			var bottomB:int = entityB.position.y + entityB.graphics.bitmap.rect.height;
			
			if( (bottomA <= topB ) || ( topA >= bottomB ) || ( rightA <= leftB ) ||( leftA >= rightB )) return false;
			
			else 
			 return true; 
		}



The code above simply gets the precise points and sizes of 2 entities that is dealing with. We put these values in variables that describe what they are pertaining to a collision with that specific entities graphic. (i.e. why it's labeled leftA, leftB, ... bottomA, and bottomB respectively).

Then instead of checking for a collision, let's just check when there's not a collision that is when we know a collision can't possibly occur. if any of these return then we return false, for we are not colliding, else we can safely assume that a collision has been made, and we must clean up accordingly.

Now that we have all enemies, and bullets. Let's create this instances.

Instantiating Enemies
First we declare the variables
				//we create a variable like we did with the player.  
				public var player:Player;
		public var bees:Bees;
		public var smallBugs:SmallBug;
		public var greenBugs:GreenBug;
		public var blueBugs:BlueBug;
		public var bullet:Bullet;



and then we create an instance of each class.

					   //we create the instance of all enemies where we created the instance of the player  
					   player = new Player();
			bees = new Bees();
			smallBugs = new SmallBug();
			greenBugs = new GreenBug();
			blueBugs = new BlueBug();
			bullet = new Bullet();



and then we initialize those entities that are needed soon as the game start. Note: we do not initialize the bullet. No need for it.

					   //we then initialize all enemies when we initialize the player  
					   player.initPlayer();
			bees.initBee();
			smallBugs.initSmallBug();
			greenBugs.initGreenBug();
			blueBugs.initBlueBug();



NOTICE: We don't initialize the bullet in this class. That's because it's not needed, for it's only initialized when we need it, which is when the player hit's the spacebar key


now let's add the final piece for this tutorial that will bring this project to life. We must now edit the player class just a little, and create an instance of the bullet when we hit the spacebar key.

Edit Player Class
//give the player some movement
		public function keyHandler(event:KeyboardEvent):void
		{
			if(event.keyCode == 37) position.x -= 20;
			if(event.keyCode == 39) position.x += 20;
			if(event.keyCode == 32) 
			{
				EntityManager.Instance.bullet = new Bullet();
				EntityManager.Instance.bullet.initBullet(new Point(position.x, position.y - graphics.bitmap.rect.height));
			}
		}



When we hit the keycode of 32, which is the spacebar key we create an instance of bullet, and then we initialize it by passing it a position which is equivalent to our players specific position at that instance.

OK, we're done!

See what you have created now!
Posted Image

Conclusion

We have created the base class of all enemies, all enemies that are not bosses, put them on a random point on the screen, created the bullet class, and once the player hits the spacebar key we initialize that bullet and as it's existing and updating we check for a collision between that bullet and all enemies. If we collide with that bullet and any of the enemies we then remove those 2 specific entities, which collided. Well that is it for now I'm afraid, but no worries I can assure you that the next tutorial will be at least 2x as long as the previous tutorial, for we'll be working on special algorithms, and level ups, so be sure to tune in for the next tutorial in this series, but until then...

Happy Coding!

Source Code
Source Code

Was This Post Helpful? 0
  • +
  • -

#3 jkennedy  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 13-March 09

Posted 20 March 2009 - 02:39 PM

just a note that I'm learning a lot from the tutorial, thanks.
Was This Post Helpful? 0
  • +
  • -

#4 coden4fun  Icon User is offline

  • if(coden4fun.NotTired){ ContinueToCode(); }
  • member icon

Reputation: 27
  • View blog
  • Posts: 696
  • Joined: 27-February 09

Posted 21 March 2009 - 02:59 PM

you're definitely welcome. I'm currently critiquing my resume, and getting ready for and attending job interviews, but the series will pick back up when I'm done with the interviews.
Was This Post Helpful? 0
  • +
  • -

#5 jkennedy  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 13-March 09

Posted 21 March 2009 - 09:07 PM

dropped an email to your personal account, look forward to talking with you.
Was This Post Helpful? 0
  • +
  • -

#6 jkennedy  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 13-March 09

Posted 22 March 2009 - 12:36 PM

I have some work for you, but I need to talk with you today (Sunday 03/22), if possible - you can reach me at 301.801.4200 or john@amdi.com. Thanks.
Was This Post Helpful? 0
  • +
  • -

#7 wolfgang  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 28-March 09

Posted 28 March 2009 - 11:03 AM

just registered to say "thank you". w.
Was This Post Helpful? 0
  • +
  • -

#8 wolfgang  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 28-March 09

Posted 13 May 2009 - 09:24 PM

dear tutor.ial.
please, in the name of cod.e continue.
Was This Post Helpful? 0
  • +
  • -

#9 coden4fun  Icon User is offline

  • if(coden4fun.NotTired){ ContinueToCode(); }
  • member icon

Reputation: 27
  • View blog
  • Posts: 696
  • Joined: 27-February 09

Posted 31 May 2009 - 11:51 AM

View Postwolfgang, on 13 May, 2009 - 08:24 PM, said:

dear tutor.ial.
please, in the name of cod.e continue.


I start this tutorial again next weekend. I've been terminally ill with a much longer hospital visit than i had anticipated, but yes I will finish it soon, sorry for the inconvenience.
Was This Post Helpful? 0
  • +
  • -

#10 DirtyBill  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 13-June 09

Posted 13 June 2009 - 11:27 AM

Terrific tutorials, best wishes for a speedy recovery.
Was This Post Helpful? 0
  • +
  • -

#11 wolfgang  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 28-March 09

Posted 06 July 2009 - 05:27 AM

View Postcoden4fun, on 31 May, 2009 - 10:51 AM, said:

View Postwolfgang, on 13 May, 2009 - 08:24 PM, said:

dear tutor.ial.
please, in the name of cod.e continue.


I start this tutorial again next weekend. I've been terminally ill with a much longer hospital visit than i had anticipated, but yes I will finish it soon, sorry for the inconvenience.


Do we have to worry? Anyway, best wishes from
Wolfgang
Was This Post Helpful? 0
  • +
  • -

#12 skipperps  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 17-July 09

Posted 17 July 2009 - 02:52 AM

just wanna say thanks a lot. I hope you recover yourself soon and look forward to reading part V!
Was This Post Helpful? 0
  • +
  • -

#13 BuckO'Five  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 23-December 08

Posted 01 September 2009 - 02:23 AM

Thanks so much for the tutorials! They have helped me learn faster than i could have hoped for.

I hope all is well.
Was This Post Helpful? 0
  • +
  • -

#14 cabs  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 08-January 10

Posted 08 January 2010 - 03:07 AM

thanks for the nice tutorial :D

I have a question, would it be possible to trigger mouse events on every object in this game (for example clicking on the player ship or hovering over on the enemy bugs)?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1