Adventure: All in the Game Code Snippets

These are just a few pieces of code I came up with or was thoughtfully provided with while working on this game. I'm posting them here in the hopes that others might find them useful in some way.

When Thalia talks while she is standing in a different pose (e.g., with her arms folded or with her hands on her hips), I tried to decrease the amount of sprites I'd have to create and use by taking a leaf out of LucasArts' book: I have an character with a view composed of invisible sprites locked to Thalia, and when she starts talking in a different pose, I have the invisible character switch to a view consisting of just Thalia's body while Thalia switches to a view consisting of just her head. This way, I don't have to import lots of new frames every time I want Thalia to talk in a certain pose -- I just import a single frame of her body in the pose I want her to be in. Here's a sample script from the intro:

player.ChangeView(38); //head
player.SpeechView=38; //head
cThal_small_xtra.ChangeView(36); //normal view
cThal_small_xtra.Animate(11, 3, eOnce, eBlock); //folds arms
cThal_small_xtra.LockViewFrame(36, 12, 0); //arms folded, body only
player.Say(" Yes, sir. ");
//[tlotzin's CommKey conversation]
cThal_small_xtra.UnlockView();
cThal_small_xtra.ChangeView(36); //normal view
cThal_small_xtra.Animate(13, 3, eOnce, eBlock); //unfolds arms
cThal_small_xtra.ChangeView(40); //invisible view
player.ChangeView(36); //normal view (head AND body)
player.SpeechView=37; //normal view (head AND body)

One of many things I was wrong about while working on this game was thinking that saving the idle views for last would be a good idea, since I wanted to get the bigger stuff done first.

As it turns out, the idle animations turned out to be a little bigger than I anticipated.

After the several days that it took to animate new idle views were over (since I wasn't satisfied with the ATIJ idle views), I tried to figure out a way to get AGS to play multiple, randomizing idle animations. Again, this was something that wasn't nearly as piffling as I thought it would be. I tried SSH's Idle Module, but to my chagrin, it caused some less than desirable glitches (e.g., getting Thalia stuck in an idle view's loop so that if I tried making her walk anywhere, she would remain in that position and "glide" across the screen instead of walking). I scoured the forums looking for an alternative, and finally, I attempted to come up with a solution on my own.

To my astonishment, I was able to do so:

if (thalia_idle==true && player.Animating==false) {
  IdleTimer++;
  if (IdleTimer>=400) {
    if (player.View==36) {
      thalia_idle_sm(); //small svga
        }
    else if (player.View==1) {
       thalia_idle_lg(); //large svga
        }
    else if (player.View==86) {
      bb_idleview(); //billy-bob
        }
     else player.SetIdleView(-1, -1); //if not in svga
    }
  }
else IdleTimer=0;

if (thalia_idle==false)  {
  player.SetIdleView(-1, -1); //idle off
}
The only problems I encountered were:
A) Having to manually adjust every single idle view frame's speed so that Thalia didn't move as if she had slipped into slow motion

B) One view which just animates Thalia blinking caused her to face up, down, right or left if that view started animating while she was at a diagonal angle. Adding enough frames to the blinking view so that it had roughly the same amount of frames as the other idle animations solved this problem, but it had me stymied for some time.

(Also, I often found that the thalia_idle=false command didn't seem to work, so I had to enter player.SetIdleView(-1,-1); instead.)


I tried to implement a slider to control Thalia's walk speed, but I was unable to get it to work properly. However, FamousAdventurer77 gave me an idea for an alternative. I was hoping to implement a feature where double-clicking on the screen would make Thalia teleport to the Walk cursor's location, but all the methods from the AGS forums that I found resulted in making the game hang whenever the Walk cursor was clicked. I decided to make the "teleport" feature active when the player holds down the Spacebar instead (this all goes under on_mouse_click):
if (mouse.Mode==eModeWalkto && IsKeyPressed(eKeySpace) == 1) {
   //if Walk cursor is selected and player is pressing the spacebar
    if (mouse.IsButtonDown(eMouseLeft)) {
   //if player presses left mouse button
    player.x=mouse.x;
    player.y=mouse.y;
    player.PlaceOnWalkableArea();
   //make Thalia's coordinates the mouse's current coordinates
   //AND place her on nearest walkable area
      }
}

How did I create the highlighting cursors for this game?

The answer to that question is both simple and complicated. For the Look, Touch and Talk cursors, making them highlight when over a hotspot, object or character was easy. I'll start with the Look cursor as an example. First, you need to create two images for each cursor: highlighted and unhighlighted.

Next, import those sprites into AGS, create a view and set Frame 0 of Loop 0 as the cursor's highlighted image. Make the Look cursor's grayed-out image its default graphic. Then, set both the cursor's Animate and AnimateOnlyOnHotspots settings to true and put the number of the View you made in the previous step in the View field. Since there is only one Frame in the cursor's View, it will appear as a static image while it is animating. This should make the Look cursor appear as a grayed-out eye when it isn't on a hotspot, object or character, then change into a sharp black and white eye when it is.

Making highlighting cursors for the inventory items is a bit harder, however. The first thing to do is to make sure the "Use selected inventory graphic for cursor" setting under General Settings is set to False. The cursor used when selecting an inventory item should be set up in a way similar to the Look cursor, but since this one cursor will be used for all of the inventory items, additional steps need to be taken.

For this example, I'll be using the CommKey. The following code should be inserted under repeatedly_execute in the Global Script:

if (player.ActiveInventory == icommkey) {
//if the commkey is the selected item
  mouse.ChangeModeView(eModeUseinv, COMM);
    //change the mouse's view to the selected inventory cursor,
    //use the commkey's animating view
}
You will need to insert similar code for all the inventory items (it may be tidier to put them all into a seperate script which is called in rep_exec), and you'll also have to create a seperate View for each of them. It is a bit tedious, but if you want to go that extra step in creating a really slick interface, it's well worth it.


Here's another handy bit of inventory-related code, courtesy of Khris from the AGS forums (Note - "Handle inventory clicks in script" needs to be set to true for this to work!):
if (gInv.Visible && (button == eMouseLeft || button == eMouseRight)) return;
//prevents objects on screen from reacting to player clicking inv items on them
  
  InventoryItem *clickedItem = inventory[game.inv_activated];
 
   if (button == eMouseLeftInv)  // left click on inventory item
  { 
    if (mouse.Mode == eModeUseinv && player.ActiveInventory != null)
    {
      if (player.ActiveInventory == clickedItem)
       //deselect the inventory item when clicking on itself
      {
        player.ActiveInventory = null;
        mouse.Mode = eModeTouch;
      //^ Change this to whatever default for mouse.Mode should be when inv is deselected
        mouse.ChangeModeGraphic(eModeTouch, 34); //arrow cursor
      }
      else clickedItem.RunInteraction(mouse.Mode);
      //run the inventory on inventory interaction
    }
    else if (mouse.Mode == eModeTouch)  //select inv item
    { 
      player.ActiveInventory = clickedItem;
    }
    else if (mouse.Mode == eModeLookat)  //look at inv item
    { 
      clickedItem.RunInteraction(eModeLookat);
    }
    else if (mouse.Mode == eModeInvtouch)  //touch inv item
    { 
      clickedItem.RunInteraction(eModeInvtouch);
    }


Back to Adventure: All in the Game