• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

More optimal version of displaying all weapons on the surface

Imiglikos

Member
Hello everyone

When I am a hero by the mirror and have more than one weapon with me, each of the hero's weapons displays.
But I have it in several loops and I would not like to burden the code in this way. How to combine it so that all weapons on the surface are displayed in one loop?

Thanks for any help, the code looks like this

obj_game

create

GML:
enum e_wep { have,ammo,firerate,dmg_min,dmg_max,ammo_type,name,ammo_sound }
enum e_gun   { ball,thunder,shotgun,blue_laser,ice }



weapons_total = 5;
current_weapon = 0;




var i = 0;


//basic weapon
global.wep[0 ,e_wep.ammo_type] = obj_ball;
global.wep[0, e_wep.have] = true;
global.wep[0 ,e_wep.ammo] = -1; //endless ammo
global.wep[0 ,e_wep.firerate] = 5;
global.wep[0 ,e_wep.dmg_min] = 3;
global.wep[0 ,e_wep.dmg_max] = 5;
global.wep[0 ,e_wep.name] = "ball";


//second weapon
global.wep[1 ,e_wep.ammo_type] = obj_thunder;
global.wep[1, e_wep.have] = false;
global.wep[1 ,e_wep.ammo] = 30;
global.wep[1 ,e_wep.firerate] = 10;
global.wep[1 ,e_wep.dmg_min] = 3;
global.wep[1 ,e_wep.dmg_max] = 5;
global.wep[1 ,e_wep.name] = "thunder";


//third weapon
global.wep[2 ,e_wep.ammo_type] = obj_shotgun;
global.wep[2, e_wep.have] = false;
global.wep[2 ,e_wep.ammo] = 20;
global.wep[2 ,e_wep.firerate] = 15;
global.wep[2 ,e_wep.dmg_min] = 3;
global.wep[2 ,e_wep.dmg_max] = 5;
global.wep[2 ,e_wep.name] = "shotgun";


//fourth weapon
global.wep[3 ,e_wep.ammo_type] = obj_blue_laser;
global.wep[3, e_wep.have] = false;
global.wep[3 ,e_wep.ammo] = 10;
global.wep[3 ,e_wep.firerate] = 20;
global.wep[3 ,e_wep.dmg_min] = 3;
global.wep[3 ,e_wep.dmg_max] = 5;
global.wep[3 ,e_wep.name] = "blue_laser";


//fifth weapon
global.wep[4 ,e_wep.ammo_type] = obj_ice;
global.wep[4, e_wep.have] = false;
global.wep[4 ,e_wep.ammo] = 5;
global.wep[4 ,e_wep.firerate] = 25;
global.wep[4 ,e_wep.dmg_min] = 3;
global.wep[4 ,e_wep.dmg_max] = 5;
global.wep[4 ,e_wep.name] = "ice";

step

GML:
if keyboard_check_pressed(ord('X')) && timeAttack <= 0 && in_air=false &&
(global.wep[cur,e_wep.ammo] > 0 || global.wep[cur,e_wep.ammo] == -1) {
timeAttack = global.wep[cur,e_wep.firerate];

timeAttack = _attackClock;
current_attack =1;

with instance_create(x,y,par_attack) {

sprite_index = spr_hero_attack;
image_xscale = other.image_xscale;


}

    var box, ins;
    if image_xscale == -1
        box = bbox_left;
    else
        box = bbox_right;


if (global.wep[cur,e_wep.ammo] >= 1) // if not infinite ammo
{
global.wep[cur,e_wep.ammo]-=1;
}



var ins = instance_create(box+image_xscale*42, y-17,global.wep[cur,e_wep.ammo_type] );
ins.hspeed = image_xscale * 15;
ins.dmg = irandom_range(global.wep[cur,e_wep.dmg_min],global.wep[cur,e_wep.dmg_max]);


   audio_play_sound(global.wep[cur,e_wep.ammo_sound],10,false)
}
and mirror object

obj_mirror

draw

GML:
// draw the mirror sprite
draw_sprite(sprite_index,0,x,y);






// mirror position


_xx = x;
_yy = y;


_surf = surface_create(300,200); // mirror size






surface_set_target(_surf);
draw_clear_alpha(c_black,0);
draw_sprite_ext(obj_player.sprite_index,obj_player.image_index,obj_player.x - _xx ,obj_player.y - _yy - 70,obj_player.image_xscale,obj_player.image_yscale,0,image_blend,.5)

var _xx1 = x
var _yy1 = y

//weapon1
with obj_ball

  {

for (i = 0; i < instance_number(obj_ball); i += 1) {
    obj= instance_find(obj_ball, i);
    draw_sprite_ext(spr_ball,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,1,1,0,image_blend,.5)
 
}
   }

//weapon2
with obj_thunder   {


for (i = 0; i < instance_number(obj_thunder); i += 1)  {
    obj = instance_find(obj_thunder, i);
    draw_sprite_ext(spr_thunder,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)


    }
}

//weapon3
with obj_shotgun {

for (i = 0; i < instance_number(obj_shotgun); i += 1)  {
    obj = instance_find(obj_shotgun, i);
    draw_sprite_ext(spr_shotgun,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)


     }
}

//weapon4
with obj_blue_laser {

for (i = 0; i < instance_number(obj_blue_laser); i += 1)  {
    obj = instance_find(obj_blue_laser, i);
    draw_sprite_ext(spr_blue_laser,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)


    }
}

//weapon5
with obj_ice  {

for (i = 0; i < instance_number(obj_ice); i += 1)  {
    obj = instance_find(obj_ice, i);
    draw_sprite_ext(spr_ice,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)


     }
}



surface_reset_target();

draw_surface(_surf,_xx,_yy); // draw mirror

surface_free(_surf) // clear mirror
 
GML:
with obj_ice  {

for (i = 0; i < instance_number(obj_ice); i += 1)  {
    obj = instance_find(obj_ice, i);
    draw_sprite_ext(spr_ice,0,obj.x - _xx1+ 32 ,obj.y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)


     }
}
You have a problem here :)

Using "with (obj_ice)": if obj_ice is an actual object, then using 'with' on it is the same as looping through them.

"for (i = 0; i < instance_number(obj_ice); i += 1)" is unnecessary, as it is already looping through obj_ice when you use 'with' and that object.

Code:
with obj_ice
{
draw_sprite_ext(sprite_index, 0 , x - _xx1+ 32 , y  - _yy1 - 70,image_xscale,image_yscale,0,image_blend,.5)
}
This is what it can be, if you want to control that objects drawing from within a different object. There is a large number of places in your code where this behaviour can be removed.

Using 'with' gives a different scope to the code. It will loop through all instances of the object, and code executed within can either be local variables set in the calling instance, that the 'with' object can access, or it can call it's own non-local variables.

In the draw_sprite code: sprite_index, 0, x / y / image_xscale / y_scale etc are all the 'with' objects variables, and will only be applied to themselves.

If 'xx1' or 'yy1' are values that the calling instance has, then they can be set to local variables, and be accessed by instances outside. Which are technically, uh...."within" as they are called, and yet also "outside" as they are still individual entities.

Code:
var amount = 50; // local variable in calling instance

with (whatever)
{
x += amount; // 'x' (self within the code block) plus 'amount' (value from "other" outside the code block)
}
Code:
var amount = 50; // local variable in calling instance
count = 0; // not local variable, "inside" the calling instance
with (whatever)
{
x += amount; // 'x' (self within the code block) plus 'amount' (value from "other" outside the code block)
other.count += 1 // is "outside" but can refer to the calling instance here, and set it's non local variable
}

if count == ? // "inside" again
{
//////do whatever
}
It's a slightly tricky thing to try and explain, but hopefully you'll have better understanding of "scope", and these changes should improve your code.

You also might want to consider the mirror object only being active when the player is within a certain distance. As it would seem to be drawing to a surface the entire time it is active in the game, and that's going to be wasteful if the player isn't anywhere near it.

ALSO:
If every object you want to draw shares a parent, then it would just be this to loop through them all.

Code:
var _xx = x - 32;
var _yy = y - 70;

_surf = surface_create(300,200); // mirror size

surface_set_target(_surf);
draw_clear_alpha(c_black,0);
draw_sprite_ext(obj_player.sprite_index,obj_player.image_index,obj_player.x - _xx ,obj_player.y - _yy - 70,obj_player.image_xscale,obj_player.image_yscale,0,image_blend,.5)


with (parent)
{
draw_sprite_ext(sprite_index, 0 , x - 32 , y  - 70, image_xscale,image_yscale,0,image_blend,.5)
}

surface_reset_target();

draw_surface(_surf,_xx,_yy); // draw mirror

surface_free(_surf) // clear mirror
Though I'm unsure if there is something I missed there, as your code does seem to have errors in scope where you're not applying things correctly.

Code:
_xx = x;
_yy = y;

var _xx1 = x
var _yy1 = y
You have these for example, and yet they are both the same value :) The local variable can be passed to the 'with' instances, and so the non-local version you first defined is pointless. Both are the x / y of the mirror.
 
Last edited:
Top