3D for GML: Elevators

From ENIGMA
Jump to navigation Jump to search


6.1 About elevator types

In the previous tutorial we have seen how the character can climb by jumping from platform to platform. Another way for a player’s character to get to another level of height is an elevator.

There are typically two types of elevators. The first type of elevator is the closed type: doors open, player character enters, doors close, wait a couple of seconds, doors open and player character exits the elevator on another floor. In this type of elevator the surrounding world is not visible to the player and because none of the motion is visible to the player it’s not really a 3D issue. You never have to see the elevator actually moving!

From the game programmer’s point of view, it is simply a way to jump from one room to another (like a portal). It can be a time when a new level is loaded into the computer’s memory. There are no real 3D or z value issues to speak of.

The second type of elevator is the open type. The player’s character steps onto a platform or gets inside a box, and while the elevator moves the world surrounding the elevator remains visible to the player.

6.2 Moving an elevator

An elevator is actually not much different from a platform tile. The only difference being that it can change in height (z value). The elevator (tile) is moved upwards using the script scr_elevatormove in the Step event of the parent object par_elevator, by using the following code:

//move elevator
z += zspeed;
if z>1024 then z=-32;

The zspeed value defines the speed of the elevator. That last line makes sure that the elevator returns to a low position when it has reached the top; its value has to start below zero because it has to lift up the character, as you can see in the following paragraph.

6.3 Lifting a character

In the gm6 that comes with this text, you will see that I’ve created a elevator tile that can lift the character and transport him to a higher level. The important code is in the script scr_MoveZ which can be found in the Step event of the camera object (obj_camera). It looks like this:

//check for elevator
if collision_point(x,y,chi_elevator,false,false) then
{
	znear=instance_nearest(x ,y,chi_elevator).z;
	if z>znear then {z=znear+64;zspeed=1;zgravity=0}
	if z<znear then {zgravity=.1;z+=zspeed;zspeed-=zgravity;}
}
else
{
	zgravity=.1;z+=zspeed;zspeed-=zgravity;
}
//land on ground

The z value of the character is compared to the z value of the nearest elevator object (chi_elevator, because the child-parent method was used in this gm6). The settings are changed accordingly (zspeed, zgravity and so on). It also handles the landing on the ground. I’ve not added code for when the camera reaches its highest point (when riding the elevator). I’ll leave that up to each individual programmer. The basics of creating an elevator should become clear from this tutorial.

6.4 Taking character height into account

Note that there is no character object in this gm6 file. The camera object serves as a character, so to speak. This is because we are using a first person view in which the character isn’t visible as such anyway. The camera object is drawn higher than its actual position in height (z value). You can think of it like this: the character’s feet are on the elevator but his eyes are placed a bit higher to make it look realistic. We are actually taking the character’s height into account. The camera projection is drawn higher than the z value, as you can see in the script scr_camera:

//draw what the camera sees
xt=x+cos(direction*pi/180);
yt=y-sin(direction*pi/180);
zt=z+zdirection
d3d_set_projection(x, y, z+64, xt, yt, zt+64, 0, 0, 1);

You see those values ‘z+64’ and ‘zt+64’? That’s what makes the camera eye appear higher than the actual height of the camera (z value).

6.5 Looking around

The xt, yt and zt values (in the code above) are used to create the effect of looking around in first person view. I’ve used the following script to create a mouselook effect:

//MOUSELOOK
//calculate motion
change_x=(display_mouse_get_x()-512)/16
change_y=(display_mouse_get_y()-384)/16
//apply treshold
if (change_x<.1) {change_x=round(change_x)}
if (change_y<.001) {change_y=round(change_y) }
//move camera
obj_camera.direction-=change_x
obj_camera.zdirection-=change_y/64
//move mouse back
display_ mouse_set(display_mouse_get_x()-change_x*4,display_mouse_get_y()-change_y*6)

It basically reads where the mouse pointer is and uses it to set the camera’s direction (left and right) and zdirection (up and down). By the way, the ‘apply threshold’ code is used to keep the camera from floating too much.

I’ve also added an object named obj_flash which creates the effect of random flashes of lightning. Just to make the game’s environment appear a bit more spooky.


All rights reserved. Copyright © 2004 by John J.A.H. Weeren. Unauthorized use or reproduction, whole or in part, without written permission from the author is strictly prohibited. This page is part of the tutorial 3D For GML. Reproduced with permission. For more information, please see the talk page.