Coin Event and changing World [SOLVED]


(Massimo) #1

Hi gentlemen! :smiley: I’m looking for an Entity object that, after collecting all the same entity inside of the same level, allow you to swap to a different World.

For now i’m cooding these:

package {
import net.flashpunk.Entity;
import net.flashpunk.graphics.Image;
import net.flashpunk.FP;

public class Coin extends Entity
{
	[Embed(source = "../assets/moneta pinco.png")]
		private const MONETA: Class;
		
		private var n:int = FP.world.classCount(Coin);
	
		public function Coin(posx:int, posy:int)
		{
			
			graphic = new Image(MONETA);
			setHitbox(30, 30);
			type = 'coin';
			x = posx * 20;
			y = posy * 20;
			

		}
		override public function update():void
		{
			if (collide('player',x,y))
			{
				n --;
				FP.world.remove(this);
				if (n==0)
				{
					FP.world = new W_gameplay();
				}
			}
		}
} }

But, obviously, it doesn’t work! Somebody know why?


(Brad Davies) #2

Its most likely due to the private var n:int = FP.world.classCount(Coin) part.

Instead of the local private variable, use a static private variable, so replace that with

private static var coinCount:int = 0;

Then, in the Coin constructor, after y = posy * 20; have the coinCount increase coinCount++;.

And then, every time the player “collides” with a coin, just reduce the coinCount coinCount–;. Then, if the last coin is removed, coinCount==0 will be true, and you can change the world.

EDIT: Alternatively, there is a very simple method which works too without the need for all this tracking of coinCount.

Instead of checking that n==0, just check if FP.world.classCount(Coin)==0, then you know all coins are gone from the world! Easy!

EDIT 2: Trimmed class code;

package
{
import net.flashpunk.Entity;
import net.flashpunk.graphics.Image;
import net.flashpunk.FP;

public class Coin extends Entity
{
	[Embed(source = "../assets/moneta pinco.png")] private const MONETA: Class;

	public function Coin(posx:int, posy:int)
	{
		super(pox*20,posy*20,new Image(MONETA)); setHitbox(30,30);
		type="coin";
	}

	override public function update():void
	{
		if (collide("player",x,y))
		{
			FP.world.remove(this);
			if (FP.world.classCount(Coin)==0) FP.world = new W_gameplay();
		}
	}
}
}

(rostok) #3

Option with classCount is much better as static variable will count all the coins in all the levels. Note that one can create and setup levels right at the game start.


(Brad Davies) #4

It depends on how his internal game structure and classes are setup. It is possible to setup all your levels at the start of the game, but you don’t need to.


(Massimo) #5

Sorry folks, but this method does’t change anything! Meybe is something that should be added in the same world rather than the entity itself?


(rostok) #6

Post your code so we can examine it. If you choose static var option you should increment it in the overloaded added() method to make sure it is actually in the world.


(Zachary Lewis) #7

Not so fast! Even though you called remove() before you checked for classes, the remove() function doesn’t instantly remove the entity — it only marks them for removal. The last step of the game loop is to check for any entities marked for removal and then remove them.

Since World.classCount() returns the number of entities of a given class that remain, you’d have to wait until the next update for the number to reflect your actual count.

Well, that makes sense. I’ll just check FP.world.classCount(Coin) == 1 and call it a day!

Not so fast! If the player collects multiple coins during the same update, the same issue will arise!

Alright, brainiac, just tell me how to do this thing.

I’d recommend performing your collision in your game world (or, at the very least, your check).

override public function update():void
{
  // What coins did the player collect this update?
  var collectedCoins:Vector.<Coin> = new Vector.<Coin>();
  player.collideInto("coin", player.x, player.y, collectedCoins);

  if (collectedCoins.length > 0)
  {
    // Yay player! You got some coins!
    for each (var collectedCoin:Coin in collectedCoins)
    {
      // Remove the coins, play a little song, whatever.
      collectedCoin.collect();
    }
  }
  else
  {
    // The player didn't get any coins. Maybe they're all collected!
    if (classCount(Coin) == 0)
    {
      // The player beat this stage! Good job!
      FP.world = getNextLevel();
    }
  }
}

(Massimo) #9

Ok ok, i know, i’m a n00b! But i can’t understand a couple of things:

  • I suppose that i have to create a function called ‘collect’, because without the code is wrong!
  • How i can get and then pass the player class position to the world class?
  • Maybe i have to include some more library than net.flashpunk.World and net.flashpunk.FP?

After that thanks, it’s seems to fit and the “lesson” was interesting!


(Zachary Lewis) #10

Yeah, you’ll need to write that function in Coin. Have it do something fun like fade out and play a sound effect.

Just save a reference to your Player in your game world.

private var _player:Player;

_player = Player(add(new Player()));

trace("The player is currently located at", _player.x, player.y);

You’ll need to include any classes you use, like Player and Coin.


(Massimo) #11

Ok, i had fixed some little issues, but now, inside the code, it can’t recognize the “collide” function, even if i imported Entity :open_mouth:

This since i included the code that you suggested to me! No one know why?

Sorry for all the question!


(Massimo) #12

Ok, i’m REALLY a n00b ._____________.

I missed a brace to the end of the update function! Well, problem solved! Now i have another big problem… Mhè!

Practically at the start of the game appears instantly the W_GameO world (the game over screen) and when i put the ok key restart as he have to do with the W_gameplay… BUT! But the plyer stay freezed -.-

Haaa… guess what: anyone know why?