8 - Pickups
Now that we have our little guy running around our map, lets give him something to pick up. We'll add some simple coins that will add to the player's score when they are picked up.
-
Open up your project in Ogmo again, and click
Edit Project
. -
On the
Entities
tab, add a new entity: -
Open up the level we used before, and, on the 'entities' layer, scatter a bunch of coins around:
-
We're going to make our coins be 8x8 pixels. For the coin's graphic, you can use this image , or make your own. Make sure you save this in
assets/images
. -
Get back into VSCode, and make a new
Coin
class:package; import flixel.FlxSprite; class Coin extends FlxSprite { public function new(x:Float, y:Float) { super(x, y); loadGraphic(AssetPaths.coin__png, false, 8, 8); } }
HAXE -
Now, head back to the
PlayState
. We need to change our map logic so that when it's loading the entities and sees a coin in our Ogmo file, it will add aCoin
object to our state. -
First, let's make a group to hold all the coins in. At the top of our class, where we defined all our variables so far, add:
var coins:FlxTypedGroup<Coin>;
HAXEGroups are like arrays of Flixel objects which can be used in a lot of different ways. In this case, since our group will only be containing coins, we will make it a
FlxTypedGroup<Coin>
.In
create()
, after we add our walls, and before we initialize our player, we need to initialize and add our coin group:coins = new FlxTypedGroup<Coin>(); add(coins);
HAXE -
Next, we just want to change our
placeEntities()
function to put a coin into our group every time it encounters one in our Ogmo file. At the end of our if statement, add:else if (entity.name == "coin") { coins.add(new Coin(entity.x + 4, entity.y + 4)); }
HAXEThis will simply create a new coin, tell it to be at the position defined in the Ogmo file (
+4
tox
andy
to center it on the tile), and add it to the coin group. -
Now we need to have the player be able to collect the coins. We're going to use an overlap check to do this. In
update()
, after yourFlxG.collide()
call, add:FlxG.overlap(player, coins, playerTouchCoin);
HAXEThis just says: every frame, check if there are any overlaps between the player and the coin group, and if there are, call
playerTouchCoin
. -
Let's add the
playerTouchCoin()
callback now:function playerTouchCoin(player:Player, coin:Coin) { if (player.alive && player.exists && coin.alive && coin.exists) { coin.kill(); } }
HAXEThis function simply verifies that the player and the coin that overlap each other are both alive and exist. If so, the coin is killed (we'll add the score a little later on).
If you run the game right now, as you walk around the map, each coin you touch will disappear. Works great, but it's a little boring… Let's add a little style!
-
Go back to your
Coin
class, and add these functions:override function kill() { alive = false; FlxTween.tween(this, {alpha: 0, y: y - 16}, 0.33, {ease: FlxEase.circOut, onComplete: finishKill}); } function finishKill(_) { exists = false; }
HAXEFirst, we
override
thekill()
function - normally, by calling.kill()
on an object, it will set both thealive
andexists
properties tofalse
. In this case, we want to setalive
tofalse
, but we don't want to setexists
tofalse
just yet (objects whichexists == false
don't get drawn or updated). Instead, we initialize aFlxTween
.FlxTween
is a powerful tool that lets you animate an object's properties. For our coins, we want to make it fade out while also rising up.We set the duration to
0.33
seconds, and we are using thecircOut
easing style, to make the tween look a little nicer. Also we want to callfinishKill()
when the tween has completed, which just sets the coin'sexists
property tofalse
, effectively removing it from the screen. By default, the tween type is set toONESHOT
so it is only executed once (instead of looping). You can change this by specifying a differenttype
in the tween options, but in our case the default behavior is just what we need.The type of the
FlxTween
complete callback isFlxTween->Void
(receives a singleFlxTween
argument and returns nothing). In this case, we named it_
to indicate that we don't care about it, which is a common Haxe idiom (other than that, there's nothing special about it - to the compiler it's just an argument named_
).
Try out the game now, and you'll notice the difference when you pick up coins! We'll do some more of this later on when we start adding 'juice' to our game.
In the next part, we'll talk about enemies!