May 27th, 2011

Creating Your First ALPACA Game, Part 4: Inventory Items and Puzzles

Click here for part 1 of the Create your First ALPACA Tutorial

We’ve got our character, our environment, and our primary goal. Now we just need to add a simple puzzle and we’ll have a complete (albeit super bare-bones) game. The player needs to get a keycard in order to use the teleporter. We could just make a keycard and put it on the floor; this would be the same process as making the teleporter, except we’d have to give the keycard a “_G” tag in order to add it to the inventory (in other words, its instance name would be keycard_O_G, making it an obstacle and a Gettable object). But let’s make the first room a little more interactive instead. This will also give us an opportunity to create a Usable object.

Open up the room1 clip and add a new symbol to it. Design a keyframe dispenser within the symbol and give it the instance name dispenser_U within room1.

Up in the timeline, add two frames with the labels “closed” and “open.” Make sure to put the stop(); action on each frame as well. This will allow us to change the movie clip slightly once the player has used the dispenser. In my case I lit up on of the display lights on the dispenser to show that it had dispensed a keycard.

Add a usePoint at floor level in front of the dispenser. This is all you need to add, since the dispenser is not an obstacle.

Open up speechlines.js and add some lines about the dispenser so the player can interact with it.

Test your movie. Notice that, when you choose to use the dispenser, JaNET automatically moves to it and uses her grab animation. But nothing actually happens beyond this – and her “use’ line from the speechlines file doesn’t play. That’s because we need to add this special functionality within the Puzzle class. This will the be first real coding we have to do in our ALPACA project.

In your com/laserdragonuniversity/alpaca folder, open up Puzzle.as. Scroll down to the bottom of the main Puzzle function and add these two lines after allPuzzles = new Object;

allPuzzles.room1 = new Object;
allPuzzles.room1.usedDispenser = false;

This will give us a property we can use to tell ALPACA whether or not the player has used the dispenser. You’ll see how this plays out in a moment. Next, scroll down to the usedItem function. This will be called whenever the player uses any item with the _U tag in its instance name. In the switch statement, above the line that reads default:, add the following code:

case "DISPENSER":
var dispenser;
for (var i in Engine.usableItems){
if (Engine.usableItems[i].displayName == "DISPENSER")
dispenser = Engine.usableItems[i];
}
dispenser.gotoAndStop("open");
speech = new Speech(stageRef, dispenser, "use");
allPuzzles.room1.usedDispenser = true;
break;

What we’re doing here is locating the dispenser movie clip in order to control it (I was never able to find a more elegant way to do so than by scanning all the usable items for it, which is clunky, but it works). Then we’re switching it over to the “open” frame that we created earlier. After that, we set JaNET to speak the appropriate line, and we change the puzzle property we created earlier to reflect that the player has used the dispenser.

Test your movie. Now the dispenser changes when the player uses it, and we get the appropriate line.

EDIT: I totally forgot one thing – the keycard dispenser needs to become unusable once we get the keycard (since multiple keycards are of no use in this example). So add a couple lines of code to the block we’ve just edited, right before the break:

dispenser.usable = false;
dispenser.lookTag = "2";

The “lookTag” means that when we try to use the dispenser again, the engine will use the line “use2″ instead of “use” within speechlines.js. So add a line in the speechlines file under the “DISPENSER” block:

"use2":"I already got the keycard."

OK, there’s just one thing we’re missing – the keycard itself. First we have to make one.

Draw a keycard in a new symbol. Name it keycardProper and make sure to export it for Actionscript. Next, create a new blank symbol, call it keycardInv, and place keycardProper in it. This second symbol is the one that will appear in the player’s inventory – it’s a separate symbol in case you want to change the appearance of something after the player picks it up.

Now go back to Puzzle.as and add these lines to the switch statement we just edited, between the lines allPuzzles.room1.usedDispenser = true; and break;

var keycard = new keycardInv;
keycard.displayName = "KEYCARD";
inv.addInvItem(keycard.displayName);

This will create a new instance of the keycard and place it in the inventory when the player uses the dispenser. Test your movie. Now it works!

You’ll get errors if you try to use or look at the keycard in your inventory, because we haven’t set up any speechlines for it. Open up speechlines.js and add some.

Note the lines “useDISPENSER” and “useWINDOW” – those will tell ALPACA what to have JaNET say when we try to use the keycard with the dispenser and window, respectively. Right now you can’t use inventory items with each other, but it wouldn’t be too hard to add that functionality.

You’ll also note that if you leave the room and come back, the keycard dispenser goes back to its default (“closed”) state. We can fix this by adding the following code within Puzzle.as, in the newBackground function:

switch (thisBack){

case "room1":
if(allPuzzles.room1.usedDispenser){
var dispenser;
for (var i in Engine.usableItems){
if (Engine.usableItems[i].displayName == "DISPENSER")
dispenser = Engine.usableItems[i];
}
dispenser.gotoAndStop("open");
dispenser.usable = false;
dispenser.lookTag = "2";

}
break;

This method gets called whenever the player enters a new room. We’re making use of the usedDispenser property to maintain the change to the dispenser. You’ll want to do this for anything you change in a background as a result of player actions.

OK, now for the final step: creating a custom movie clip for when JaNET uses the keycard on the teleporter. Right now, nothing will happen if you try this. When you try to use an item on another item, ALPACA will check to see if there is a movie clip in the library pertaining to that action. Once we create it and name it properly, it will show up automatically when we play the game.

Create a new movie clip and name it action_KEYCARD_TELEPORTER (export for Actionscript, you know the drill).

Drag teleporterProper from the library into the clip. Now here’s the important thing: ALPACA will remove the player and the teleporter from the stage when this clip is activated, and replace it with the movie clip for the clip’s duration. That means that you need to make sure that the items in the movie clip are properly lined up, so the user doesn’t see a sudden jump when the movie clip starts.  To do this, open up teleporter (the version with the obstacle nodes in room2) and check the properties of theproper movie clip. Note its x and y value. Open up action_KEYCARD_TELEPORTER, select the teleporterProper instance, and set its x and y to those same values. This will keep it properly lined up with the teleporter in room2.

Test your movie. Now you can use the keycard, but JaNET just disappears and nothing happens.

That’s because ALPACA is replacing JaNET and the obstacle with our new movie clip, which only contains the teleporter. ALPACA is waiting for the movie clip to report back that the clip is finished with the ”clipFinished” event, and since the movie clip never sends that message, it will stay on the stage indefinitely. Let’s fix that.

First, let’s put JaNET in the clip. In teleporter, make note of the x and y values of the usePoint. Drag Player from the library into our new clip and set it to those x and y values. You’ll also need to apply a flip horizontal transform so she faces the right way. Put JaNET on a separate layer within the movie clip and use Modify->Break Apart to turn it from a symbol into a graphic (this is important – otherwise there will be more than one Player object in the scene and that will create a conflict). JaNET’s shadow will still be a movie clip, which is fine – place that on another layer behind her.

Break Apart the teleporter as well. Add a keyframe at frame 30 (two seconds, since the project is set to 15fps by default). Change the gradient in the middle to something brighter and glowy. Select the space on the layer between the keyframes and add a Shape Tween, so we get a nice fade from gray to glow.

On a new layer, add a glowy rectangle. Use shape tweens to make it expand outward and upward over the course of a few seconds.

Create a keyframe for JaNET in which she has floated up and rotated a bit into the glowy portal, then apply a Classic Tween in between the keyframes.

On the frame where she reaches the portal, make a big flash. Use shape tweens to make it start small and expand quickly, like an explosion. Play round with this animation (press Enter to preview it) until it looks like JaNET being drawn into the portal to your standards.

Now we need to add an actionPlayerspot instance from the library. Name the instance playerspot. This indicates where the player will be placed after the movie clip has ended. Since we’re ending the game after this clip, it doesn’t matter where we put it, but you should get in the habit of using it.

Our final step is to create an action layer, add a keyframe on the final frame, and then add the following lines of code on that keyframe:

stop();
dispatchEvent(new Event("clipFinished"));

Test your movie. It works, but JaNET just reappears at the position of our playerspot. We still need to add the code that ends the game here; back to Puzzle.as! In the performedAction functon, add the following within the switch statement:

case "[object action_KEYCARD_TELEPORTER]":
stageRef.dispatchEvent(new Event("endGame"));
break;

Once again, test your movie and solve the puzzle. Now we get a generic ending! Woohoo!

All you have to do now is spice up your opening and closing titles and you know have a (barely) functional game!

Play our sample game here. (The whole thing breaks mysteriously when I try to embed it here in WordPress. Something to look into, no doubt).

Download the full project files here.

All right, this concludes the basic ALPACA tutorial. At some point soon I’ll post some supplementary tutorials dealing with the other aspects of the engine, like the conversation system, and using audio for the speech lines.

52 comments to Creating Your First ALPACA Game, Part 4: Inventory Items and Puzzles

  • conan

    I have gotten to the point where you put the first lot of code in but I can’t get it so that the dispenser changes and the player says the use dialog. I have tried re-writing the code again and copy and pasting it but can’t seem to get it to work. Any ideas what I might be doing wrong?

  • Quinn

    Are you getting any error messages in your output window? Here’s what that entire method should look like at that point in the tutorial (forgive the lack of indentation, WordPress is weird about blockquotes):


    public function usedItem(thisItem:String):void{
    switch (thisItem){
    case "DISPENSER":
    var dispenser;
    for (var i in Engine.usableItems){
    if (Engine.usableItems[i].displayName == "DISPENSER")
    dispenser = Engine.usableItems[i];
    }
    dispenser.gotoAndStop("open");
    speech = new Speech(stageRef, dispenser, "use");
    allPuzzles.room1.usedDispenser = true;
    break;

    default:
    break;
    }
    }

  • conan

    I am not getting any errors. he is doing his use animation but no dialog and the dispenser isn’t changeing. do I need to export it for action script or something? I just have a yellow square that is red on the second fram. I labeled the frames closed and open. and gave it an instance name of dispenser_U.

  • Quinn

    That’s very odd. Why don’t you zip all your project files together (including the core ALPACA files) and send them to helpme@alpacaengine.com. I’ll take a look and see if I’m overlooking something.

  • conan

    I have sent you it. any help would be great.

  • Quinn

    Ah, I see the problem – you placed the code inside the newBackground method instead of the usedItem method. Since there’s no background called “dispenser,” it never got called. Once I cut and pasted the code into the usedItem method it worked fine.

    I like the look of your game so far – looking forward to seeing a finished product!

  • conan

    Ah very silly of me. thanks for the help!

  • Ryan

    Me again, I placed the line of code:

    var keycard = new keycardInv;
    keycard.displayName = “KEYCARD”;
    inv.addInvItem(keycard.displayName);

    Between allPuzzles.room1.usedDispenser = true; and break; however when I test the game I get an error saying

    “C:\Users\Ryan\Downloads\alpaca_source_2-0\source\blank_project\com\laserdragonuniversity\alpaca\Puzzle.as, Line 79 1180: Call to a possibly undefined method keycardInv.

    Also, by looking at the code, when we want to make our own game with our own objects how will we code it? Not everything in our games will be called dispenser. I’m referring to this line of code.

    “case “DISPENSER”:
    var dispenser;
    for (var i in Engine.usableItems){
    if (Engine.usableItems[i].displayName == “DISPENSER”)
    dispenser = Engine.usableItems[i];
    }
    dispenser.gotoAndStop(“open”);
    speech = new Speech(stageRef, dispenser, “use”);
    allPuzzles.room1.usedDispenser = true;
    break;”

    I have autism and learning difficulty’s so that’s why I always get stuck on coding.

  • Quinn

    No worries, ALPACA is still not as simple as I’d like it to be – hopefully the next release will be a step forward in that regard.

    For your first question, it sounds like you don’t have keycardInv exported for Actionscript. Check its properties and make sure that part is filled in.

    For the second, just swap out DISPENSER for the name of whatever item you’re using. The code on the top will find it out of all the interactive items in the scene. I should have just created a “find this symbol” method instead of reusing all that code – yet another thing for the next release!

  • Ryan

    Thanks that worked, however now when I click use keycard in my inventory the cursor just disappears and the game just sort of stops.

  • Ryan

    Wait, I managed to fix that. But now the problem is that once I have the object and left the room, when I return the dispenser is looking how it should. It hasn’t gone back to its default look but I still can get keycards from it.

  • Quinn

    Oops! I forgot to deal with that. Thanks for the heads up. I’ll update the tutorial.

  • Ryan

    Where in the tutorial does it explain how to fix it?

  • Quinn

    Sorry, haven’t added it yet. Look for a big “edit” next to the section once it’s up.

  • FrankStein

    how can i change the background if i use an item??

  • Quinn

    @FrankStein Do you mean switch to a new background, or change something about the current background?

  • FrankStein

    switch to a new background

  • Quinn

    In the usedItem method in Puzzle.as, add your item to the switch statement, set Engine.newBack to the room you want to switch to, and then dispatch the changeBackground event to the stage. It’ll look something like this:


    public function usedItem(thisItem:String):void{
    switch (thisItem){
    case "myitemname":
    Engine.newBack = "thenameofthenewroom";
    stageRef.dispatchEvent(new Event("changeBackground"));
    break;
    }
    }

  • FrankStein

    thanks =>

  • quinn

    How do I do dialogue? Is there a way I can have a two-way dialogue where the character speaking has a portrait pop up while they’re saying their lines?

  • Quinn

    I’ll do a dialogue tutorial at some point, but for right now check out the dialog documentation for an overview. There are no portraits right now but you could add them by editing the code in the Dialog and Subtitle classes (Subtitle contains the code that formats the onscreen text when characters talk, so you’d add your portrait code there).

  • quinn

    Thanks a ton~

  • Steve

    HELP! I cant seem to use my keycard on anything and when I grab it from inventory it just sticks to the cursor.
    what am I doing wrong?
    I even copy pasted the same code from the my_first_alpaca puzzles thingy.

  • Steve

    oh wait I did a little bit of tinkering with the placement of the centre point in each of the keycards, works fine now. nevermind lol

  • Quinn

    Good thing to note – your inventory items need to have their registration points in the middle, because when you click to use it with something, you need to click the inventory item, not the background, for the code to work.

  • Steve

    hey I am working on a new game now using ALPACA, great engine by the way! just wondering how to incorporate a map element. like in “the secret of monkey island.” I have photoshop so I am able to draw some sweet maps. any clues on how to make it work?

  • Quinn

    I suppose you’d want to make a Map class, and associate it with a movieclip containing your map. Then set up some basic click functionality that takes you to whichever point on the map you select. The code to change the background looks like this:
    Engine.newBack = "thenameofthenewroom";
    stageRef.dispatchEvent(new Event("changeBackground"));

    I don’t think there’d be much more to it than that!

  • Steve

    thats awesome Quinn thanks very much, I’ll give it a try and let ya know how it goes
    =-)

  • Steve

    hey Quinn its me again, do I put this code into puzzles or engine?
    Engine.newBack = “Map”;
    stageRef.dispatchEvent(new Event(“changeBackground”));

  • Steve

    the main trouble I am having is, the map is something that I pick up in one of the rooms, then I would like to be able to use it from my inventory. just not sure how to make inventory item work as an EXIT as such.

  • Quinn

    Sorry if I was unclear – you don’t want to set the map as the new background. That’s the code you’ll use WITHIN the map in order to set a new background. The map should be a custom class (and associated movieclip) with its own code. You’ll probably want to write a new class entirely for it. You’ll also need to modify the useThing method in the UseBox class (line 89). Right now it runs a check for if the target item is in the inventory, and creates a draggable item if it is. You’ll want to add an exception if the item is the map and have it bring up the map class instead.

    If you don’t want to write a new class, you could probably just make the map movieclip and add all the functionality on an actions layer. I don’t think it would be able to talk directly to the Engine class, so you would need to have it dispatch a “destinationSelected” event or something and set up the Engine to respond to that.

  • Steve

    thank-you so much, I’m relatively new to this, this will be my 1st game ever made.

  • Steve

    hey Quinn, sorry I’m such a pain. do I create my Map class in the same style as all the other ones in “com.laserdragonuniversity.alpaca/(class name here) ie. Map?

    also with changing the UseBox (line 89) I am having trouble with how to actually make the exception I want.

    I have tried a few ways but none are quite right, would you be able to figure out the code I need to continue?

  • Steve(the Noob)

    just been playing around with this a bit more. just wondering how to have the game start with inventory items already loaded into it? for instance a sword or a map.

  • Quinn

    If you’re having trouble creating classes, I’d recommend these tutorials, particularly the “Avoider” game you build with them: http://www.foundation-flash.com/tutorials/index2.php

    Doing a simple game from scratch will help you get a more solid knowledge about how classes work and communicate with each other in Flash – it’s definitely worth it.

  • Quinn

    In the firstAction method in Puzzle, you’ll just want to create new instances of the inventory items, give them display names, and then simply add them to the inventory. Here’s what the code from the sample project looks like that gives you the balloon out of the box:
    balloon = new balloonProper;
    balloon.displayName = "BALLOON";
    inv.addInvItem(balloon);

  • Steve(the Noob)

    hey man thanks very much, I managed to make a weapons inventory and class, followed the code from the existing inventory, then changed all the inv strings to wpn strings and set up the engine to respond to a new button on the tool-bar. I think I’m finally getting the hang of it now. =-) I could send you the game when I think its good enough if you want to check it out. might be a few weeks work before its a real DEMO as such though. I’ll keep in touch, thank-you so much for your help.

  • Quinn

    Glad things are working for you, and I’d love to see the game once you have it running. I’d really like a gallery of ALPACA games to put on the site so people can see more than just my demo.

  • Sean

    Hi There

    For the life of me I cannot get my character to use the dispenser. I’m stuck at the point just before you make your keycard. I also made the initial mistake of entering my code in the newBackground method, but even fixing that doesn’t resolve my problem. I can look at the dispenser, but if I click to use it, my character just walks to it.

    Any thoughts?

  • Quinn

    Do you get any errors in the output window when you try to use the dispenser? Does your character say a line when they get there? After they get there, are you still able to walk around and look at things like normal?

  • Sean

    Hi Quinn

    If I click on my dispenser, I get the line if I select ‘LOOK”.
    If I click on ‘USE’, my character walks to the usepoint but nothing happens… no interaction, no line.
    I can still carry on after this (move around in game, look at other things).
    I’m honestly baffled. I have looked at your sample code from the project, and cannot spot any difference in the code. My only thought is that I have actually created my dispenser wrong.

  • Quinn

    Are you sure there aren’t any typos in your speechlines file? Try opening up the UseBox class and uncommenting the trace statements in the manipulateThing method. Those should show up in your output window and tell you if the game is at least trying to interact with the item. If you try that and don’t see any output, then something isn’t working in the reachedThing method. Maybe try creating a new gettable item from scratch and see if you have the same problem.

  • Sean

    me again. Thanks for your assistance so far…

    I uncommented the trace statements… no output in window. The I tried creating another simple gettable item ( a piece of string with a single frame in a single layer, instance name string_U, updated the speech file… ). When I test it, I get my text line when I LOOK at it. If I click on use, my character walks over… and nothing further. No text, no movement, no error.

    I even went so far as to copy over directly the rock from the tundra scene in the sample game, and updated the speech file for the rock speech. Nothing.

    Please help me.

  • Sean

    Ignore my previous post. I found my mistake.
    I forgot to put the line

    parent.dispatchEvent(new Event(“clipFinished”));

    in my character’s grab animation.

    Thanks for a great tutorial, and even better support. Hopefully I can finish my game now.

  • Quinn

    Glad you figured it out! Yeah, the clipFinished event is a real pain – I had issues getting Flash to recognize that the clip was finished otherwise, but that’s definitely something to revisit.

  • David

    Hello, it’s me again, Taiwanese (H)

    here’s are two question.

    1.How can we combine two items to single item?
    2.How can I type the CHINESE in the dialoge?

    Thanks you!!!(K)

  • Quinn

    1. You can’t, in ALPACA’s current version. You’d need to customize the Inventory and DraggedItem classes so that the inventory doesn’t disappear when you use one if its items, and go from there. A few people have asked about this, so I’ll be sure to add it to the next release.
    2. Um…good question! I’m really not sure. I guess you’d have to set your Flash font to a Chinese font (in any class that uses text, and be sure to export it in the Flash Actionscript settings); JSON should be able to handle Chinese characters as long as the file is UTF-8 encoded, although I’m not sure if the JSON decoder I’m using will be able to parse them, since I’ve never tried it. You might want to ask someone who’s more knowledgable about Flash and non-Western characters. Sorry I can’t be of more help!

  • Manfred

    Hello from Germany!
    I really like ALPACA. Following this tutorial i found a small glitch. After adding


    dispenser.usable = false;
    dispenser.lookTag = "2";

    you get an error using the keycard on the dispenser. To correct this you change in “speechlines.js” the lines


    "KEYCARD":{
    ...
    "useDISPENDER":"bla",
    ...
    }

    Correct:


    "KEYCARD":{
    ...
    "useDISPENDER2":"bla",
    ...
    }

    This will do the trick, but seems kind of incorrect?!

    Regards

    Manfred

  • Quinn

    @Manfred – that’s actually how things work right now with the lookTag, even if it looks a little strange :) Thanks for catching that!

  • Andrey

    Hi, I would like to know if its possible to change the talk options in a dialog according variables of puzzle.

    ty in advance

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>