Wednesday, 10 December 2014

Unit 22 & 72 - Platform game development Blog - Concept art for characters, weapons and backgrounds

Short synopsis
Max must set out on a quest through several nature filled environments to recover the diamonds that a giant magpie has stolen. He is an inventor and bug exterminator with a number of different weapons at his disposal.

Max concept design
Concept designs for Max, the main character. I went through a number of designs, taking the character from a humble gardener to more of an adventurer. I felt that the sheer amount of foes and the adventure laying ahead of Max would call for a tougher, more resilient character than his original, softer incarnation (top left).
I can’t say I am entirely happy with Max at this stage. I like the certain elements like his goggles and general demeanor, but feel he could be more iconic. This will be achieved by making certain aspects more exaggerated like his clothes or hair. I will continue his evolution with another design before the final sprite is produced. I also have a clearer idea of the art direction now because of other concept art I have produced for this game since drawing him (i.e, the insects and magpie.)

The sprites in game will likely be PNGs as they will cater for transparent areas around them and be optimized for best performance.
Weapon designs
The bug sprayer design for Max is as follows. It is an upgradeable item with different effects depending on which version you have at that time. From top left and working along each row:

Gas sprayer: Basic weapon, short range. Stuns enemies. Infinite use, does not require a refill.
Chemical shot: Stronger attack, projectile weapon so has longer range.  Stuns enemies. Short use, requires a refill
Smoke machine: For use on bees and wasps.  Stuns enemies. Short use, requires a refill.
Flame thrower: For use on all insects. Destroys insects. Short use, requires a refill.
Bug shot: Extremely powerful rapid fire weapon that shoots small seeds.. Destroys large groups of enemies. Short use, requires a refill.
Bug copter: Means player can travel upwards infinitely without jumping. Drops bombs that destroy enemies. Infinite use.

Weapons will be GIFs or PNGs as they have transparent areas around them - they will be tiny files, around 65 x 65 pixels, and have multiple views of them depending on what the player is doing at the time (for example backpack weapons may be facing in different directions.)
Background designs
Various hand painted backgrounds for each level. They are hand painted to allow the more ‘sketched style’ sprites to ‘pop out’. They will be displayed onscreen as optimized JPEGs to keep the file size to a minimum and still allow for good performance on screen.
Insect enemy designs
Various concept designs for bugs and insect enemies. They represent the foes that Max will face on his journey to recover the stolen diamonds. The finished art style will be very much like the magpie enemy - large black outlines and simple shaded colors to allow them to stand out from the hand painted backgrounds. This will give an ‘animated feature film’ effect, and should produce a very definite art style.

They will be PNGs in game and JPEGS in the cut scenes. JPEGs support a great deal of colors and detail, so will be perfect for storytelling and rich graphics between levels.
Magpie concept design
A full size drawing of the main villain in the game, a magpie. She is queen of her treetop domain, crafty and a thief, hence her expression and personality. This heavy black line style drawing style will help the sprite to stand out from the backgrounds (see diagram in the top right hand corner). The solid, cel - shaded artwork style will also lend itself to ‘pin-puppet’ type effect when it comes to animation. For example, the wing can be cut out and over laid over the bird’s body with a single joining point where rotations can occur. This will lead to the effect of the wing flapping smoothly. The same effect could be applied to the head, tail and beak. The animation is essentially 2D with parts being animated to fool the eye into thinking it is more 3D than what it actually is.

The sprites in game will likely be PNGs as they will cater for transparent areas around them.

Monday, 8 December 2014

Unit 22 & 72 - Platform game development Blog - Diamond collection design

I am still working with the test level and the place holder sprites and objects I have created. 

I have programmed the game to have some kind of block to the exit that is only removed after the player collects all the diamonds on the level. In short the code is set to recognize that when all the instances of blue diamonds = 0, the block will disappear when it is touched. The pictures below illustrate the process of this:

The player must collect all the blue diamonds. The black block with the 'X' represents a block that will disappear after all the diamonds are collected.

If the player collides with the block when there are diamonds left to collect, the block will not disappear.

When all the diamonds are collected, the instances of them will be set to 0. The block will then disappear when the player collides with it.

Monday, 1 December 2014

Unit 22 & 72 - Overcoming problems during development

I have decided to tackle the side of things I am less comfortable with first - namely the logic of Game Maker and it's interface. I have built some dummy sprites, objects, and a room:

Test sprites to help me to get to grips with Game Makers' gravity. I know can substitute these for the real game sprites later on. At the moment, understanding gravity is key.

First problem: friction between player and platforms

One of the first problems I have encountered during the development of my platform game concerns my main sprite 'sticking' to platforms. Why this is, I am not sure. I tried altering bounding boxes around the sprites. making them more precise in the hope that this could solve the problem. So far, nothing. I can only move left and right when I jump in the air. This implies that the problem is in the relationship between sprites and platforms:

My sprite 'sticking' to platforms and being unable to move

My sprite can jump fine, and even move left and right in the air.

Solving the problem - 3/12/14

Eventually, using this short script, I semi solved the problem of gravity and friction. The first step was to create several variables: gravity, horizontal speed, vertical speed, jump speed, and move speed 

In player object : CREATE EVENT
grav = 0.2;
//Horizontal variable
hsp = 0;
//Vertical variable
vsp = 0;
//How fast to jump and move
jumpspeed = 8;
movespeed = 4;

The next step was to create a short script that first checks if certain keys have been pressed: Escape to exit game, left, right or up to jump. Following this, the code checks to see if left and right are pushed together. If so, the movement cancels out and does nothing. This is checked by left and  right both equaling 1. move will equal 1. If both keys are pushed at the same time move will equal 2 (1 + 1) and the movement cancels out.

Next, the horizontal move speed (hsp) is calculated. This is worked out by first checking to see if left or right has been pressed . hsp is initially set at 0. If left or right has been pressed it sets to 1.

hsp then has a new value applied to it using move (1 due to the playing pushing left or right) * movespeed (4). So, 1 * 4 = 4. hsp is now set to 4.

Next gravity is worked out. grav is already set to 0.2. Every time the player pushes up to jump, 0.2 will be added until it reaches a maximum of 10. After this the player will fall back to the ground. The code for this is worked out via a kind of loop - what the code is saying is:

"As long as the vertical speed is less than 10, take vsp (0.2) and add 0.2 every time up is pushed until it reaches a maximum total of 10. After this a gravity of 10 will cause the player to fall back to the ground."

If the player is already on the ground and jump has not been pressed, vsp = 0. Once up is pushed (so 1 is set) vsp is assigned a new value - 1 * -8.
Code inserted into player object: 

In player object : STEP EVENT
// End game

if keyboard_check(vk_escape){game_end()}
// checks to see if key has been pushed
// this does not move player
//if pushed key_right = 1
key_right = keyboard_check(vk_right);

//if pushed key_left = 1
key_left =- keyboard_check(vk_left);

//if pushed key_jump = 1
key_jump = keyboard_check_pressed(vk_up);
//move is a temp variable 
// move = 1 for left or 1 for right
//if move =  2 cancels out movement  if left and right are pushed
move = key_left + key_right;

//hsp = if key_right or key_left has been pushed hsp =1
//move already = 1 from left or right  pushed
//1 = 1 * 4  up speed
hsp = move * movespeed;
//if you have pushed up gravity "0.2" will be added until to vsp =10
// then the play will drop
if (vsp <10){vsp += grav;}
//if your player is already on the ground vsp = 0 until up is pushed
if (place_meeting(x,y,obj_blk_4))
    // 1 = 1 + - 8 down speed
    vsp = key_jump * - jumpspeed

// co-ordinates of player on the screen
x += hsp;
y +=vsp;

The resulting problem of using this script was yes, the player moved, yes the player jumped, but unfortunately there was a 'sticking' issue when the top of the player hit the bottom of blocks. This was unacceptable to me, and looking at the code I felt sure that there must be a more streamlined solution.

The issue is finally solved - 9/12/14

I worked towards and eventually achieved the solution by writing this code and inserting it into the player object:

Comment: // initialise variables

grav = 0.2;   // (gravity)
hsp = 0; // (horizontal speed - set to empty because initially, it is just a container)
vsp = 0; // (vertical speed - set to empty because initially, it is just a container)
jumpspeed = 7; // (the amount of speed that will be added to the object in the up direction when we jump)
movespeed = 4; // (the amount of pixels that we move left and right when we press those keys)


Add Event
Step (This means that these events carried out by the object will happen every single frame of the game)
Drag in code box into actions panel

Add comment // get the player's input

Check player movement inputs - this is done by assigning the results of keyboard checks to variables.

Type this into the code box:

key_right = keyboard_check(vk_right);
// if key is pressed, this variable will equal 1, otherwise it will equal 0

key_left = -keyboard_check(vk_left);
// minus before keyboard check - this mens it will equal 0 or -1

key_jump = keyboard_check_pressed(vk_space);
// pressed means the computer checks to see if the button was pressed, but it
// was not pressed the frame before - i.e, literally just pressed jump button.
// Means you can't just hold the jump key down to continually jump

// React to inputs
move = key_left + key_right;
// -1 if left key is pressed, 1 if right key is pressed and 0 if neither is pressed
// If both are pressed it still equals 0

hsp = move * movespeed;
// As move (shown above )equals -1 or 1 and move speed = 4, this should set hsp in this instance to either - 4 or 4

if (vsp < 10) vsp += grav;
// vsp will add 0.2 to itself, up to a maximum of 10. This controls the falling rate
// of the player, otherwise the onscreen sprite would just pick up speed with every frame it falls
// with no limit

if (place_meeting(x,y+1,obj_wall))
// This is asking "Is there an object called wall 1 pixel below the player"?
    vsp = key_jump * -jumpspeed;
    // If jump key is pressed, this should set the jumpspeed to -7. If not, 0.

// Collision - Ordinarily in GM if you've collided with something, it's already too late
// What you need to do is get into the midst and logic of saying to the computer we are "ABOUT"
// to collide, do something NOW
// For example, our hsp here = 4. If we are three pixels from a wall, we need to ask the computer
// are we about to hit a wall to our right?
// If we are 3 pixels away, we move 1 pixel at a time until we can't move any further without hitting
// the wall and we reduce our speed to 0


// Horizontal collision
if (place_meeting(x+hsp,y,obj_wall))
    while (!place_meeting(x+sign(hsp),y,obj_wall))
   // sign will return 1 or -1 depending on whether hsp is positive or negative
   // so this would equate to x left or x right (-1 left or 1 right)
   // sign will multiply this by the horizontal speed -1 * 4 or 1 * 4. This gives the current amount of
   // pixels to move left or right for the horizontal speed.
  // So what you are saying is, if the player is not touching obj_wall, keep on moving 1 pixel
  // until it does. At which point reduce speed to 0 and stop. Same principle goes for vsp below.  
        x += sign(hsp);

    hsp = 0;

x += hsp;
// add horizontal speed to x co ordinate - move sprite left or right

// Vertical collision
if (place_meeting(x,y+vsp,obj_wall))
    while (!place_meeting(x,y+sign(vsp),obj_wall))
    // sign will return 1 or -1 depending on whether hsp is positive or negative
        y += sign(vsp);

    vsp = 0;
y += vsp;
// add vertical speed to y co ordinate - move sprite up and down

This code works perfectly and solves the problem - pixel perfect gravity. I went on to apply this code to every surface in the game to create a solid, interactive world.


More problems to write about in future blogs -
Sprite collision with walls and blocks (show code mistake and explain why)
Sprite resizing
Platforms and destructible. Switching from one state to another - the way I solved the problem.
Platform generator and its problem - sticking and turning a positive into a negative
Choosing the right power ups
Choosing and designing the games enemies

Creating Joe-bot and his reason to be in the game.
Fine tuning.