Tutorial 04: Changing rooms and inventory

What you learn in this tutorial

  1. How to create two rooms and change them in game using door.
  2. Creating items to the scene
  3. Creating inventory and using items in scene
  4. Very basic “Old use key to the door” -ploy

Introduction

This tutorial assumes you have a copy of 3D Studio Max installed in your system, and you have downloaded Starting Tutorial File and extracted it to folder, which we refer with (Dage)\

Also these tutorials assumes you have basic knowledge how to find things in 3D Studio Max, like property editor, material editor, etc.

It is recommended you have already took the previous tutorials.

Preparation of the scene

Let's look at the starting tutorial file.

There is our lonely guy in a room, where there is a door and a crate. You can do nothing much, but to walk around.

Identifying objects the room

First we want to create a way for player to identify objects in game.

We use TDummy objects to create invisible boxes. If user hovers mouse or clicks inside the boxes, we want to give feedback of players actions.

Place in roomscripts.txt file following lines in the end of file.

function onRoom01Load()
   mtDoor = TDummy.Create();
   mtDoor.SetPosition(1.6,9.7,6);
   mtDoor.SetScale(9,1.2,13);
   mtDoor.onMouseDown = 'onDoorMouseDown';
   mtDoor.onMouseMove = 'onDoorMouseMove';
end

This code creates new TDummy object and repositions and scales it so that it is around the door. Then it adds mousedown and mousemove function handlers to it.

Press F8 to debug TDummys.

Next we want to define what happens when user hovers mouse over the mousetarget.

Add new function.

function onDoorMouseMove()
   MouseText.Text = 'door';
end

Now if we test the game, we can hover over the mouse and the text changes to 'door'. However the text doesn't change back to '[none]' when we hover off from the door.

function onRoom01MouseMove()
   MouseText.Text = '[none]';
end

This simple function does the trick. Note that you don't have to assign the event to Room01, it does it automatically.

Next we do the same for the crate:

 
function onRoom01Load()
   mtDoor = TDummy.Create();
-- .....
-- .....
 
   mtCrate = TDummy.Create();
   mtCrate.SetPosition(-4.8,-5.4,2.2);
   mtCrate.SetScale(5,5,5);
   mtCrate.onMouseDown = 'onCrateMouseDown';
   mtCrate.onMouseMove = 'onCrateMouseMove';   
end
 
function onCrateMouseMove()
   MouseText.Text = 'crate';
end

When changing rooms, we want that our objects destroy when we unload the room, so we script this:

function onRoom01Unload()
   mtDoor.Destroy(); -- This destroys object in Engine Core side.
   mtCrate.Destroy();
   mtDoor = nil; -- This removes any reference from LUA
   mtCrate = nil; 
end

Changing room

Now that we have our room identified, we want to change to Room02 when clicking door.

First we need to create our second room. Insert the following to onGameLoad.txt file.

Room02 = TRoom.Create();
Room02.Name = 'Room02';
Room02.Filename = 'Room01/Room02.3ds';
Room02.WalkArea = 'Room01/Room02.3ds';
Room02.scriptfile = 'roomscripts.txt';

Note that we share the same scriptfile here. It is recommended to place the room scripts in separate scriptfiles. We have so small game it doesn't matter.

Then we assign mousedown event so that the Room02 is loaded:

function onDoorMouseDown()
   Room02.Load();
end

We already assigned onDoorMouseDown event to our mtDoor object, so now when we click we jump to the next room. Little adjustments on camera angle should be in place. Write this in roomscripts.txt file:

function onRoom02Load()
   Camera.SetPosition(20,20,-20,1);
end

Now when we click we end up having camera angle changed smoothly. Few more adjustments for actor and light position.

function onRoom02Load()
   Camera.SetPosition(20,20,-20,1);  
   MainActor.SetPosition(5,5,5);
   Light.SetPosition(20,50,-20); 
end

As with Room01, we will create TDummy for door, add little mouse-events. Here is full script. Note that we re-use door mousemove event. Also we clear actors walkpoints and position him according to the room entrance.

function onRoom01Progress()
  if MainActor.Y < -40 then
    MainActor.SetPosition(0,10,0);
    MainActor.ClearWalkPoints();
  end
end
 
function onRoom01Load()
   MainActor.ClearWalkPoints();
   Camera.SetPosition(20,20,20,1);  
   MainActor.SetPosition(5,5,-4);
   MainActor.PointTo(0,5,100);
   Light.SetPosition(20,50,20); 
 
   mtDoor = TDummy.Create();
   mtDoor.SetPosition(1.6,9.7,6);
   mtDoor.SetScale(9,1.2,13);
   mtDoor.onMouseDown = 'onDoorMouseDown';
   mtDoor.onMouseMove = 'onDoorMouseMove';
 
   mtCrate = TDummy.Create();
   mtCrate.SetPosition(-4.8,-5.4,2.2);
   mtCrate.SetScale(5,5,5);
   mtCrate.onMouseDown = 'onCrateMouseDown';
   mtCrate.onMouseMove = 'onCrateMouseMove';   
end
 
function onCrateMouseMove()
   MouseText.Text = 'crate';
end
 
 
function onDoorMouseMove()
   MouseText.Text = 'door';
end
 
function onDoorMouseDown()
   Room02.Load();
end
 
function onRoom01MouseMove()
   MouseText.Text = '[none]';
end
 
function onRoom01Unload()
   mtDoor.Destroy(); -- This destroys object in Engine Core side.
   mtCrate.Destroy();
   mtDoor = nil; -- This removes any reference from LUA
   mtCrate = nil; 
end
 
-- ROOM 02!!! ...
 
function onRoom02Progress()
  if MainActor.Y < -40 then
    MainActor.SetPosition(0,10,0);
    MainActor.ClearWalkPoints();
  end
end
 
function onRoom02Load()
   MainActor.ClearWalkPoints();
   Camera.SetPosition(20,20,-20,1);  
   MainActor.SetPosition(5,5,4);
   MainActor.PointTo(0,5,-100);
   Light.SetPosition(20,50,-20);    
   mtDoor2 = TDummy.Create();
   mtDoor2.SetPosition(5.6,-9.7,6);
   mtDoor2.SetScale(9,1.2,13);
   mtDoor2.onMouseDown = 'onDoor2MouseDown';
   mtDoor2.onMouseMove = 'onDoorMouseMove';
end
 
function onDoor2MouseDown()
   Room01.Load();
end
 
function onRoom02MouseMove()
   MouseText.Text = '[none]';
end
 
function onRoom02Unload()
   mtDoor2.Destroy();
   mtDoor2 = nil;
end

Locking the door

Next we create a key to our game. We don't want to create this specifically in room scriptfile, because we want to carry this through our game (to the next room also).

Note: Make sure your inventory mesh objects are located and centered in origo. Otherwise they will not get mouse-events and might look funny in inventory.

Put this in onGameLoad.txt before Room01.Load();

obKey = TMesh.Create();
obKey.Load('Room01/key.3ds');
obKey.SetPosition(-4.65,4.1,5);
obKey.onMouseMove = 'onKeyMouseMove';
obKey.onMouseDown = 'onKeyMouseDown';
obKey.CastShadows = 1;

Okay, it's little pixel hunting to find the key. We could make another TDummy for the object, but to keep it simple, we won't.

Next we will say that the door is locked, unless we have the key. So change the onDoorMouseDown function to following:

function onDoorMouseDown()
   if obKey.InInventory == -1 then
     MainActor.Say("It is locked"); 
   else
     Room02.Load();
   end
end

InInventory gives the id of inventory where the key is located. If it is in room, it is -1.

Inventory? We don't have inventory to put the key on. So let's create one.

Inventory = TInventory.Create();
Inventory.SetPosition(-0.65,-1.0);

Now we have inventory. Next we want to add the key to the inventory, when player clicks the key.

function onKeyMouseDown()
   if obKey.InInventory == -1 then
    MainActor.Say("That looks useful, I'll take it");
    obKey.MoveToInventory(Inventory.ID);
    obKey.SetScale(1.5,1.5,1.5);
   end  
end

Once again, if the key is not in inventory, take it.

Now when we have taken the key, we can go freely through the door.

Remember, when creating your own inventories and objects, inventory mouse-events are found in current room scriptfile. So basically you have to have in all room scriptfiles mouse events for objects in your inventory.

That wraps our Room changing and Inventory handling tutorial.

Back to top
tutorial04/start.txt · Last modified: 2009/07/25 07:32 by rahakasvi