Page 3 – The Button

Step Seven: The Button

Step Seven Files

For my game I am making a button. This button will have various uses in different levels, but for the most part the button will provide access to the rest of the level you are playing, and therefor must be pressed to pass the level. I originally tried duplicating buttons and having more than one like my gems, but I for some reason ran into miles and miles of trouble doing it. Hopefully SIO2 2.0 will work better. Either way I am going to limit the number of buttons per level to one.

Blender

The button is comprised of three objects in their own sio2 file (button.sio2), and an empty mesh in the levels sio2 file (iMarble.sio2), named buttonLoc (or whatever you decide to call it). In the button are the objects buttonBase, buttonTop, and buttonTopG. When the button is triggered, buttonTop will disappear and buttonTopG will appear (it’s green), giving the appearance that a little light is sitting on top of a grey base, and when you bump into it, the light turns green. I have also added a ‘click’ sound to the third texture channel for buttonBase’s material.

Variables

I declared an object named button for use with my button, and an int named BUTTON, to indicate whether the button has been pressed or not.

SIO2object* button = NULL;
unsigned int BUTTON = 0;

gameLoading

In gameLoading we add some a new section which will load the button.sio2 file, then move the appropriate parts to the spot marked out by the buttonLoc empty mesh object in the iMarble.sio2 scene. It also makes the green one invisible so it looks like it is turned off. The first thing I do is set the obj_loc object to point to the buttonLoc empty mesh. If buttonLoc is not contained in iMarble.sio2 (or any .sio2 file loaded before this point) then this code is skipped. So if I don’t want a button in a level, I don’t have to worry about this code throwing errors when I don’t include one. Something similar has been done in gameRender.

/////BUTTON LOADING AND PLACEMENT
obj_loc = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonLoc");
if( obj_loc )
{
i = 0;
sio2ResourceOpen( sio2->_SIO2resource, "button.sio2", 1 );
while( i != sio2->_SIO2resource->gi.number_entry )
{ sio2ResourceExtract( sio2->_SIO2resource, NULL );
++i; }
sio2ResourceClose( sio2->_SIO2resource );

button = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonBase");
button->_SIO2transform->loc->x = obj_loc->_SIO2transform->loc->x;
button->_SIO2transform->loc->y = obj_loc->_SIO2transform->loc->y;
button->_SIO2transform->loc->z = obj_loc->_SIO2transform->loc->z;
button = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonTop");
button->_SIO2transform->loc->x = obj_loc->_SIO2transform->loc->x;
button->_SIO2transform->loc->y = obj_loc->_SIO2transform->loc->y;
button->_SIO2transform->loc->z = obj_loc->_SIO2transform->loc->z + 0.418f;
button = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonTopG");
button->_SIO2transform->loc->x = obj_loc->_SIO2transform->loc->x;
button->_SIO2transform->loc->y = obj_loc->_SIO2transform->loc->y;
button->_SIO2transform->loc->z = obj_loc->_SIO2transform->loc->z + 0.418f;
sio2EnableState( &button->flags, SIO2_OBJECT_INVISIBLE );
}

I have also added two lines to the resetting variables section of gameLoading. The first resets the BUTTON flag, and the second calls a Lua function associated with the level.


/////RESETTING VARIABLES
vel.x = 0;
vel.y = 0;
gem_count = 0;
BUTTON = 0;
sio2ExecLUA("Level.ready();");

gameRender

In gameRender we check to see if the player has touched the button in the same way we check to see if they have collided with any of the gems. When the player is within the prescribed range of the button the object buttonTop is made invisible, and the object buttonTopG (the green one) is made visible. This code is inside two if() statements. The first, if( !BUTTON ) checks to see that the button has not been pressed. If it has then it wont activate again. If it has not, it checks to see that buttonLoc exists like in gameLoading. If it doesn’t (because I didn’t need a button in that level) then this code is skipped and wont cause errors looking for buttons that don’t exist. If there is a button it checks the distance from the player, and triggers if necessary.

/////BUTTON RENDERING
if( !BUTTON )
{
button = (SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonLoc" );
if( button )
{
dif.x = (button->_SIO2transform->loc->x - player->_SIO2transform->loc->x);
dif.y = (button->_SIO2transform->loc->y - player->_SIO2transform->loc->y);
dif.z = (button->_SIO2transform->loc->z - player->_SIO2transform->loc->z);
if((sqrt(sqrt((dif.x * dif.x) + (dif.y * dif.y))*sqrt((dif.x * dif.x) + (dif.y * dif.y)) + (dif.z * dif.z))) _SIO2resource, SIO2_OBJECT, "object/buttonTopG" );
sio2DisableState( &button->flags, SIO2_OBJECT_INVISIBLE );
button = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonTop" );
sio2EnableState( &button->flags, SIO2_OBJECT_INVISIBLE );
button = ( SIO2object * ) sio2ResourceGet( sio2->_SIO2resource, SIO2_OBJECT, "object/buttonBase" );
sio2SoundPlay(button->_SIO2sound[0]);
BUTTON = 1;
}
}
}

At the end we set BUTTON to 1, causing the button rendering section to no longer respond (because the button has been pressed), and triggering another section to evaluate every loop. This is to facilitate programming in Lua that needs to be called every loop.


/////BUTTON
if( BUTTON )
{
sio2ExecLUA("Level.button();");
}

Lua

This is the same Lua script that I used earlier to tell gameLoading how many gems I decided to use in this level. It now has three functions in it. For each level I will customize this script with the number of gems, and other things that I need to activate for accomplish that is different in each level. Level.data() contains the number of gems and is called at the beginning of gameLoading. I can also put any other set up information I need in this function. Level.ready() is called at the end of gameLoading, and will be used to activate the Ipo for my goal object (the finish point for each level), and any other Ipo’s I want to create for each individual level. Finally Level.button() is called every loop after the button has been pressed. I will use this to move level pieces, open up bridges or pathways. I have had problems creating objects that are moving that I can roll across. I tried using Ipo’s, but when the ball touches an object with an Ipo it generally goes flying. The only thing that works with Ipo’s if you keep it flat and move it back and forth or rotate it around the Z-axis. Even then the ball falls through the object too often to be useful in a game. If I do it programatically all I can achieve without my ball falling through is rotating around the Z-axis. But it hardly ever falls through if I do it this way. I might use this in a couple of spots, but I think the way I will use it is to just move a wall, ie: Have a pathway that doesn’t move, but have a wall blocking it. When the button is pressed, the wall is moved via Ipo or programatically, either should work as long as the button is far enough away that the moving wall doesn’t hit the ball and send it flying. What the code currently does is set a piece rotating which you can roll across to the other side. I tried making it more like a bridge so you would have to hit it to get across, but my ball fell through. It only seems to work if I keep it square-ish, lame. I hope this stuff works better in SIO2 2.0, or I am going to be (more) unhappy about paying for it.

Level = {};
Level.Lua = SIO2.sio2ResourceGetObject( SIO2.sio2._SIO2resource, "object/Lua" );
Level.Goal = SIO2.sio2ResourceGetObject( SIO2.sio2._SIO2resource, "object/Goal" );
Level.Cube = SIO2.sio2ResourceGetObject( SIO2.sio2._SIO2resource, "object/Cube" );

function Level.data()
--NUMBER OF GEMS
Level.Lua._SIO2transform.rot.x = 9;
end

function Level.ready()
SIO2.sio2IpoPlay( Level.Goal._SIO2ipo );
end

function Level.button()
Level.Cube._SIO2transform.rot.z = Level.Cube._SIO2transform.rot.z + 0.1;
SIO2.sio2TransformBindMatrix( Level.Cube._SIO2transform );
end

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s