A state-based Player

A random idea. It’s pretty simple to create a player with different animations and facings using swap to change to a different player tile. But what if your game has different modes? The example that immediately comes to mind is an RPG where you may have a town, overworld, battle, and menu modes. Keeping track of which mode you're in inside every event handler on the player can get out of control quickly.

So here’s that random idea:

on any do
    mimic “player {player_state}”
end

That’s it. That’s your player’s entire script.

One more piece of plumbing. Set a default value for player_state in the game’s load handler. eg. player_state=“town”.

Now create a new Sprite tile for each state in your game. We’ll start with “player town”. When player_state is set to “town", the “player town” tile will handle all the player's events. Because we’re not using swap the player still draws itself. Let’s fix that by adding this to the script for “player town”:

on draw do
    hide
    draw “{event.tile}” at event.px,event.py
end

Maybe your player uses a different sprite in town than it does on the overworld (maybe it’s two tiles high). Maybe in town you draw a hud showing how much gold you have to spend at shops. Maybe on the overworld a different hud shows hit points remaining. Maybe in battle the player isn’t even drawn, instead you draw hit and magic points remaining, turn order, visual effects on critical hits, etc. This idea can be extended to other Player event handlers like enter, exit, update, confirm, cancel, etc.

I guess the point is, this doesn’t all have to live in the Player tile’s script. There are clever ways to organize your logic to make things a little more manageable.

7 Likes

I’m trying to do this, but when I move this code from my player script to my sprite script it leaves a permanent trail of images behind the player.


on update do
	if event.dx==-1 then
		swap "Charlie right"
	elseif event.dx==1 then
		swap "Charlie left"
	elseif event.dy==-1 then
		swap "Charlie up"
	elseif event.dy==1 then
		swap "Charlie down"
	end
end

I’m not entirely sure why it breaks, or the best way to fix it.

I suspect swap is being called on the tile your player is currently on, rather than the player themselves.

Try wrapping the swaps like this maybe?

tell event.player to
  swap "Charlie ..."
end
1 Like

Thank you for this. I had tried to use tell before, but forgot the event.player, and was just using player. Oops