First Person Paintball

Adapted from a tutorial by Mark Overmars

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

 

1. Create your Room using horizontal and vertical walls. (32x8 and 8x32) Centered to (16x4 and 4x16)

Make it simple for now. We will be improving it later

Design several different areas.
2. Create your player. (16 x 16) Centered at (8 x 8)
DEPTH 100


(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 speed
UP

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 Improved
What 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!

You must add 20 Marks worth of upgrades.

 

Evaluation Sheet

 

 

 

Mouse Upgrade (Optional)