Flixel Adventure Game Tutorial – Part 8: Picking up items

Index
Previous part: The Inventory

Previous part of the tutorial we have created an inventory system. Now, we will create an item in the world for the player to interact with and pickup. For the pencil we want to have a world-representation in the form of a character. The way Flixel handles sprite-sheets allows us to create a single 16 by 16 sprite that will be used for all the animations of our ‘character’.

Let’s create a ‘pencil character’, create a new private variable.

private var pencil:Character;

Instantiate the variable in the constructor.

// Item that can be picked up in the world
pencil = new Character(10,3, imgPencil, map);
foreground.add(pencil);

And add it to the characterList.

characterList.push(pencil);

For our pencil, we will have to add some dialogue to notify the player that he/she has obtained a pencil. Note that we use a strange notation for the first line, we will use the string later on as a command to add pencil to our inventory.

pencil.dialog = ["::addInv@Pencil", 
"*You have found a pencil.*"];

Add the following functions, these will be used to check for events and execute them.

// returns true if there is an event
private function checkLine(line:String):Boolean
{
	if (line.substring(0,2) == "::")
		return true;
				 
	return false;
}

If the first two characters of the dialogue-string are ‘::’, it will see that part as a function and use the part after the ‘@’ as the function’s arguments.

private function runEvent(line:String):void
{
	if (line.substring(0,2) == "::")
	{
	    // Check if the function has arguments.
		if (line.split("@")[1] != null)
		    // Execute function written in string with arguments.
			this[line.split("@")[0].substring(2)](line.split("@")[1]);
		else
			this[line.split("@")[0].substring(2)]();
	}
}

Now we will have to add this function to the two places where we get new lines for the dialogue, the start of a conversation.

// Change text to dialogtext.
dialogIndex = 0;
// Check for events and go to next line.
while ( checkLine(tempChar.dialog[dialogIndex]))
{
	runEvent(tempChar.dialog[dialogIndex]);
	dialogIndex++;
}
text.text = tempChar.dialog[dialogIndex];

And the second place, during the conversation, when the world is frozen.

// Else display next line
else
{
	// Check for events and go to next line.
	while ( checkLine(tempChar.dialog[dialogIndex]))
	{
		runEvent(tempChar.dialog[dialogIndex]);
		dialogIndex++;
	}
	text.text = tempChar.dialog[dialogIndex];
	}
}

Now we are able to write events in our dialogue and have them executed. Try running your game and you’ll see that you can ‘talk’ to the pencil in the world and have a pencil added to your inventory.

You can do this indefinitely, in order to solve this problem we’ll have to make the pencil disappear after it has been ‘picked up’. Let’s write a function that teleports Characters.

// Teleports a Character
private function tele(input:String):void
{
	tempChar.x = input.split(",")[0] * 16;
	tempChar.y = input.split(",")[1] * 16;
}

We’ll have to reference this new function in the text-array of the pencil dialogue.

pencil.dialog = ["::addInv@Pencil", 
	"::tele@-1,-1",
	"*You have found a pencil.*"];

We are teleporting the pencil to tile (-1,-1) because it is unreachable and not visible for the player.

Now you have learned how to make items that you can pick up and how to create functions that you can call by dialogue in our adventure-game engine. In the next part we will look into item-trading with characters.

You can download the code for this part here: Flixel Adventure Game Tutorial part 8 code.

Next Part: Item Trading

Join the Conversation

2 Comments

  1. WOW!!! The approach is pure genius! It took me a while to comprehend it, but I finally got it. THANK YOU for this wonderful tutorial!

    Btw, I would like to suggest an alternative method of removing an item from the foreground when it is picked up since I liked this personal approach better: since all items, npcs and the char are “Character” type, why not give each item a name, while the chars’ name would be null? like this:

    public function Character(x:uint, y:uint, image:Class, map:FlxTilemap, name:String = "")
    

    and then the obvious this.name = name;

    so that when we create a pencil we add an extra variable like “pencil”, serving as the item’s name:

    pencil = new Character(10, 3, imgPencil, map, "pencil");
    

    With this, in tele, instead of using an x and y variable in negatives, we could write the dialogue like this:

    "::removeFromMap@pencil",
    

    So the function removeFromMap will recieve a string that will be compared with the name of each char, and when found, then it is removed from the foreground:

    private function removeFromMap(name:String):void
      for (var i:int = charList.length - 1; i >= 0; i--)
      {
        if (charList[i].name == name)
        {
          foreground.remove(charList[i]);
          charList.splice(i, 1);
        }
      }
    }
    

    Hope it helps! 🙂

Leave a comment

Leave a Reply to Gabriel Reinhart Cancel reply

Your email address will not be published. Required fields are marked *