This End Up

Year: Jan 2009 - Mar 2009

Tools:3d Gamestudio / C Script

Role:Programmer/ Lead Deasign

Description:

A 3D adventure where the player must scale and rotate his environment to complete puzzles and defeat enemies. The game is a puzzle platformer. I scripted the rotation mechanic using C-Lite, a flavor of C. The original concept was created for a student project.

Number of Students: 10

Project Goals: Create a full game design implementing two different gameplay mechanics.

What I did: I used my extensive knowledge of the 3D Gamestudio game engine to code a player movement, Enemy AI, Sound, Shader Rendering, Animation, and UI.

This End Up Unique Gameplay

Explanation of Rotation

The rotation mechanic in This End Up was born by committee. The original idea came from the prototype from Bob the Blob – that game the prototype asked the question – what happens if you are able to manipulate yourself and the environment to solve puzzles. (See Bob the Blob For more details on that project) We ran out of time to implement the full feature in that project. (We were able to make the blob change his shape, but we were unable to give the player the ability to manipulate the world) When the group reconvened, we decided that we wanted to explore manipulating the world further.

We decided that we needed to lock down how the player would actually control this rotation. We settled on the player being able to rotate his world by hitting special gears or cogs that were placed throughout the world. The player is temporarily lifted up while the entire level around him rotates. Depending on the gear, each room can rotate multiple ways. The player can use this to escape rooms and defeat enemies. Each time the player rotates the room, enemies are thrown into spikes and other hazards. The player has to be careful not to throw himself into these obstacles however. This is where the interesting choice comes into play.

I implemented the script to allow the player to rotate each room around him. I also implemented the scripting to allow enemies to die when they fall from high ceilings.

Example Code

#define PRAGMA_PATH "shade-c"#include "sc_core.c"; #define PRAGMA_PATH "shade-c"#include <acknex.h>#include <default.c>#include "sc_core.c"; /////////////////////////////Starting Variables////////////////////////////////////////////////////////varvideo_mode=7; // 800x600 pixelsvarvideo_depth=32; // 32 bit modevarvideo_screen=1; // start the engine in full screen modevarplayer_close=0;
varattackstatus=0;
varmove_vec[3] =0,0,0;
////////////////////////////////PATHS//////////////////////////////////////////////////////////////////////////////path"C:\\robodemo\\models"; // Path to models subdirpath"C:\\robodemo\\scripts";
path"C:\\robodemo\\levels";
path"C:\\robodemo\\sounds";
path"C:\\robodemo\\images";
////////////////////////////////////Includes/////////////////////////////////////////////////////////////include<player.wdl>;
include<glowing.wdl>;
include<enemy.wdl>;
include<specular.wdl>;
functionstart_level1();
//////////////////////////////////Bmap///////////////////////////////////////////bmapmain_tga=<startmenu.pcx>; // main panelbmapstart_pcx=<start.pcx>;
bmappointer1_tga=<pointer1.tga>; // mouse pointerbmappointer2_tga=<pointer2.tga>;
/////////////////////////////////////////Strings///////////////////////////////////////stringdummy_wmb=<dummy.wmb>;
stringdemo_wmb=<demo.wmb>;
////////////////////////////////////////////////////////////////////////////////////vargame_started=0; // will be set to 1 when the game starts////////////////////////////////////////////////////////test zone///////////////////////////////////////Starters///////////////////////////////////////////////////// so aparantly this only works when it's directed toward you. It also looks like to use it you need to have the file tiles floor attached to the entity you wantbmaptilesfloorDOT3=<floor1_Nrm.tga>;
materialtilesfloor
{
skin1=tilesfloorDOT3;
flags=tangent;
}
starterload_shaders()
{
d3d_automaterial=1;
effect_load(tilesfloor,"bumpmap.fx");
effect_load(tilesfloor,"bumpmap.fx");
wait(5);
}
materialrobonormal
{
skin1=tilesfloorDOT3;
flags=tangent;
}
///////////////////////////////////////// Do All stuff you are unsure that works herepanelmain_pan// main panel
{
bmap=main_tga;
layer=20;
pos_x=0;
pos_y=0; // for nowbutton=397, 475, start_pcx , start_pcx, start_pcx, start_level1, start_level1, start_level1;
// button = 559, 431, help2_tga, help1_tga, help2_tga, show_help, null, mouse_over;// button = 647, 329, load2_tga, load1_tga, load2_tga, load_game, null, mouse_over;// button = 681, 226, save2_tga, save1_tga, save2_tga, save_game, null, mouse_over;flags=overlay, refresh, visible;
}
functionstart_level1()
{
mouse_mode=0; // hide the pointermain_pan.visible=off; // hide main_panlevel_load (demo_wmb); // load the first playable level (runs level1.wdl when it is loaded)
}
//////////////////////////Functions///////////////////////////////////////////////actiontrap_trigger
{
my.enable_touch=on;
// my.event = trap_player;while(player==null){wait(1);}
while(vec_dist(player.x, my.x) >100) {wait(1);} // player with the 40player_close=1;
}
// this is the basis for our game // with action trap player /// this basically looks at the trigger and causes it to either tilt(rotate) pan (rotate horizonatlly) or scaleactiontrap_player
{
while(player_close==0){wait(1);}
// the way this should work is that it checks to see if the player is clse while (my.z>180) // this shouldn't work until the player_close is equal to 1
{
my.z-=50*time;
wait(1);
}
my.pan=my.pan+360;
}
actiontest1
{
while(player_close==0){wait(1);}
// the way this should work is that it checks to see if the player is clse my.tilt=my.tilt+-720*time; // tilt is up pan is horizontalplayer.z+=50;
my.scale_x=2+random(5);
my.scale_y=2+random(5);
my.scale_z=2+random(5);
ifplayer_close==2
{
my.tilt=my.tilt+180*time;
}
}
///////////////////////////////////////////////////////////////////////////actionspikes
{
if (you!=null) // kill the player if he touches you
{
you.health=-100;
}
}
functionmain()
{
camera.arc-=30; // set the default zoom factorlevel_load (dummy_wmb);
wait(3);
// sc_setup();// camera.x = 0; // choose a convenient camera position// camera.y = 0;// camera.z = 350;camera.tilt=-90; // and anglemouse_spot.x=50; // ~ 63 / 2mouse_spot.y=25; // ~ 35 / 2camera.tilt=-90; // and anglemouse_mode=2; // show the pointerwhile (game_started==0) // as long as we haven't started the game
{
mouse_pos.x=pointer.x;
mouse_pos.y=pointer.y;
if (random (1) >0.95) // use the second bitmap for the pointer every 20 frames (or so)
{
mouse_map=pointer2_tga;
}
else
{
mouse_map=pointer1_tga;
}
wait (1);
while (player==null) {wait (1);} // wait until the player appears in the level
}
}

Code to handle rotation. I set up a loop to check the distance of the player. If the player was close enough, the trigger would rotate the object that this is attached to.

// this is the first rotation. This is for the first rotation in the game action1strotatetrigger
{
while(player_close==0){wait(1);}
// the way this should work is that it checks to see if the player is clse while (my.z>180) // this shouldn't work until the player_close is equal to 1
{
my.z-=50*time;
wait(1);
}
my.pan=my.pan+360;
}
action1strotate// this is the first rotate for memo's room. There should only be one.
{
while(player_close==0){wait(1);}
// the way this should work is that it checks to see if the player is clse my.tilt=my.tilt-180*time; // tilt is up pan is horizontalplayer.z+=5;
}

Summary Block

This is example content. Double-click here and select a page to feature its content.
Learn more