In this tutorial we will create a first person shooter. Even though
all the graphics will look 3-dimensional, the game actually takes place
in a 2-dimensional world. So we will use the standard machinery of Game
Maker to create this 2-dimensional game, but rather than drawing the
2-dimensional room we will create 3-dimensional graphics instead.

WARNING: MAKE SURE EACH STEP WORKS BEFORE
MOVING ON TO THE NEXT STEP.
IT IS HARD TO FIND ERRORS LATER!!!!!!!!!

2-D Room

IT IS IMPORTANT THAT YOUR SPRITES ARE THE SAME SIZE AS MINE
OR YOU CODE WILL NEED TO BE MODIFIED

(Since we will never see it, just use a circle with something to indicate
orientation)

Character Movement

Adding Code to the Player

On Create we will set some friction
friction = 0.2;

On EndStep Transform the Sprite so that it is always facing the direction
it is moving

Set the Movement Keys

On Left and Right Keys set the direction
direction+=3 and direction-=3

On the Up and Down Keys we will change the speedUP

Down

Hitting the Walls

Uncheck Precision Collision Checking in your
wall sprites

Since we want the same thing to happen when we hit a vertical or horizontal
wall

Create a obj_wall_basic with no sprite
Make this wall the parent of obj_wall_hor and obj_wall_vert

Add a Collision Event with obj_wall_basic (the
parent of the other walls)
speed=0;

Make sure your character moves correctly
before moving on to 3D

Turning It into a 3-Dimensional Game

Our player object becomes the most important object. In
its creation event we initialize the 3D mode by using the following
piece of code:

Making Walls, Floors and Ceilings

Create 3 Backgrounds 128 x 128

To draw a wall with this background texture we need to
know what the coordinates of the wall should be. We set this in the
Create event of each individual wall object (because it will be different
for each). For the horizontal wall we put the following code in the
Create event:

For the vertical wall

We actually draw the wall on the Draw event of the obj_wall_basic
object.

We still need to indicate how we look at the world and
we must also draw the floor and ceiling of the rooms. We do this in
the draw event of the player object. The player object will from now
on serve the role of the camera that moves through the world.

You can now run the game and walk around in your world.
Suddenly our game looks completely different, even though it is in fact
still our 2-dimensional game. Only the graphics have become 3D.

NOTE: To change the height of your player change both
10's in the d3d_set_projection

Wall Variation

The world as we designed it up to now looks rather boring. All walls
look the same. Not only is this boring, it makes it also difficult for
the player to orient himself in the world. This is bad game design (unless
it is the intention of the game). It is more user-friendly if the player
can more easily remember where he is and where he came from.

We add a number of additional textures in the game and make a number
of additional wall objects. These will be exactly the same as the other
ones, except that in their Create event we assign a different texture
to them. Remember to give all the wall objects the obj_wall_basic wall
as their parent. By using different colored sprites for the different
wall it is easier to create the levels. Try your own or use mine!!!

Design a Better Level using the New Walls

To get interesting surprises we should have a sparser set of areas
with corridors between them. By adding turns in the corridors we reduce
the part of the world that the player can see at any one time.

To create a sparser level we will need more space. So we will increase
the size of the room to something like 1000 x 1000

Adding Fog

The effect of fog is that objects in the distance look darker than
objects that are nearby (or lighter, depending on the color of the fog).
When an object is really far away it becomes invisible. Fog adds atmosphere
to the game, gives a better feeling of depth and distance, and makes
it possible to avoid drawing objects that are far away, making things
faster. To enable fog, just add the following line to the Execute Code
action in the Create event of the player object (after enabling 3D).

d3d_set_fog(true,c_black,10,300);

This enables the fog, with a black color, starting at distance 10,
and becoming completely black at distance 300. Play arround with this
to get the effect you want

Better Motion

Wall Hit ImprovedWhat remains to be done is to
improve the motion control. When you hit an object you stop moving at
the moment. This is not very nice and makes walking through corridors
more difficult. When you hit a wall at a small angle, you should slide
along the wall rather than stop. To achieve this we need to make some
changes. First of all, we no longer make the walls solid. When objects
are solid we cannot precisely control what happens in case of a collision
because the system does this for us. But we want all the control. So
make all wall objects non-solid. In the collision event (with
obj_wall_basic) we include an Execute Code action with the following
piece of code:

Strafe

Most First Person Shooter games the player is also able to strafe,
that is, move left and right sideways. For this we use the <z>
and <x> key. The motion should perpendicular to the current direction
the player is facing. For the <x> key the code becomes:

A similar piece of code is required for the <z> key. Change the
+ to -

Walking and Running

Your Turn ......

When the player presses the <Shift> key we make the player move
faster. This is achieved as follows: In the <Up> and <Down>
Keyboard events we test whether the <Shift> key is pressed and,
if so, allow for a faster speed.

Adding Objects

In this section we are going to add some objects to our world. These
are mainly for decoration but the player (and opponents) can also hide
behind them. We will simply use sprites to represent these objects in
our world. We will use this technique for everything in our world: the
bullets, plants, weapons, explosions, etc.

Plants

Textures are 128 x 128 NOTE: In this case the
Textures are sprites not backgrounds, see above!

The Plant Sprites are squares that are 16 x 16 and centered!

Create the plant objects and set the parent as obj_wall_basic

DEPTH -20

In the Create Function set the texture of the plant

tex = sprite_get_texture(tex_plant1,0);

In Create of the Player and in the End Step set the camera variables

In the Draw of the Plant

Your Turn

Create some other objects in your game that you can place in the rooms.
(But don’t overdo it. This will make the game slow and hamper
game play.)

Adding Animations

The Barrel

Create a sprite for the Barrel (just
a square) with 2 frames.
Add the Texture as a sprite

Then create the object and assign the
square sprite

On Create set the image speed and the texture

On Draw

Draw the barrel using camsin and camcos

You may need to modify numbers slightly!!!

The Paintball Gun

Create obj_Gun using the real sprite
not a square.

You can use the gun example to start
but must create a paintball gun of your own after you have it working.

Add the Paintball Gun into you room. Anywhere is fine (Depth -50)

On Create set the image speed and index to 0

On Draw

Note: You can also change the 2,2 to very the size of your gun!

On Space set the image speed to 0.4, image index to 0 and play a sound.

Add an animation end event and set speed and image back to 0

TRY THIS BEFORE MOVING ON!!!! MAKE SURE
IT WORKS!

Collision checking is a little more difficult we need to check in front
of us, move forward, check again ... and so on.

Check if you hit a barrel

Create an Object BarrelExplosion

Note: The sprite you create for the explosion
(just a square) must have the same number of frames as the explosion
(5)

Add the Draw Event to the object (See Barrel)

On the Barrel object Destroy event, create the explosion.

Your Turn

Create other objects to shoot. For each one add an if to check for
a hit, (Remember to make sure all objects have obj_basic_wall as a parent)

You may also wish to incorporate the can_shoot option from the previous
tutorials.

Adding Opponents

The steps below will add a monster with 2 sprites - alive and covered
in paint, but you may add any opponent you choose.

Create the Textures for your monster (64x64), the sprites (16x16)

Make two objects, one for the monster that is normal and one for the
monster that is covered in paint.
For both set the animation speed correctly.
When the monster dies create a dying monster at the same position. This
all works exactly the way as for the barrel. There is just one difference.
At the end of the dying animation we do not destroy the dead monster
but we keep it lying around, just showing the last subimage of the animation.
To do this in the Animation End event add a Change Sprite action and
set the correct subimage (7) and set the speed to 0.

On Create of the Monster set the Texture
On Draw of the monster Draw in 3D

To be able to shoot the monsters we can use the same idea as the barrel,
with a few changes. First of all, we do not want monsters to be children
of our basic wall object. This will give problems when they walk around.
So create a new object obj_monster_basic. This will be the parent object
for all monsters (even though we have just one now).

Now add the hit check into your space bar in the section where no basic_wall
has been hit

And add the code to remove the monster when hit below section that
removes the barrel

You can repeat the above code for other objects.

The final thing to do is to let the monster attack the player. This
monster will not shoot but simply walk towards the player. When it hits
the player the player should lose some health. In the creation event
of the player we set the health to 100. In the gun object, that also
functions as our overlay, we also draw the health bar, slightly transparent,
as follows:

Add in Lives and No More Lives Feature

Monsters Attack

Set the image index, and speed on create

On Begin Step

On the Draw add

if (point_distance(x,y,global.camx,global.camy) > 240) exit;

You will have to add the collision with the wall code to obj_monster_basic

Add an Intro Screen
Add a Help Screen
Add a Play Again Option

Modify the walls, floor and
ceiling.

Add Health and Health pacs.
Add a scoring system.

Create some additional monsters,
and add some other objects in the world. (Keys, Portals etc.) You could
give monsters health, requiring multiple shots. It is up to you. Be
creative and have fun!