Collision / World Class


(I'll tell you what I want, what I really really want) #21
    package  
{
	import Enemy.BackdropBG;
	import Enemy.blue_block;
	import Enemy.Pill;
	import Enemy.Snow;
	import Enemy.WallOne;
	import net.flashpunk.Entity;
	import net.flashpunk.FP;
	import net.flashpunk.graphics.Image;
	import net.flashpunk.graphics.Text;
	import net.flashpunk.tweens.misc.VarTween;
	import net.flashpunk.World;
	/**
	 * ...
	 * @author PawelBetkowski
	 */
	public class LevelOne extends World
	{
		
		[Embed(source="../assets/redbg.png")]
		protected const LEVEL_ONE_BG:Class;
		
		protected var _timeLeft:Number = 0;
		
		protected var _levelCount:Text;
		
		protected var _instruction:Text;
		
		var bullet:Bullet;
		private var _pill:Pill;
		


		
		public function LevelOne() 
		{
			super();
		}
		
		override public function begin():void 
		{
			
			Text.font = "czcionkaDWA";
			
			_levelCount = new Text("1/20", 710, 510);
			_levelCount.size = 50;
			_levelCount.color = 0xFFFFFF;
			
			_instruction = new Text("He has to stop, he has to make pills disappear");
			_instruction.size = 50;
			_instruction.color = 0xFFFFFF;
			_instruction.centerOrigin();
			
			
			FP.screen.color = 0xFFFFFF;
			add(new BackdropBG());
			
			addGraphic(_levelCount);
			addGraphic(_instruction, 0, FP.halfWidth, 40);
			
		
			// Gracz			
			add(new Player(400, 300))	
			add(new Pill(400, 400));
			
			//Walls
			add(new WallOne(364, 332));
			add(new WallOne(402, 332));
			add(new WallOne(332, 300));
			add(new WallOne(436, 300));
			add(new WallOne(300, 268));
			add(new WallOne(468, 268));
			add(new WallOne(268, 236));
			add(new WallOne(500, 236));
			
			add(new blue_block(400, 200));	
	}
	override public function update():void 
	{
		super.update();
		
		 if  (bullet.collide("pill", bullet.x, bullet.y))
		{
			FP.world = new Menu1;
		}
		
		
	}

}
}

(Justin Wolf) #22

Okay, various problems I can see.

  1. Define your bullet object as private var bullet:Bullet;
  2. bullet never actually gets set or created in your World class, as you stated before. Where are you running the functions that check for your Input?

It looks like you’re going about this in an unusual way that’s likely making it a lot harder for yourself.


(I'll tell you what I want, what I really really want) #23

In my player’s update. Because the bullet is being created where player’s x and y is.


(Justin Wolf) #24

Let’s just remove that bullet collision check from your world completely. You should handle its collision inside your actual Bullet class, in its own update loop. So inside your Bullet class’ update, add:

if (collide("pill", x, y)) FP.world = new Menu1;

However, I imagine you’ll have some other problems because according to your code you’re constantly creating a new bullet every update tick, assuming that this post is all contained within your update. You’ll want to move the var bullet:Bullet = new Bullet(x-3, y); line inside each Input check so that new bullets only get created when you release one of the appropriate keys:

var bullet:Bullet;
if (Input.released(Key.S))
{
        bullet = new Bullet(x-3, y);
	world.add(bullet);
	bullet.fire(0, 5);
}
if (Input.released(Key.W))
{
        bullet = new Bullet(x-3, y);
	world.add(bullet);
	bullet.fire(0, -5);
}
if (Input.released(Key.A))
{
        bullet = new Bullet(x-3, y);
	world.add(bullet);
	bullet.fire(-5, 0);
}
if (Input.released(Key.D))
{
        bullet = new Bullet(x-3, y);
	world.add(bullet);
	bullet.fire(5, 0);
}

(I'll tell you what I want, what I really really want) #25

See, the problem is, I only want the bullet to get me to the next world in this level. In next level, it might be 3 pills destroyed, in the next one, it might be something else. That’s why I thought I need to do it in the world’s update.

Even if I write this in bullet’s update:

if (collide(“pill”, x, y)) FP.world = new Menu1;

it’s not working.

Is there no way I can create an event inside of the world’s function using entity’s properties?


(Ultima2876) #26

This is a good thing for inheritance to handle. Create a Base World Class (Lets call it BaseWorld) that defines a base function:

public class BaseWorld
{
  public function destroyedAPill(): void { }
}

Then you want to extend (or inherit from) that class in all your level worlds;

public class MyWorldClass extends BaseWorld
{
  // ...
}

You can use something like (FP.world as BaseWorld).myFunction(); to call myFunction() in any world that extends BaseWorld. So, something like (FP.world as BaseWorld).destroyedAPill();, which calls destroyedAPill in your current world (as long as it extends BaseWorld!), a function you might define like so (in your actual world class):

public override function destroyedAPill(): void
{
  // We destroyed a pill. In this world, we want to advance straight away!
  FP.world = new World2; // when you make World2, make sure to remember to extend BaseWorld!
}

Remember you have to define the base function in BaseWorld!

So how does it work? When you do (FP.world as BaseWorld).myFunction(); you’re saying ‘We know that FP.world, the current world, extends BaseWorld. Anything that extends BaseWorld definitely has the myFunction() function, because BaseWorld has that function. We want to call the version of that function that corresponds with whatever world is currently active’. This is powerful. This means that every world can define its own ‘override’ of destroyedAPill and handle it differently. They could change the world. They could check if 3 pills have been destroyed. They could create new pills; they could print some text to the screen! Whatever you want to do in each world.

Another way to handle this would be to simply have a counter in the world - make a public variable called ‘pillsNeeded’, then you can do (FP.world as MyWorldName).pillsNeeded within any Entity class to get the number of pills needed to advance. Not as exciting as inheritance… but maybe a bit easier (but definitely not as flexible either!)


(I'll tell you what I want, what I really really want) #27

should the BaseWorld extend World or should it be an empty class?


(Ultima2876) #28

BaseWorld should extend World :slight_smile:


(I'll tell you what I want, what I really really want) #29

@Ultima2876, you inspire me. I can feel it will work.

but there’s a problem,

	if (_bullet.collide("pill", _bullet.x, _bullet.x))
	{
		(FP.world as BaseWorld).DestroyedPill();
	}

still cannot access that property in the first line.

Is this even the correct way to handle entity’s collision in world class?

Maybe because my bullet is created when player fires, and it’s written in player’s entity and not in the world itself?


(I'll tell you what I want, what I really really want) #30

So I did it the easier way with the var and stuff, and it works! Thank you so much @Ultima2876!

One question tho, when I write this:

FP.world = new Level2();

it works, but when I write this:

			var newWorld:World = new Menu1();
			var oldView:Image = FP.screen.capture();
			oldView.relative = false;

			var e:Entity = newWorld.addGraphic(oldView, -200);

			var fader:VarTween = new VarTween(function():void { newWorld.remove(e);}, ONESHOT);
			fader.tween(oldView, "alpha", 0, 2);
			newWorld.addTween(fader, true);

			FP.world = newWorld; 

It doesn’t. Anyone knows why?

EDIT: And now, It works once, then I run program again, and it doesn’t. What is going on.


(Jacob Albano) #31

What do you mean by “it doesn’t”? What doesn’t work?


(I'll tell you what I want, what I really really want) #32

It works, what I mean is when the bullet collides with pill it should take me to the next world as it is in the if statement, but it only does once for let’s say 3 times I turn “the game” on.