The Fourth Level

As mentioned in a previous post, Level 4 of the GPC was not a lesson, but rather a series of challenges meant to reinforce what was taught in Level’s 2 and 3. This time, I elected to create a new game rather than modify an existing one.

I settled on a top down shooter/adventure game and added features and flourishes as I went along. I used my earlier conceived true grid movement code, but this time, I used a switch statement instead of a series of if statements (or at least fewer of them):

switch (keyboard_key)
 {
  case vk_left:
  case ord("A"):
     sprite_index=spr_player_walk_left;
     if moving=0 {
       moving=1
       instance_destroy(obj_target) 
       target=instance_create(x-64,y,obj_target)
       move_towards_point(target.x,target.y,4) 
      }
      break; 
 case vk_right:
 case ord("D"):
    sprite_index=spr_player_walk_right;
    if moving=0 {
      moving=1
      instance_destroy(obj_target) 
      target=instance_create(x+64,y,obj_target)
      move_towards_point(target.x,target.y,4) 
     } 
     break;
 case vk_up:
 case ord("W"):
    sprite_index=spr_player_walk_up;
    if moving=0 {
      moving=1
      instance_destroy(obj_target) 
      target=instance_create(x,y-64,obj_target)
      move_towards_point(target.x,target.y,4) 
    } 
    break;
 case vk_down:
 case ord("S"):
    sprite_index=spr_player_walk_down;
    if moving=0 {
      moving=1
      instance_destroy(obj_target) 
      target=instance_create(x,y+64,obj_target)
      move_towards_point(target.x,target.y,4) 
     } 
     break; 
 }

While trying to figure out line of sight, I came a new function:

collision_line(x,y,obj_player.x,obj_player.y,obj_barrier,1,0)

That was my first time using the collision_line, which I don’t think is covered at all in the GPC, though it might be included in his how-to’s somewhere…I came across it after watching a tutorial video by “GM Wolf” on YouTube:

This would have solved a lot of issues for me…for instance, in a previous project, I had an idea to create a trap comprised of two moving blocks which collided into and bounced off of each other. While everything worked fine, it would occasionally cause the block to get stuck in a wall. This happened because it’s movement caused it to overlap before it detected the collision, thereby getting stuck inside the wall, unable to go anywhere.

I solved this before using the place_meeting function, but was never introduced to the End Step Event, which  would have been the right way to do it. Nevertheless, I can think of other uses for collision_line and am glad I learned of it!

All in all, I spent about 2 days (most of the weekend) working on this little mini-game, and here are some of the features I included:

  • Destructible walls that advance in damage by manipulating the image_index
  • Enemies that can navigate mazes (using John Janeka’s code from Level 12)
  • Line of Sight for enemies with projectiles
  • Health, ammunition and keys global variables that persistent between rooms
  • Lock and key mechanism
  • A switch that reveals the exit when touched
  • Randomized muzzle flare and smoke when firing bullets
  • Randomized impact splatters when an enemy is hit
  • Different sounds for each impact
  • Randomized health power up sprites to add variety using a single object
  • Exits that allow you to advance to the next room
  • Capped health at 100%

What I not did include were:

  • Fail condition/game over when you run out of hitpoints
  • Start screen
  • Game Over screen

All in all, it’s a neat little game though unfinished, and good practice for more serious projects to come!

GPC Level 3 Revisited

Shortcuts…

With my files recovered, I’m free to concentrate on getting back to my second run through the GPC. I’m back to Level 3, and bits and pieces of the GML syntax are coming back to me.

For instance, when calculating variables, the course suggests something like this:

hitpoints = hitpoints + 1

This works of course, but he also suggests that hitpoints = +1 does not work, which is true, however, if you reverse that (e.g. hitpoints +=1), it does the same thing with fewer characters to type. A small, but useful time saver.

###

A Hamburger That Fires Bananas (Improved)

In GPC 3-03-A, he introduces a function that randomizes an integer:

irandom_range(0,100)

This allows you use a random number generator (RNG) to decide the outcome of a particular variable within a specified range (i.e. 0 to 100 in the code above). This is used to manipulate the direction that a hamburger fires bananas, and the speed at which they are fired.

I took this a step further by adding the following step event (pun very much intended) to obj_banana:

image_angle+=speed*10

This (in my most humble opinion) makes the bananas far more interesting/exciting to watch as it causes them to spin through the air at a speed consistent with their velocity – i.e. a fast traveling banana rotates faster than a slower moving banana.

Try it yourself!

Aside: I couldn’t help but giggle at the silliness of this lesson – you wouldn’t think a burger that shoots bananas would be so amusing but you’d be wrong! Very entertaining stuff 🙂

Switching Things Up

In Level 3, “Challenge 2 – Random Generation,” the student is required to write a series of if statements to randomly move the player character in one of 4 orthogonal directions.

In my first time around, I recall touching on Switch statements, which can be a good way to handle this very scenario. Here’s how that would look:

Instead of this:

num=irandom_range(1,4)

if num=1 {
direction=0
speed=4
}

if num=2 {
direction=90
speed=4
}

if num=3 {
direction=180
speed=4
}

if num=4 {
direction=270
speed=4
}

You could do something like this:

speed=4
switch (irandom_range(1,4)) { 
 case 1: direction=90; 
 break; 
 case 2: direction=0; 
 break;
 case 3: direction=270; 
 break;
 case 4: direction=180;
 break;
}

This seems like a far more efficient and cleaner way to handle multiple (more than 3+) consecutive if statements, but is cheating at this stage as Switch isn’t covered in the GPC until much, much later*…

So why mention it now? Because I want to get in the habit of making my code clean and efficient.

And with that, on to Level 4!


*I can’t quite recall exactly when this was introduced… For all I know, it may not have even been in the GPC, but if I do come across it later, I will update this post with where you can find it.

Transition

“Use a superior development system than your target to develop your game.” – John Romero, Early Id Software Programming Principles

One of the nice things about being employed again was the ability to afford a new computer, something I’ve put off as long as I could.

About 5 years ago, I’d purchased a very high-end mobile workstation to take with me overseas so I’d have something to keep myself entertained on the 26+ hour flights to and from the US:

  • Intel Core i7 3630QM @3.2GHz
  • 32GB of DDR3 RAM @ 1600MHz
  • Nvidia GTX 675MX 4GB of VRAM
  • 120GB SSD Primary Drive
  • 1TB Storage Drive

When I came back home, I found it more convenient to develop on my aging desktop machine with ideas of upgrading it when possible:

  • Intel Core i7 2600K @ 3.4GHz
  • 8GB DDR3 @ 1600MHz
  • AMD HD 5770s 2GB VRAM (x2 in Crossfire)
  • 120 GB SSD Primary Drive
  • 80GB SSD Auxiliary Drive
  • 320GB Storage Drive
  • 1 TB Secondary Storage Drive

A couple of months ago, I built myself a new PC that should last me a good 3-4+ years with minor upgrades:

  • Intel Core i7 7700K @ 4.2 GHz
  • 16GB DDR4 @ 3000MHz
  • Nvidia GTX 1080 8GB of VRAM
  • 240GB SSD Primary Drive
  • 2TB Storage Drive

I’ve been very pleased with it so far, and have been slowly reinstalling my development tools. The next step was to copy down my data so that I could pick up where I left off. To facility this, I purchased an inexpensive but well-made USB 3.0 SATA Hard Drive Docking Station.


What was intended to be a simple task, however, turned out to be anything but…The data I needed was spread across 4 different drives, one of which was BitLocker encrypted. The machine itself belonged to me originally, was lent a friend who in-turn savaged it, replacing several of the drives and the OS. On the actual computer, I’d solved this using Windows Libraries, but didn’t have that luxury when reading the raw drives.

So what did I do? I incorporated a handy application called SpaceSniffer to help me work out [visually] where the files I was looking for were.

This application is very similar to WinDirStat, but performs significantly faster. I still have a few more applications to [re]install, but I can get that done tomorrow at some point as it is now 4:13am, and I should think about getting to bed as I have to be up in 3 hours.

Here I Go Again on My Own

It’s been over 6 months since my last post. I’ve settled into my new role, and as the year winds to a close, I’ve been getting the itch to return to game making. Unfortunately, circumstances are such that I’ll be going it alone as Eric has retired from V-Toad Games.

Game programming and design is difficult, frustrating, greatly rewarding -but it’s not for everyone. What I learned from my last go at it was that programming is not painting by the numbers. Being able to complete an exercise no more makes you a programmer than following a recipe makes you a cordon bleu chef. There are core skills you have to master, and to do that, you have to be passionate enough to stick with it.

Eric really tried – I sincerely believe that. Nevertheless, I know all too well that bills must be paid, and can’t blame him for not having the energy to go home and learn something that he just wasn’t passionate about.

So why is being a solo project a problem for me? Many game developers, past and present, were/are one-man shows. I suppose it’s because I like feedback; I like to share what I’ve learned and bounce ideas off of other people because this helps me to reinforce and retain that knowledge.

As a consequence of my hiatus, I’ve all but lost everything I learned about GML, and will need to go through the lessons again to get back in the saddle. This time around should be much quicker, albeit lonelier.

“…Here I go again on my own…” – David Coverdale, Whitesnake