Game Maker's Blog: N - Type

Sunday, January 08, 2006

The Enemy - Wave04: Rock Slime

Yes, well, when I came across this on my graphic collecting, I though "this is weird! I must include it!" You actually need to see it animated to understand why, it morphs into three blobs and then morphs back into one again in a fluid, almost liquid fashion, something you don't see rock doing every day!

I wanted to break up the wave of ships with something different, and this was it but in what way should it 'appear' to the player? I didn't really want it in the same place on screen as the player could easily line up and just plow shots into it so I decided it must move somehow, also, it doesn't shoot anything so it needed to be quite tough.

Looking back through the 'sine wave' topic I created on the GMC (see The Enemy - Wave03:Bioships), tsg1zzn actually came up with a formula for a sine wave which i didn't use, but I did now and adapted it for the Rock Slime

x += 2;
offset = 200;
str_x = 20;
str_y = .1;

y = offset + sin(x*str_y)*str_x;


The Rock Slime moved up and down in a smooth wave just enough to move out of range of the player's shots. I then placed a load of them on the level (they weren't 'created', they were on the level from the start but quite a way away) so when the player reached them, the Bio Ship wave just ends and the player is faced with all these Rock Slimes moving up and down, they take quite a bit to hit as well (6 hits I think).

The Enemy - Wave03: Bio Ships

(I called these ships 'Bio Ships' because that was the name of the graphic when I found it!) Yet another different enemy, yet another different attack pattern. I wanted these ones to go up and down as they moved across the screen, in a sort of sine wave (think Mexican Wave) motion but I'm absolutley crap at maths and didn't know where to begin! So I threw this open to the GMC and Tarik help me by saying that the y positioning of the ships could reverse when going above / below a certain number:


x+=1 // Movement to right.
if (y < 200)
{yChange = 1}
else
{if (y > 400) { yChange = -1}}
y += yChange


Although this didn't produce a smooth sine wave motion, it did the job of having the ships move up and down as they moved along. Coupled with the bullets aiming towards the player, you had to think fast to get through this wave!

The Enemy - Wave02: StopShips

For this attack wave, I wanted the ships to come from the top, stop, then fire at the player. I achieved this by having them move downwards as soon as they are created, then used an alarm to stop the movement at a random time, this made sure that the ships didn't all stop along the same line. In the Step Event I used image_angle (another good reason to register) to alway's point the gun towards the player (I had to put the StopShip's x position at the end of the gun). While the StopShips were on screen, I had them fire off a bullet at random intervals towards the player's position.

Tuesday, January 03, 2006

Starting the attack waves

But how do you tell the game when to use the asteroids? For that, I created a controller object with an extremely thin, but room height tall sprite! I placed this a screens width in front of the player and left it to move with the room. The idea here was that the player started off with nothing but his ship on screen moving throught the level, after a short while the player would collide with this controller object (being the entire height of the screen, there was no way to avoid it) and this would trigger a set of alarms in the controllers collision event with the player at certain intervals, something like this

/* First wave: Asteroids ************************************
These will move from right to left at different speeds and cannot be destroyed, the player has to dodge them.
--Set number of asteroids */
asteroids = 100;
// Start them moving
alarm[0] = 10;
// ***********************************************************


/* Second Wave Wave: Stop - Fire ships ***********************
These ships come down from the top downwards at random intervals and stop at random positions, they then turn and fire towards the player.
--Set number of Stop - Fire ships */
stopfireships = 30;
// Start them moving
alarm[2] = 1050;

At 10 steps after the player has collided with the controller object, I created 100 asteroids one after the other at random heights just outside the right-hand side of the view and then had them move left at different speeds. When put together, this gave the illusion of the player going through an asteroid field, which he had to dodge. And darned good luck to him too! :)

The Enemy - Wave 01: Asteroids!

I had a moving ship that could fire, I had a long room within which battles could take place. . . but I had nothing to battle with! Time for some enemies!!!

When I first had the idea of a space shoot-em-up, a long time ago, back in GM V5.3A day's, it was a top-down shooter with the player's ship at the bottom firing up and it was called StarBlaster (you can take a look at it here) and even then I knew what the plot was and what the first wave of enemies should be. The first wave wasn't even going to be enemies! It was asteroids. The plot was the player was going from Earth, through space to the enemy mothership that's approaching Earth so the entire first level was set in space, and what do you find in space? Asteroids.

I toyed with the idea of whether to let the player destroy them or make him have to doge them. . . In the end I settled for dodge, that way the player can 'practice' manoeuvering the ship for when the game gets hectic.

I came across an animated rotating asteroid which I though looked perfect, but having loads of asteroids all tumbling exactly the same didn't look right, so I decided to not have them animated. When created, I stopped their animation and picked a random frame to display as the asteroid, this way, the image shown for the asteroid was 1 of 60 different ones (as there were 60 frames of asteroid tumbling animation) so each asteroid looked different, the end result looked pretty good don't you think?

Monday, January 02, 2006

The player - Shooting

The player has to have someway to destroy the enemy! I had to be careful how I coded the shooting as the player can pick up powerups which changed what shot he used. As he started of with a single shot, this was what I coded first but there was a number of problems to overcome even for single shooting.

The first problem encountered, to be fair, has nothing to do with my game but either Game Maker or Windows itself:- for some reason (and a few people have come up against this problem), when using the SPACEBAR to fire, you can't have two cursor keys pressed at the same time as well as SPACE. You can't move the player diagonal AND fire, it's diagonal OR fire and this is certainly no good in a fast paced shoot-em-up so I decided to use the LEFT MOUSE BUTTON for fire which solved the problem.

The next problem was the continuous stream of bullets that came from the player when firing, I needed someway to time the shots so he fired one every few moments, this was achieved be the use of an alarm which changed a variable to 'on' so the player could fire, and in the FIRE event, after the player fired, the variable was set to 'off'. The timing of the alarm was also a variable (like the ships speed) so that it could be changed with powerups to have faster shots.

So now the player could move and shoot (about 2 shots every second) and as the player's shots would always go to the right, I checked whether it was out of view so I could destroy it when it couldn't be seen anymore.

The player

I already had a lovely bright coloured spaceship that I got ages ago (I can't remember where) which had frames of the ship tilting up and down, it's attention to the little details that players pick up on and it looks kinda neat so I used that. Then I coded in the movement of the ship in the Step Event for when the player presses the cursor keys. I used a variable called shipspeed so I could change it when the player picked up a ship-speedup powerup. Here's the code (the up / down movement is coded in seperate events at this stage):

if keyboard_check(vk_left)
{
// move the player's ship left
x -= shipspeed+1;
// Change image to normal looking spaceship
image_index = 0;
}

if keyboard_check(vk_right)
{
// move the player's ship right
x += shipspeed+1;
// Change image to normal looking spaceship
image_index = 0;
}


So now the player could move around the screen while it scrolled to the left, the only problem was when the player left go of the keys so he wasn't moving the ship, it 'moved' backwards towards the left side of the screen, and then moved out of view! Actually when the player let go of the keys, the ship wasn't moving at all! It was the room that was moving with everything in it giving the illusion that the player's ship was moving backwards on its own. I remedied this by having the ship move to the right in the no key event:

// Keep ship from moving backwards
motion_set(0,3);


This kept the player 'still' on the screen. All that was left was to keep the player from wandering outside the view on screen. As the view only really concerned the width of the view, I could check if the player wandered above or below room_height by simply putting:

// Prevent player from going off screen
y = yprevious;


in the intersect boundry event. Checking the left and right was a little trickier as the player wouldn't intersect the boundry if moving outside of the view, I also wanted the ship to be 'pushed' along if it reached the left hand side (this was left over from when I left the ship move 'backwards' if the player wasn't controlling it), so I placed this in the Step Event which did the job quite nicely:

// This will 'push' the ship along if it reaches the left-hand edge
if x-sprite_xoffset < view_xview {x = view_xview+sprite_xoffset}

Creating the levels

The first thing I did was to create the first level. I did this be creating a room 600 pixels high by 90000 pixels wide! This ensured that I could add extra background objects like planets and so forth as the player moved along, something to break up the tiled space background.

Once I created the 'room' I needed someway to have it continually scroll to the left so the player could move along. I did this by creating a controller object (with no sprite) placing it in the room and set it moving to the right as soon as the game starts, I then focused the view on this object so the room had to scroll. I searched and found (as I did with nearly all the graphics) a nice space background that tiled well and used this, then I found some small moons / planets and nebulars which I created as objects which I could scatter about the level to break up the endless space backdrop.

So now I had a scrolling space level, it was time to add the player.

The Creation of N - Type

Yeah, i've decided to create a blog on how I created my horizontal shoot-em-up in Game Maker. I'm doing this for two reasons, so I can remember how the hell I created it! and to help others if they want to do something similar.

Ok, where shall I start, the beginning seems a likely target so here goes:

I'm a big fan of shoot-em-ups, particularly space type ones and one arcade game that I really loved was one called R-Type, so I decided to write my own, it was also an excellent way to get to grips with Game Maker as well.

I started with the basic idea that it should be a long room which scrolls and different attack waves of different enemies should come one after the other. The game is split into 10 levels:

1 - Space
2 - Over Ship
3 - Inside Ship #1
4 - Inside Ship #2
5 - Inside Ship #3
6 - Space #2
7 - Planet Surface
8 - Inside Planet #1
9 - Inside Planet #2
10 - Planet Core

With a small boss midway through the level and a large boss at the end. The player can also collect powerups and addons to the ship to create some awesome firepower! So where did I begin?