Now we will find some sounds to add to our game
Some examples can be found at the following sites:
http://github.grumdrig.com/jsfxr/
To save a sound right click on the link and save link as
We want to find sounds for:
attacking with sword
shooting bow
spring trap
When finding sounds it is best to use wav sounds for sound effects like sword, arrow and fire
mp3 sounds should only be used for background music
Sound Code explanations:
sound_play(index) Plays the indicates sound once. If the sound is background music the current background music is stopped.
sound_loop(index) Plays the indicates sound, looping continuously. If the sound is background music the current background music is stopped.
sound_stop(index) Stops the indicates sound. If there are multiple sounds with this index playing simultaneously, all will be stopped.
sound_stop_all() Stops all sounds.
sound_isplaying(index) Returns whether (a copy of) the indicated sound is playing. Note that this functions returns true when the sound actually plays through the speakers. After you call the function to play a sound it does not immediately reach the speakers so the function might still return false for a while. Similar, when the sound is stopped you still hear it for a while (e.g. because of echo) and the function will still return true.
It is possible to use further sound effects. In particular you can change the volume and the pan, that is, whether the sound comes from the left or right speaker. In all these cases the volume can only be reduced. These functions do not work for files that play through the media player (like mp3 files).
sound_volume(index,value) Changes the volume for the indicated sound (0 = low, 1 = high).
sound_global_volume(value) Changes the global volume for all sounds (0 = low, 1 = high).
sound_fade(index,value,time) Changes the volume for the indicated sound to the new value(0 = low, 1 = high) during the indicated time (in milliseconds). This can be used to fade out or fade in music.
sound_pan(index,value) Changes the pan for the indicated sound (-1 = left, 0 = center, 1 = right).
sound_background_tempo(factor) Changes the tempo of the background music (if it is a midi file). factor indicates the factor with which to multiply the tempo. So a value of 1 corresponds to the normal tempo. Larger values correspond to a faster tempo, smaller values to a slower tempo. Must lie between 0.01 and 100.
Shooting your arrow
Save this arrow sprite center it and turn it into an object call it oArrow
We will give the arrow speed and make it face the correct direction from the player object using a local variable. Local variables are used in one event only and take very little memory.
You want the animation for the attack sprites to end when the animation ends so you add this code to the Animation End Event to your character
To make your character shoot you need a projectile object so I will use an arrow
Create the object and center the sprite
Add an outside view event to your arrow object add the follow code
This code will make your arrow destroy itself if it goes outside your view. If you don't add this your arrows will kill enemy's anywhere in your room even though you can't see them
Outside view Event of oArrow
instance_destroy();
Add this to your characters Step Event to let you shoot arrows put this at the top in the //Get Input section
attack = mouse_check_button_pressed(mb_left);
Sword and bow attack sound
We will add sounds for both of these attacks.
Make sure the sounds are not too long you want them to be short sounds so they stop playing about the same time the animation ends so they don't over lap.
To make sure the sound only plays once we will start it in the Animation End Event
Change your Animation End code in your players object with this code
Since we are starting to use lots of if then statements in the Animation End event lets change it to a switch statement.
Switch statements are easier to follow and faster to process
Studio has different functions for sounds so I have included both codes
In studio to play a sound the function is built like this:
Animation End Event of your character
switch state
{
case "attackbow":
//When you create the arrow
var ID;
ID = instance_create_layer(x,y,"Instances",oArrow);
audio_play_sound(sndArrowShoot,10,false)
with (ID)
{
image_xscale = other.image_xscale; // makes arrow face same direction as you
hspeed = other.image_xscale*15; //Sets the arrow's speed to 10 or -10
}
break;
case "attackspear":
break;
}
canattack=0;
state="idle";
STEP 4 Add Sounds to Special Blocks
Spring Sound
Now to play this sound we go to your characters Step event and add this code to the bottom
Hurting Sound
Now to play this sound we go to your characters Step event and add this code to the bottom
Water Sound
Now to play this sound we go to your characters Step event and add this code to the bottom
Background Music
Now to play this sound in the background of the game that always plays go the the Create Event of your player and add this code to the bottom
Step Event of your character
//super jump block code
if place_meeting(x,y,oSpring)
{
vsp=-35;
oSpring.subimage=-1
if !audio_is_playing(sndSpring)
audio_play_sound(sndSpring,10,false)
}
Step Event of your character
// Hurt block
if place_meeting(x,y,oHurt)
{
hpamount -= 1;
if !audio_is_playing(sndHurt)
audio_play_sound(sndHurt,10,true)
}
else
audio_stop_sound(sndHurt);
Step Event of your character
// Slow block
if place_meeting(x,y,oSlow)
{
movefactor=.1;
if !audio_is_playing(sndWater)
audio_play_sound(snd_water,10,true);
}
else
{
movefactor = 1;
audio_stop_sound(sndWater);
}
Create Event of oPlayer
audio_play_sound(sndMusic,20,true)
If you can add sounds for any of the following you can earn bonus points
Hurting enemy
Getting hurt
Jumping
Enemy attack
etc.
STEP 5 Side to Side Enemy Create Event
You can add enemies that will move back and forth, fall off edges and are destroyed if you jump on their heads. Add the following to the create event of the enemy object
Create Event of monster
///Initialize Variables
dir = 1; // Makes the monster start moving Right
movespeed = 3; // Speed of monster
grav = 0.2;
hsp = 0;
vsp = 0;
points=100; // points you earn for killing monster
Destroy Event of Monster
score+=points; // Add points for killing monster
I used a wolf and called it oWolf
You can find your own sprites for your game online here is one spot spritedatabase.net
Some of these sprite sheets are harder to make into smooth animations so choose wisely.
This Wolf will be the parent monster for all others
Side to Side Enemy Step Event
The wolf will use the same code the player except instead of controlling it with keys it will change direction whenever it hits a wall.
Add this code to the step event of your enemy, it should look familiar its the same as your character without the keyboard inputs.
Remember that this code:
dir *= -1;
Will change the direction the enemy is moving.
Multiplying a variable by -1 switches the sign so it goes from right to left
Right is a positive direction
Left is a negative direction
Step Event of monster
//Set speed
hsp = dir * movespeed;
vsp += grav;
//Horizontal Collision
if (place_meeting(x+hsp,y,oBlock))
{
while(!place_meeting(x+sign(hsp),y,oBlock))
{
x += sign(hsp);
}
hsp = 0;
dir *= -1;
image_xscale = dir;
}
x += hsp;
//Vertical Collision
if (place_meeting(x,y+vsp,oBlock))
{
while(!place_meeting(x,y+sign(vsp),oBlock))
{
y += sign(vsp);
}
vsp = 0;
}
y += vsp;
//Enemy Collision
if (place_meeting(x,y,oPlayer))
{
if (oPlayer.y < y-sprite_height/2)
{
with (oPlayer) vsp = -global.jumpspeed;
instance_destroy();
}
else // Bounce back effect if hit without attacking
{
oPlayer.hpamount-=1;
if oPlayer.x > x
{
if place_free(x-32,y)
x-=32;
}
if oPlayer.x < x
{
if place_free(x+32,y)
x+=32;
}
}
}
We have health so we want to take away health from your character if a monster hits you and you fail to attack it.
We will also add a bounce back effect so the monster will bounce away from you when it hits you.
STEP 6 Create Jumping Enemy
We will now create Frog enemy save this sprite and create an object for the frog call it oFrog
We also want the parent of the frog to be the wolf. This will save lots of coding.
When you select the oWolf as the parent the frog.
Every object in the game can have a parent object, but what does this mean? Well, when an object has a parent, it can share code, actions and events with that parent. This is called "inheritance" and an object that has a parent is called a "child". But that's not all! You can also do checks and run code on parent objects which automatically include the child objects too which saves a lot of time and energy. Another way to look at a parent object is as a way to "group" objects together under the same umbrella and have them share certain things without loosing their own identity.
STEP 7 Jumping Enemy Create Event
The cool thing about code is we can use it over and over again to do the same thing. This is what we are doing in the enemies. The only difference is that instead of changing directions with keyboard keys we use the collisions with blocks.
Add this code to the Create event of your enemy.
Create Event of jumping monster
///Initialize Variables
dir = -1;
movespeed = 2.5;
jumpspeed=10;
grav = 0.2;
hsp = 0;
vsp = 0;
jump=0;
alarm[0]=60; // sets the alarm to jump 60 is once every two seconds change if you want
points=50;
STEP 8 Jumping Enemy Step Event
Add this code to the step event of your enemy.
Step Event of jumping monster
//Set speed
hsp = dir * movespeed;
vsp += grav;
// jumping code
if (vsp < 10) vsp += grav;
if (place_meeting(x,y+1,oBlock))
{
vsp = jump * -jumpspeed
jump=0
}
//Horizontal Collision
if (place_meeting(x+hsp,y,oBlock))
{
while(!place_meeting(x+sign(hsp),y,oBlock))
{
x += sign(hsp);
}
hsp = 0;
dir *= -1;
image_xscale = dir;
}
x += hsp;
//Vertical Collision
if (place_meeting(x,y+vsp,oBlock))
{
while(!place_meeting(x,y+sign(vsp),oBlock))
{
y += sign(vsp);
}
vsp = 0;
}
y += vsp;
//Enemy Collision
if (place_meeting(x,y,oPlayer))
{
if (oPlayer.y < y-sprite_height/2)
{
with (oPlayer) vsp = -global.jumpspeed;
instance_destroy();
}
else // Bounce back effect if hit without attacking
{
oPlayer.hpamount-=1;
if oPlayer.x > x
{
if place_free(x-32,y)
x-=32;
}
if oPlayer.x < x
{
if place_free(x+32,y)
x+=32;
}
}
}
STEP 9 Jumping Enemy Alarm Event
We want your frog to jump every 2 seconds so we will add an alarm event to do this.
Add this code to the alarm 0 event of your enemy.
An alarm is a timer once the timer goes off you can tell it to do something and reset the timer so it will do it again and again.
alarm[0] Event of jumping monster
jump=1;
alarm[0]=60;
STEP 10 Enemy Arrow
Enemy That Fights Back Arrow Object
You want your enemy to fight back? You first need to make a projectile I will use an arrow. Find a sprite and turn it into an object. Name the object oEnemyArrow
Remember to center your sprite
Enemy That Fights Back Arrow Object
To make the arrow destroy itself when it hits a wall add a collision event this with a wall and a to destroy self which is instance_destroy()
You also don't want the enemies to shoot at you from anywhere. So we will destroy the arrow if it is NOT in your view. So in other words if you cant see the enemy his arrows are instantly destroyed.
.
Collision Event with obj_block of arrow object
instance_destroy();
Outside View Event of the arrow
instance_destroy() // destroys the arrow if not in your view
STEP 11 Shooting Enemy
Create and Animation End Event
Remember to make the wolf the parent of the skeleton and all the rest of the enemies you make
We will make the enemy move and be affected by gravity just like you except he moves by it's self. This enemy will also shoot.
Add this code to the Create event of your enemy.
We will use an alarm to make the skeleton shoot every 3 seconds. Remember 30 steps is 1 second.
In the Animation End event we have to do something we haven't talked about yet. Instance ID's.
Every instance that you create is given a number that is used internally to identify this instance and this variable is what you can use to reference it.
So since we want to have lots of arrows shot in the room we can't identify it by its object name we must use its ID.
We will also pass the variables to the arrow from the creating skeleton. This way the arrow will be shot in the same direction as the skeleton.
Shooting Enemy Step Event
Add this code to the step event of your enemy.
We are also using a different movement system for the monster.
hspeed is horizontal speed.
We will use states in this skeleton just like your character. Remember by using states we can give it different sprites.
We have a walking sprite and a shooting sprite.
Create Event of fighting monster
///Initialize Variables
hspeed = 2;
vsp=0;
grav = 0.2;
alarm[0]=90;
state="walk";
points=250;
Animation End Event in obj_skeletonArcher
if state=="shoot"
{
//When you create the arrow
var ID;
ID = instance_create_layer(x,y,"Instances",oEnemyArrow);
with (ID)
{
image_xscale = other.image_xscale; // makes arrow face same direction as skeleton
hspeed = other.image_xscale*10; //Sets the arrow's speed to 10 or -10
}
state="walk";
hspeed=choose(2,-2) // randomly selects either right or left movement
}
Step Event of fighting monster
//Set speed
vsp += grav;
//Horizontal Collision
if (place_meeting(x+hspeed,y,oBlock))
{
hspeed *= -1;
}
//Vertical Collision
if (place_meeting(x,y+vsp,oBlock))
{
while(!place_meeting(x,y+sign(vsp),oBlock))
{
y += sign(vsp);
}
vsp = 0;
}
y += vsp;
//Enemy Collision
if (place_meeting(x,y,oPlayer))
{
if (oPlayer.y < y-sprite_height/2)
{
with (oPlayer) vsp = -global.jumpspeed;
instance_destroy();
}
else // Bounce back effect if hit without attacking
{
oPlayer.hpamount-=1;
if oPlayer.x > x
{
if place_free(x-32,y)
x-=32;
}
if oPlayer.x < x
{
if place_free(x+32,y)
x+=32;
}
}
}
// Sets image to face correct direction
if hspeed>0 image_xscale=1;
if hspeed<0 image_xscale=-1;
switch state
{
case "walk":
sprite_index=sSkeltonWalk;
break;
case "shoot":
sprite_index=sSkeletonArcher;
hspeed=0;
break;
}
STEP 12 Shoot every 3 seconds
Shooting Enemy Alarm Event
We want your skeleton to shoot every 3 seconds so we will add an alarm event to do this.
Add this code to the alarm 0 event of your enemy.
An alarm is a timer once the timer goes off you can tell it to do something and reset the timer so it will do it again and again.
alarm[0] Event of fighting monster
state="shoot";
alarm[0]=90;
Use the sprite for your castle archer you can use the same arrow as the regular skeleton archer
STEP 13 Castle Archer
Now we will make another type of archer. This one will not move but will aim at you. You can put these in hard to reach spots and they will be annoying monsters.
This archer will shoot every three seconds.
We will use a variable called subimage to make the character animate only when shooting.
Remember if you select -1 for the subimage of any sprite it will animate it. If use 0 for the subimage it will only draw the first subimage of the sprite.
In the step event we make the castle archer face your character by checking the x coordinate.
The Animation end event will create an arrow and aim it at your character by using the code "move_towards_point"
move_towards_point( x, y, sp );
Create Event of obj_castleArcher
///Initialize Variables
alarm[0]=90;
state="idle"
subimage=0;
points=350;
dir=-1;
Alarm Event for Castle Archer
state="shoot";
alarm[0]=90;
Step Event of Castle Archer
//Enemy Collision
if (place_meeting(x,y,oPlayer))
{
if (oPlayer.y < y-sprite_height/2)
{
with (oPlayer) vsp = -global.jumpspeed;
instance_destroy();
}
else // Bounce back effect if hit without attacking
{
oPlayer.hpamount-=1;
if oPlayer.x > x
{
if place_free(x-32,y)
x-=32;
}
if oPlayer.x < x
{
if place_free(x+32,y)
x+=32;
}
}
}
// Sets image to face correct direction
if x< oPlayer.x dir=1;
if x> oPlayer.x dir=-1;
switch state
{
case "idle":
subimage=0;
break;
case "shoot":
subimage=-1;
break;
}
Animation End Event for Castle Archer
if state=="shoot"
{
//When you create the arrow
var ID;
ID = instance_create_layer(x,y,"Instances",oEnemyArrow);
with (ID)
{
image_angle = point_direction(x,y,oPlayer.x,oPlayer.y)
image_xscale = other.image_xscale; //arrow faces same direction
move_towards_point(oPlayer.x, oPlayer.y, 10); // moves toward you
}
state="idle";
}
Draw Event for Castle Archer
draw_sprite_ext(sprite_index,subimage,x,y,dir,1,0,c_white,1);
Use these sprites for the catapult and the rock make objects for both
Step 14 Catapult Enemy
We can also make a lobbing catapult enemy we will use a script for this.
Scripts are the way in which GameMaker: Studio permits you to design your own functions. You can use code in a number of places within GameMaker: Studio, from objects, to rooms and instances, and there are a number of built in functions that make your life easier when programming, however it is often necessary for you to create your own functions to do a specific task, or to condense a large section of code into a more manageable chunk, or even to be able to re-use a particular code block in many different places. That is why GameMaker: Studio gives you the ability to create scripts.
Create an object for the catapult and the rock center both sprites.
Create Event of oCatapult
alarm[0]=90;
spd=0;
subimage=0;
points=1000;
dir=-1;
Alarm Event of oCatapult
//Create projectile
var angle,target,ID,g;
target=oPlayer; // target of catapult
g=0.3; // gravity
angle=calc_angle(target.x-x,target.y-y,spd,g); // run script get angle back
if(angle!=-1)
{
subimage=-1;
ID = instance_create_layer(x,y,"Instances",oRock);
ID.direction=angle;
ID.speed=spd;
ID.gravity=g;
spd=0;
alarm[0]=90
}
else
{
spd+=1;
alarm[0]=1;
}
Step Event in oCatapult
// Sets image to face correct direction
if x< oPlayer.x dir=1;
if x> oPlayer.x dir=-1;
Animation End event for oCatapult
subimage=0;
Draw Event for oCatapult
draw_sprite_ext(sprite_index,subimage,x,y,dir,1,0,c_white,1);
calc_angle script
//calc_angle(xdist,ydist,speed,gravity)
var xx,yy,v,g;
xx=abs(argument0);
yy=-argument1;
v=sqr(argument2);
g=argument3;
var d,s;
d=sqr(v)-g*(g*sqr(xx)+2*yy*v);
s=sign(d);
if(s==-1)
return -1;
if(xx==0)
return 90;
var a;
a=(arctan((v+sqrt(d))/g/xx))/pi*180;
a=(a+90)*sign(argument0)-90;
return (a+360) mod 360;
Outside View Event of the Rock
instance_destroy() // destroys the rock if not in your view
Use these sprites to make your flying enemy and the egg that will drop on you call them oEagle and oEgg
STEP 15 Flying Enemy Object
You want an enemy that fly's and drops eggs on you?
Find a sprite and create an object for that flying creature
Remember to center your sprite
Flying Enemy Object Create Event
You want to give you flying enemy some variables to make him fly. We don't want gravity to effect him so we omit that variable.
Notice I increased the speed to 2 and added an alarm so that eggs will drop every 2 seconds.
Create Event of Flying monster
///Initialize Variables
hspeed = 5;
alarm[0]=90;
points=1000;
Step Event of fighting monster
//Horizontal Collision
if (place_meeting(x+hspeed,y,oBlock))
{
hspeed *= -1;
image_xscale=sign(hspeed);
}
//Enemy Collision
if (place_meeting(x,y,oPlayer))
{
if (oPlayer.y < y-sprite_height/2)
{
with (oPlayer) vsp = -global.jumpspeed;
instance_destroy();
}
else // Bounce back effect if hit without attacking
{
oPlayer.hpamount-=1;
if oPlayer.x > x
{
if place_free(x-32,y)
x-=32;
}
if oPlayer.x < x
{
if place_free(x+32,y)
x+=32;
}
}
}
alarm[0] Event of fighting monster
instance_create_layer(x,y,"Instances",oEgg);
alarm[0]=90;
STEP 16 Flying Enemy's Egg Object
Now create an egg object so find an egg sprite and turn it into an object
Egg Object Create Event
When the egg is created we want it to drop down so add vspeed=10; to create event
Egg Object Collision Event
When the egg collides with a block you want it to be destroyed so add a collision with obj_block and add this code.
Create Event of egg
vspeed=10;
Outside View Event of the Egg
instance_destroy() // destroys the egg if not in your view
Collision with block Event of egg
instance_destroy();
STEP 17 AI Enemy Chase, Attack, Idle and Hit
Now we will make a different type of enemy an enemy that possesses AI or artificial intelligence. We will use states and scripts to accomplish this.
Our enemy will have 4 states
idle
chase
attack
hit
You can go here if you want to find your own sprite spritedatabase.net
We will need three different sprites for these states we can use chase sprite for idle and not animate it
Create an object for this monster and select the walking sprite for it sprite and mask
Also modify the mask so the collision is only with the body of this monster
Create sprites for these 3 different states for the mini boss
Then create one object call oViking
STEP 18 Viking Mini Boss
The Viking is a mini Boss he has cool animations and can perform more than one task based you the distance to you.
We will use states in conjunction with scripts. Using scripts allows us to re-use these scripts with multiple monsters.
We just have to set things up correctly, so in the create event we want to use variables for all the items that need to change in the scripts. So in this case the sprites and the distance to chase and attack.
Create Event for oViking
///Initialize Variables
movespeed=3; // speed of monster
points=1500; // points for killing
state="idle"; // sets the state to idle
subimage=0; // subimage to be drawn -1 for animated 0 for non-animated
chaseD=300; // monster will chase you when you get close
attackD=50; // monster will attack when you get close
image_speed=.5; // slows down animation
chaseSprite= //put in the names of your three sprites here
attackSprite=
hitSprite=
Step Event for oViking
if distance_to_object(oPlayer) < chaseD && distance_to_object(oPlayer) > attackD
{
state="chase";
}
if distance_to_object(oPlayer) < attackD
{
state="attack";
}
if distance_to_object(oPlayer) > chaseD
{
state="idle";
}
if place_meeting(x,y,obj_oPlayerplayer)
state="hit";
// Check state of enemy and change sprite
switch state
{
case "chase":
scr_chase(chaseSprite);
break;
case "attack":
scr_attack(attackSprite);
break;
case "idle":
scr_idle(chaseSprite);
break;
case "hit":
scr_hit(hitSprite);
break;
}
Draw Event for oViking
draw_sprite_ext(sprite_index,subimage,x,y,image_xscale,1,0,c_white,1);
STEP 19 AI scripts
We will create 4 different scripts that will handle what a monster will do when in the four different states:
scr_chase
function scr_chase(_sprite)
{
sprite_index=_sprite;
subimage=-1;
// Sets image to face correct direction
if x< oPlayer.x image_xscale=1;
if x> oPlayer.x image_xscale=-1;
//Move toward player
hspeed=image_xscale*movespeed;
}
scr_attack
function scr_attack(_sprite){
sprite_index=_sprite;
subimage=-1;
// Sets image to face correct direction
if x< oPlayer.x image_xscale=1;
if x> oPlayer.x image_xscale=-1;
hspeed=0;
}
scr_idle
function scr_idle(_sprite){
sprite_index=_sprite;
subimage=0;
// Sets image to face correct direction
if x< oPlayer.x image_xscale=1;
if x> oPlayer.x image_xscale=-1;
hspeed=0;
}
scr_hit
function scr_hit(_sprite){
sprite_index=_sprite;
subimage=-1;
// Sets image to face correct direction
if x< oPlayer.x image_xscale=1;
if x> oPlayer.x image_xscale=-1;
hspeed=0;
}
STEP 20 Hurt the Enemy's
When you attack an enemy with your bow or sword you want them to be destroyed and give you some points.
To do this we will have a parent monster which will be the wolf . That way we don't have to code collisions with all objects. Parent objects save lots of time in games that have lots of different monsters.
So open your Wolf monster and add points to the create event, This variable is how many points you will gain for destroying the monster.
In fact it would be a good idea to add points variable to all your monsters at this time. Make them all different amounts depending upon the difficulty of the monster.
Arrows Hurt the Enemy's
When you attack with your bow you want to destroy the enemy, the arrow and get some points.
So go to the wolf object and add a collision event with the arrow. The following code will do the three things we would like.
Notice the with other code. This code destroys the other object the wolf collided with, Which in this case is the arrow.
Remember The += operation means add points to the score.
Now make all other enemies have the wolf as their parent.
Create Event of wolf monster
///Initialize Variables
dir = 1;
movespeed = 3;
grav = 0.2;
hsp = 0;
vsp = 0;
points=100; // this is how many points you gain for killing this monster
Collision with arrow Event in wolf monster
instance_destroy();
with other
instance_destroy();
STEP 21
Spear Hurts: the Animation
When you attack with your spear or sword you want to destroy the enemy and get some points.
This however has some problems we have to think about.
We only want the spear to hurt the enemy not your whole body. We also want the enemy to hurt you if it hits you from behind.
So we only want the spear part of the animation to damage the enemy and not any other part of your attack animation.
To do this we have to make a new object with a new sprite that only contains the spear but not your characters body.
Duplicate the spear attack sprite erase out all the body from each frame of the animation and center it.
As you can see from the pictures only the last two frames of the sword attack animation will hurt the enemy.
Remember to keep all the blank animations in the new sprite so the two animations sync.
Also this is a good time to change the mask of your character. The mask is what handles the collisions in your character. So if we attack while jumping our sword will get stuck in a wall to avoid this make your idle sprite your mask.
Original animation
Erased animation notice only the last two frames actually have anything in them keep the other frames blank so the animations sync
Erased animation
Erased animation notice only the last two frames actually have anything in them keep the other frames blank so the animations sync
STEP 22
Spear Hurts: the Create Event
Make an object with the spear animation and call it oSpearAttack. Make this new object invisible by un-checking visible
To make sure the spear object syncs with your character movement we need to use a draw event and draw the spear attack object at the location of the player.
Now we also have to make your character create this sword object when you attack. So open your characters Step Event and find the code that sets your state to "attackspear"
Replace the existing case code for attackspear with this notice we check if a obj_spearAttack object doesn't exist before creating another
We also use the with construct to pass variables to the obj_spearAttack object.
Animation End Event of spear object
instance_destroy();
Draw Event of oSpearAttack
draw_sprite_ext(sprite_index,-1,oPlayer.x,oPlayer.y,image_xscale,1,0,c_white,1);
Step Event of your character
// attack state
if canattack==1 && wep=="spear" && !instance_exists(oSpearAttack)// You must press the attack button and no spear object can exsist
{
state="attackspear";
var ID;
ID = instance_create_layer(x,y,"Instances",oSpearAttack);
with (ID)
{
image_xscale = other.image_xscale; // makes spear same direction as player
}
}
Animation End event of oSpearAttack
instance_destroy();
STEP 23
Spear Hurts: the Enemy's
Now open the wolf object and add a collision event with the oSpearAttack
You want to destroy the enemy and add points to your score.
Collision with spear Event of wolf monster
instance_destroy();
STEP 24
Monster Health and Battle Stats
Now we will add health add battle stats to your monsters this will add levels of difficulty for each monster and require you to hit it multiple times.
Instead of using health bars for each monster will will draw the hit-points that each monster has above his head.
We need to add some variables to your oWolf and all the rest of your monsters
The create event variables need to be added to all your monsters add the two Health variables and the attack, armor and canHit to all monsters in your game tougher monsters will have more hit-points and greater armor and attack.
Click on this link and fill out our monster stat sheets for all the monsters in your game. Make a different copy of the monster stat sheet for all your monsters
This online tool can give you ideas for your monsters
Based on the monster stat sheets add hitpoints, armor and attack with all enemies.
You need to have at least 10 different monsters you can make different types of jumpers, archers, side to side monsters just duplicate then change sprites and stats.
Also add an alarm event to your parent monster. This variable will be used in the battle script later. Also the other monsters which have an alarm event add that variable to those alarm events as well.
Remember if you monster has its own alarm we will need to add the alarm info to that monster as well.
Create Event of oWolf
// Health
hpmax=39
hpamount = hpmax
//Battle Stats
attack=6
armor=14
canHit=true;
Draw Event of oWolf
draw_self();
draw_text(x,y-sprite_height/2-10,string(hpamount));
Alarm Event for parent monster
canHit = true;
alarm[0]=10
Make your own animation or use this on for your sHits sprite
STEP 25
Monster Hit animations
To give you a visual indication of what type of hit you had on the monster will will create a new sprite with three subimages
Hit
Miss
Crit
Create your own sprite or use mine it is 32 x 16 and centered name it sHits
Now create three objects with this sprite
oHit
oMiss
oCrit
These objects will have a create, alarm and a draw events
The create event will set the subimage correctly so make sure you set it correctly 0 in hit object 1 in miss object and 2 in crit object
The alarm will destroy the object after 1 second and the draw event will draw the correct sub-sprite
Create Event for oHit oCrit and oMiss objects
subimage=0; // this goes in hit object
subimage=1; // this goes in miss object
subimage=2; // this goes in crit object
alarm[0]=30;// add this to all three objects
vspeed=-2;
Alarm Event for oHit oCrit and oMiss objects
instance_destroy();
Draw Event for oHit oCrit and oMiss
draw_sprite(sHits,subimage,x,y)
STEP 26 Battle System Flow Chart
We will now create a battle system for your monsters. This system will use armor and attack to determine how much damage you do to the monster and how much damage the monster does to you.
This system check two things attack and armor and compares them. If attack is greater than armor you will damage your opponent.
Damage is the the difference between attack and armor.
The system also has a random component called critical.
We randomly produce a number from 1 to 20 if a 18 or higher is produced a critical hit is taken.
Critical hits do double damage.
We can also hit an enemy on every roll of a 20. So no matter how high the armor is of an enemy you have a chance to hit it.
Flow Charts are essential to break down what happens in a complex script.
Now Make your own Flow Chart we will do it in the simplest way here are your directions turn into the google class room when done
STEP 27 Battle System Script
The script uses two variables attack and armor so all the monsters in the game need to have these two variables.
AttackDamage script
/// AttackDamage(other.attack,armor);
/*
argument(0) attack from player
argument(1) armor from enemy
*/
Batattack=argument0;
Batarmor=argument1;
roll=0
damage=0
hitdamage=0
roll=irandom_range(1,20); // random # to determine hit, miss or critical and bonus attack damage
damage=Batattack-Batarmor; // gets damage
if damage<0 // if damage is less than 0 sets to zero
{
damage=0;
hitdamage=0 ;
if roll=20 // roll of 20 always hits for damage
{
hitdamage=(damage+1)*2; // calculates new damage if 20 is rolled
instance_create_layer(x,y,"Instances",oCrit);
return(hitdamage);
}
instance_create_layer(x,y,"Instances",oMiss);
return(hitdamage);
}
hitdamage = roll + damage;// Calculates total damage
if roll >=18 // Checks if you hit with a critical
{
instance_create_layer(x,y,"Instances",oCrit);
hitdamage*=2;
return(hitdamage);
}
instance_create_layer(x,y,"Instances",oHit);
return(hitdamage);
STEP 28 Parent Monster collisions with spear and arrow
Add collision events for both the spear and the arrow objects.
Collision Event with obj_spear
if canHit
{
canHit = false;
alarm[0] = 10;
damage=AttackDamage(global.attack,armor);
hpamount-=damage;
}
if hpamount<0
{
instance_destroy();
}
Collision Event with obj_arrow
with (other) instance_destroy();
damage=AttackDamage(global.attack,armor);
hpamount-=damage;
if hpamount<0
{
instance_destroy();
}
Alarm Event for Parent Monster
canHit = true;
alarm[0]=10
We also need to add an alarm event to the parent so that it can only be attacked every 10 steps of the game other wise you could hit the enemy faster than the attack animation.
Upgrades and New ideas
Now you can start to add new things to your game here are some ideas to explore
Links for Tutorials for different game & Links to upgrade your Game