 ### Sonic Game Engine

To understand how to create a Sonic Game Engine you must first understand the physics of sonic the hedgehog and how he moves along a curves using basic collision detection by angles using sin and cos.

A collision circle object is used to detect objects and terrain which is used only for an x and y position at end, sonic will be drawn over the object at angles rounded to the nearest 45 degree increment.

Sin and Cos is used to locate precise X and Y positions by angle for object detection. Cos represents horizontal positions in X to current angle. Sin represents vertical positions in Y to current angle.

At object angle 0 a variable angle can be used to locate a position by sin and cos angle. This can only work by the use of code degtorad which converts degrees to radians for game maker.  Just change the angle to change the position to a circular path.

for example

// Circle Radius of 10
//==========================
if place_meeting( x + cos( degtorad( angle )) * 10 , y - sin( degtorad( angle )) * 10 , land_object )
{ do codes here }
The chart below is a point of reference on which direction to apply sin and cos which includes corner positions.

for example

// Bottom Right Corner
//==========================
if place_meeting( x + cos( degtorad( angle )) * 10 + sin( degtorad(angle)) * 10  ,
y - sin( degtorad( angle )) * 10 + cos( degtorad(angle)) * 10 , land_object )
{ do codes here }

Sonic moves horizontally by the calculation of sin and cos according to the current angle to the ground multiplied by the x_speed which determines the next X , Y position

for example

// X Movement
x += cos( degtorad(angle)) * x_speed
y - = sin( degtorad(angle)) * x_speed
This is a list of major collision positions during a calculation of sonic falling to the ground.
A basic collision detection keeps the circle out of the walls.

P1 and P2 detect weather these two position detect the ground. If they do detect the ground together they perform a calculation to change the angle variable to the angle of the ground. This angle is change by first creating 2 positions inside of the circle. If there is no collision between these two points the position is change down 1 pixel position. These two positions will eventually collide with land at two different positions. The new angle is then gained by a point_direction between these two new positions.

This new angle is then used for all angled collision detection like the slope position which will keep sonic to the ground and out of the ground according to the direction of sin and cos angle.

When P1 and P2 do not collide together the angle calculation is not performed and the angle is change to angle 0 and x_speed and y_speed are exchanged if the angle was not = to 0.

### Drag and Drop Into Game Maker Language

'Move Fixed'

'Move Free'
motion_set(direction,speed);

'Move Towards'
move_towards_point(x,y,speed);

'Speed Horizontal'
hspeed=speed;

'Speed Vertical'
vspeed=speed;

'Set Gravity'
gravity_direction=direction;
gravity=amount;

'Reverse Horizontal'
hspeed=-hspeed;//actual code.

'Reverse Vertical'
vspeed=-vspeed;//actual code.

'Set Friction'
friction=amount;

x=value;
y=value;

x=xstart; //actual code.
y=ystart;//actual code.

move_random(1,1);
//actual code. The 1 and 1 in the code are the hsnap and vsnap positions.

'Align to grid'
move_snap(hsnap,vsnap);

’Wrap Screen’
move_wrap(hort,vert,margin);
// This code should be placed in the outside room event. Set hort (horizontally)and vert (vertically) to either 1 for true or 0 for false. Set margin to how far outside the room the instance must be before the action happens.

'Move to Contact'
move_contact_solid(dir,maxdist)
//for solid objects

move_contact_all(dir,maxdist)
//for non solid objects, dir=direction, maxdist=maximum distance.

'Bounce'
//for solid objects, advanced=advance bounce(0 or 1).

//for all objects, advanced=advance bounce(0 or 1).

Set Path'
path_start(path,speed,endaction,absolute);

'End Path'
path_end();

'Path Position'
path_position=value;//Must lie between 0 and 1.

'Path Speed'
path_speed=value; //pixels per step.

'Step Towards'
mp_linear_step(x,y,stepsize,checkall);
// stepsize is in pixels. Checkall can be either 1 for stopping when hitting any object, or 0 for only solid objects.

'Step Avoiding'
mp_potential_step(x,y,stepsize,checkall);

'Create Instance'
instance_create(x,y,object0);
//use x and y variables for relative.

'Create Moving'
//No equivalent, but you can use the following code.
ID=instance_create(x,y,object1);
with (ID)motion_set(direction,speed);

’Create Random’
instance_create(x,y,choose(object0,object1,object2,object3));
//object0, etc are the object names. Drag and Drop allows only four slots, but the'choose' code allows up to sixteen.

'Change Instance'
instance_change(obj,perf );
//perf(1 or 0)is whether or not to perform create and destroy events.

'Destroy Instance’
instance_destroy();

'Destroy at Position'
position_destroy(x,y);

'Change Sprite'
sprite_index=sprite0;

'Transform Sprite'
image_xscale=value;//horizontal scaling of sprite.
image_yscale=value;//vertical scaling if the sprite.
image_angle=value;//angle the sprite.
image_xscale=-1;//flip the sprite horizontally, actual code.
image_yscale=-1;//flip the sprite vertically, actual code.

'Color Sprite'
image_blend=color ;
image_alpha=value;//from 0 to 1, 1 being opaque.

'Play Sound'
sound_play(sound);//plays sound once.
sound_loop(sound);//loops sound.

'Stop Sound'
sound_stop(index);
//Stops the indicates sound. If there are multiple sounds with this index playingsimultaneously, all will be stopped.

'Check Sound'
if sound_isplaying(sound)=true{
// actions here.
}
//If you wish to use transitions with the following statements call this statementfirst. Transition types can be found in Appendix A.

transition kind=value;

'Previous Room'
room_goto_previous();

'Next Room'
room_goto_next();

'Restart Room'
room_restart();

'Different Room'
room_goto(room);

'Check Previous'
if room_previous(room)<>-1 then {
// actions here
}//'room' is constant variable for current room. Actual code.

'Check Next'
if room_next(room)<>-1 then {
// actions here.
}
//'room' is constant variable for current room. Actual code.

'Set Alarm'
alarm=value; //set 0 from 0 to 11 for alarm.

'Sleep'
sleep(numb); //'numb' is in milliseconds.

'Set Timeline'
timeline_index=timeline;

'Set Timeline Position'
timeline_position=value;

'Display Message'
show_message('Hello');

'Show Info'
show_info();

'Show Video'
show_video(fname,full,loop); //full and loop are either 1 or 0 for yes or no.

'Restart Game'
game_restart();

'End Game'
game_end();

'Save Game'
game_save(fname);
//fname is the name of the save file. Place it in quotes.

//fname is the name of the save file to load. Place it in quotes.

'Replace Sprite'
// precise, transparent,smooth,preload are all 1 or 0 for yes or no.

'Replace Sound'
//loadonuse is 1 or 0 for yes or no.
//Kind is one of the following...
0-normal
1-background
2-3d
3-mmplayer

'Replace Background'
// transparent,smooth and preload are all 1 or 0 for yes or no.

Check Empty'
if place_free(x,y) {
//actions here.
}
//for solid

if !place_empty(x,y)
//actions here.
}
//for all

'Check Collision'
if !place_empty(x,y) // for All
if place_meeting(x,y,all) // for All
if !place_free(x,y) // for Solid only
// As well, there are several advanced codes that allow you greater control over
checking collisions. Please see the manual for explanations of each...

if collision_point(x,y,obj,prec,notme) {
//actions here.
if collision_rectangle(x1,y1,x2,y2,obj,prec,notme) {
//actions here.
}
//actions here.
}
if collision_ellipse(x1,y1,x2,y2,obj,prec,notme) {
//actions here.
}
if collision_line(x1,y1,x2,y2,obj,prec,notme) {
//actions here.
}

'Check Object'
if place_meeting(x,y,object0) {
//actions here.
}

'Test Instance Count'
if instance_number(obj)=value {
//actions here.
}

'Test chance'
if floor(random(value))=0 {
//actions here.
}

'Check Question'
if show_question('Do you want to do this?') {
// actions here.
}

'Test Expression'
if (the expression) {
// actions here.
}
//examples for expression would be x=5, y>10, global.item='Apple'.

'Check Mouse'
if mouse_check_button(numb) {
//actions here.
}
// numb can be mb_none,mb_left, mb_middle,mb_right.

'Check Grid'
if place_snapped(value,value) {
//actions here.
}

'Start Block'

'End Block'

'Else'
//All above are part of if, else statements example...
if x=50 {
hspeed=2;
vspeed=-2;
}
else {
motion_set(90,1);
}

'Exit Event'
exit;

'Repeat'
repeat (value) <statement>;
//example: repeat (10) instance_create(x,y,object0);

'Call Parent Event'
event_inherited();

Execute Code’
//This is the icon that all coding is placed in.

'Execute Script'
script_execute(ind,arguments);
// or call a script in code by the script name and the arguments in () beside it…

'Comment'
//Enter a comment in code by putting '//' followed by the comment.

'Set Variable'
// Set a variable by either using a built-in variable or by using your own.
example...

health=50;
lives=3;
name='Gordon';
//Use 'global.' for your own variables that are to be used by more than one
object...

global.name='Gordon';
//You do not need to use global for built-in variables like 'lives', or 'score'.

'Test Variable'
//Use an if statement to check this. Example...
if lives=0 {
//actions here
}

'Draw Variable'
draw_text(x,y,global.name);
draw_text(x,y,lives);

'Set Score'
score=value;

'Test Score'
if score=value {
//actions here.
}

'Draw Score'
draw_text(x,y,'Score: ' + string(score));

'Show Highscore'
highscore_set_background(back); //set with background image.
highscore_set_border(show); //1 or 0 for yes or no.
highscore_set_colors(back,new,other); //set colors for background,new entry, other entries.
highscore_set_font(name,size,style);
//set style to 0=normal, 1=bold, 2=italic,3=bold italic.
highscore_show(numb); //This actually shows the table, with numb being the new
score to add if it is high enough.

//Note: there are many other controls for the high score table. These are just the
ones used in the drag and drop.

'Clear Highscore'
highscore_clear();

'Set Lives;
lives=value;

'Test Lives'
if lives=value {
//actions here.
}

'Draw Lives'
draw_text(x,y,'Lives: ' + string(lives));

'Draw Life Images'
// no equivalent but you can use the following code in the draw event. sprite0 is
the sprite image. Set 'a' in the 5th line to however far apart you wish the images
to be on the screen in pixels...

var a;
a=0;
repeat(lives){
draw_sprite(sprite0,0,view_xview+a,view_yview);
a+

'Set Health'
health=value;

'Test Health'
if health=value {
//actions here.
}

'Draw Health'
draw_healthbar(x1,y1,x2,y2,amount,backcol,mincol,maxcol,direction,showback,s
howborder);

'Score Caption'
show_score=value; //set to 1 for yes, 0 for no.
caption_score=string;
show_lives=value; //set to 1 for yes, to 0 for no.
caption_lives=string;
show_health=value; //set to 1 for yes, to 0 for no.
caption_health=string;

Create Part System'
index=part_system_create();
//Assign to an index (variable). Must be used in other functions.

'Destroy Part System'
part_system_destroy(index);

'Clear Part system'
part_system_clear(index);

'Create Particle'
index=part_type_create(); //Assign to an index.
part_type_shape(index,shape); //see manual for shape types.
part_type_size(index,size_min,size_max,size_incr,size_rand);
part_type_color(index,color_start,color_middle,color_end);
//there are other functions for particles; these just cover the Drag and Drop.

’Particle Color’
part_type_color1(ind,color1)
//Indicates a single color to be used for the particle.
part_type_color2(ind,color1,color2)
//Specifies two colors between which the color is interpolated.
part_type_color3(ind,color1,color2,color3)
//Similar but this time the color is interpolated between three colors that represent
the color at the start, half-way, and at the end.
part_type_color_mix(ind,color1,color2)
//With this function you indicate that the particle should get a color that is a
random mixture of the two indicated colors. This color will remain fixed over the
lifetime of the particle.
part_type_color_rgb(ind,rmin,rmax,gmin,gmax,bmin,bmax)
//Can be used to indicate that each particle must have a fixed color but chosen
from a range. You specify a range in the red, green, and blue component of the
color (each between 0 and 255).
part_type_color_hsv(ind,hmin,hmax,smin,smax,vmin,vmax)
//Can be used to indicate that each particle must have a fixed color but chosen
from a range. You specify a range in the hue saturation and value component of
the color (each between 0 and 255).

'Particle Life'
part_type_life(index,life_min,life_max);

'Particle Speed'
part_type_speed(index,speed_min,speed_max,speed_incr,speed_rand);
part_type_direction(index,dir_min,dir_max,dir_incr,dir_rand);

'Particle Gravity'
part_type_gravity(index,grav_amount,grav_dir);

'Particle Secondary'
part_type_death(index,death_number,death_type);

'Create Emitter'
index=part_emitter_create(ps);
// ps is the index of the particle system. You must assign this to an index.
part_emitter_region(ps,index,xmin,xmax,ymin,ymax,shape,distribution);
//ps is the index of the particle system. Index is the index of the emitter.

'Destroy Emitter'
part_emitter_destroy_all(ps) //ps is the index of the emitter.

'Burst from Emitter
part_emitter_burst(ps,index,parttype,number) ;
// ps is the index of the particle system. Index is the index of the emitter. Parttype
is the index of the particle.

'Stream from Emitter'
part_emitter_stream(ps,index,parttype,number);

'Set Score'
score=value;

'Test Score'
if score=value {
//actions here.
}

'Draw Score'
draw_text(x,y,'Score: ' + string(score));

'Show Highscore'
highscore_set_background(back); //set with background image.
highscore_set_border(show); //1 or 0 for yes or no.
highscore_set_colors(back,new,other); //set colors for background,new entry, other entries.
highscore_set_font(name,size,style);
//set style to 0=normal, 1=bold, 2=italic,3=bold italic.
highscore_show(numb); //This actually shows the table, with numb being the new
score to add if it is high enough.

//Note: there are many other controls for the high score table. These are just the
ones used in the drag and drop.

'Clear Highscore'
highscore_clear();

'Set Cursor';
window_set_cursor(curs);
//this will set the cursor to a default setting (see end of document for types)
to have a custom sprite as a cursor use the following statement…
cursor_sprite=sprite0;
//Change cursor image to sprite index.

'Open a Web Page'
execute_shell('http//www.somepage.com',0);

'Draw Sprite'
draw_sprite(sprite,subimage,x,y);

'Draw Background'
draw_background(back,x,y) //single image.
draw_background_tiled(back,x,y); //tiled image.

'Draw Text'
draw_text(x,y,string);

'Draw Scaled Text'
draw_text_transformed(x,y,string,xscale,yscale,angle);

'Draw Rectangle'
draw_rectangle(x1,y1,x2,y2,outline); //Outline is 1 or 0 for yes or no.
19

draw_rectangle_color(x1,y1,x2,y2,col1,col2,col3,col4,outline);
//Set col1 and col4 to the left color. Set col2 and col3 to the second color.

draw_rectangle_color(x1,y1,x2,y2,col1,col2,col3,col4,outline);
//Set col1 and col2 to the top color. Set col3 and col4 to the bottom color.

'Draw Ellipse'
draw_ellipse(x1,y1,x2,y2,outline); //outline is 1 or 0 for yes or no.

draw_ellipse_color(x1,y1,x2,y2,col1,col2,outline);
//col1 is the color in the middle. col2 is the color at the boundary.

'Draw Line'
draw_line(x1,y1,x2,y2);

'Draw Arrow'
draw_arrow(x1,y1,x2,y2,size); //size is in pixels.

'Set Color'
draw_set_color(col);
//See the manual for colors.

'Set Font'
draw_set_font(font);
draw_set_halign(halign); //Can be set to fa_left, fa_center, fa_right.
draw_set_valign(valign); //Can be set to fa_top, fa_middle, fa_bottom.

'Set Full Screen'
window_set_fullscreen(full); //Set to 0 for window, to 1 for full screen.

Take Snapshot'
screen_save(filename);

'Create Effect'
effect_create_below(kind,x,y,size,color)
//Creates an effect of the given kind (see
below) at the indicated position. size give the size as follows: 0 = small, 1 =
medium, 2 = large. color indicates the color to be used. The effect is created
below the instances, that is, at a depth of 100000.
effect_create_above(kind,x,y,size,color)

//Similar to the previous function but this
time the effect is created on top of the instances, that is, at a depth of -100000.

//The following are the effect kinds to use in the above statements...

ef_explosion
ef_ring
ef_ellipse
ef_firework
ef_smoke
ef_smokeup
ef_star
ef_spark
ef_flare
ef_cloud
ef_rain
ef_snow

'Visible'
visible= 1 or 0

'Solid'
solid= 1 or 0

'Depth'
depth=123....or -123...

'Persistent'
persistent=1 or 0

'Parent:'
object_set_parent(obj name,obj parent)
// Use -1 in obj to have no parent