How to set in a draw event. sprite position

Imiglikos

Member
Hi,

How to set in a draw event.
sprite position so that it is always displayed as it appears in the upper left corner, both in full screen and in window mode

I currently have yes
but when I switch to windowed mode the sprite is in a different place than on fullscreen


GML:
if (bones) {
draw_sprite(spr_icon_bone, 1 , view_xview+5,view_yview+100)
}
 

flyinian

Member
Hi,

How to set in a draw event.
sprite position so that it is always displayed as it appears in the upper left corner, both in full screen and in window mode

I currently have yes
but when I switch to windowed mode the sprite is in a different place than on fullscreen

GML:
if (bones) {
draw_sprite(spr_icon_bone, 1 , view_xview+5,view_yview+100)
}
Try This:

GML:
if (bones)
{
draw_sprite(spr_icon_bone, 1 ,  x + 5, y + 100);
};
Using the x and y variables uses the room coordinates. The view_x/y_view sets the view in which you see the game, like a camera.

As a side note, You'll want to draw your sprites in a draw event and any functions like the "if" should be done in the step event.
 

Imiglikos

Member
Try This:

GML:
if (bones)
{
draw_sprite(spr_icon_bone, 1 ,  x + 5, y + 100);
};
Using the x and y variables uses the room coordinates. The view_x/y_view sets the view in which you see the game, like a camera.

As a side note, You'll want to draw your sprites in a draw event and any functions like the "if" should be done in the step event.

In the step event, when I put this code syntax, it does not show sprite to me then ...
therefore I put the code in the draw event

as for the above code, this solution does not help ... because now I have sprite stuck to the hero ... and it should be in the upper left corner ... regardless of the size of the game window


obj_hero

draw

GML:
if (bones)
{
draw_sprite(spr_icon_bone, 1 ,  x + 5, y + 100);
};
 

Imiglikos

Member
If you want it to always be in the same position within the viewable area (ie: always on screen), then use a Draw GUI Event, not the Draw Event. Draw GUI uses x/y coordinates that will always start at 0,0 for the top-left corner of the window/view.

yes, but in draw gui it worked for me without variable bones, and with variable bones, nothing is displayed to me ... That's why I have this sprite in the draw event ..

I know that display_get_gui_width must be used then but I have never used it ...
 

rytan451

Member
yes, but in draw gui it worked for me without variable bones, and with variable bones, nothing is displayed to me ... That's why I have this sprite in the draw event ..
If you're calling the code without the variable bones being defined, then it would cause an error. Do you mean, "in Draw GUI, it drew the sprite even though bones was false, and didn't draw the sprite when it was true"? If that's the case, then you should be checking if (!bones), both in the draw event and in the Draw GUI event.

Is bones a local variable (defined within the draw event using var)? Is it being set to a different value in the draw event?

When I test the code you gave, modified for the Draw GUI event, it worked perfectly.

GML:
var bones = true; // Placeholder for testing

if (bones)
{
draw_sprite(spr_icon_bone, 1, 5, 50);
}

bones = false; // Test for when it's false


if (bones)
{
draw_sprite(spr_icon_bone, 1, 5, 100);
}
Only the first spr_icon_bone is drawn, as expected.

A quick note: for image indexes, GMS counts from 0. So, the image indices of each respective frame would be 0, 1, 2, 3, etc. If you're drawing draw_sprite(spr_icon_bone, 1,view_xview+5, view_xview+100);, then you're drawing the second frame.

What version of GameMaker are you using? In GMS2+, view_xview and view_yview is deprecated. In GMS1, view_xview and view_yview are arrays, so to get the x position of view 0, you need to use view_xcode[0].
 

Imiglikos

Member
If you're calling the code without the variable bones being defined, then it would cause an error. Do you mean, "in Draw GUI, it drew the sprite even though bones was false, and didn't draw the sprite when it was true"? If that's the case, then you should be checking if (!bones), both in the draw event and in the Draw GUI event.

Is bones a local variable (defined within the draw event using var)? Is it being set to a different value in the draw event?

When I test the code you gave, modified for the Draw GUI event, it worked perfectly.













Only the first spr_icon_bone is drawn, as expected.

A quick note: for image indexes, GMS counts from 0. So, the image indices of each respective frame would be 0, 1, 2, 3, etc. If you're drawing draw_sprite(spr_icon_bone, 1,view_xview+5, view_xview+100);, then you're drawing the second frame.

What version of GameMaker are you using? In GMS2+, view_xview and view_yview is deprecated. In GMS1, view_xview and view_yview are arrays, so to get the x position of view 0, you need to use view_xcode[0].

I have a bone variable defined in the create event in obj_hero, it is set to 0
yes it's a local variable ... not global ..
I need this variable ... because I take one object from the board and then a bone is displayed to me then when I approach another object and give the bone, the bone sprite disappears ..
as for your code in draw GUI, you are right, it works..but when I use it, it always displays a dice sprite ... and it should be displayed only when I have a dice..and when I give it back to another obiect, it cannot be displayed. .
I'm using gms 1.4





obj_hero

create

GML:
hasbones = false;
bones = 0;

step

GML:
if place_meeting(x,y,obj_bones)
{
bones = 1
hasbones = true
with obj_bones instance_destroy();
}

if hasbones = true {
with obj_tiger {
obj_tigerattack = false
}
}

if !instance_exists  (ob_bones) and hasbones == false{
instance_create(obj_tiger.x+32,obj_tiger.y+12, obj_bones)
}
bones = 0;
}
 
Last edited:

rytan451

Member
Ah, so they're instance variables (declared without var), not local variables.

The code should be drawing the bone icon, not dice. I'm not sure why the code would be drawing dice rather than bones; are you sure the bone icon is in the second frame (image index 1) of spr_icon_bone?
 

Imiglikos

Member
Ah, so they're instance variables (declared without var), not local variables.

The code should be drawing the bone icon, not dice. I'm not sure why the code would be drawing dice rather than bones; are you sure the bone icon is in the second frame (image index 1) of spr_icon_bone?


yes ... because note that on my previous code in the draw .. event, this sprite of the dice is drawn when the condition is met .. and disappears when I give the bone to the tiger ..
I have already improved the sprite index from 1 to 0 ... and it's the same ... next to my code, this icon is displayed when the condition is met, I will find obj_bones ... when I give obj_bones to the tiger, the bone icon disappears ... it should be like that

the problem is that he wants this spr_bones icon to be displayed always in a fixed place regardless of the size of the window .. So it probably can't be a draw gui if the condition must be met for this dice sprite to display and then disappear after giving it to the tiger ..
 

rytan451

Member
I've managed to get a simplified version of it working on my end. Here's what I did:
GML:
// In obj_player:
// Create event
bones = false;

// Keyboard Space event
x += 5;

// Collision with obj_bones
bones = true;
instance_destroy(other); // Before GMS2.3, this was "with (other) { instance_destroy(); }"

// Collision with obj_tiger
if (bones) {
  bones = false;
  instance_destroy(other);
}

// Draw GUI
if (bones) {
  draw_sprite(spr_icon_bone, 1, 5, 100);
}
It seems to work exactly how you want it to: when the player picks up the bones, a bone icon appears. Then, when the player gives the bone to the tiger, the icon disappears. And in all cases, the icon appears in a fixed place in the window.
 

Tony Brice

Member
as for the above code, this solution does not help ... because now I have sprite stuck to the hero ... and it should be in the upper left corner ... regardless of the size of the game window
Draw Event
Code:
if (bones) {
  draw_sprite(spr_icon_bone, 1, 5, 50);
} else {
 draw_sprite(spr_icon_bone, 1, 5, 100);
}
The reason it was appearing above your object is because you used the x and y when you don't need to if it's in a fixed position and you're not scrolling the room area.
 

Imiglikos

Member
I've managed to get a simplified version of it working on my end. Here's what I did:
GML:
// In obj_player:
// Create event
bones = false;

// Keyboard Space event
x += 5;

// Collision with obj_bones
bones = true;
instance_destroy(other); // Before GMS2.3, this was "with (other) { instance_destroy(); }"

// Collision with obj_tiger
if (bones) {
  bones = false;
  instance_destroy(other);
}

// Draw GUI
if (bones) {
  draw_sprite(spr_icon_bone, 1, 5, 100);
}
It seems to work exactly how you want it to: when the player picks up the bones, a bone icon appears. Then, when the player gives the bone to the tiger, the icon disappears. And in all cases, the icon appears in a fixed place in the window.

Thanks guys for your help .. and especially colleague Rytan451. I think that the reason was in the variable bone .. because instead of setting false and true I set 0 and 1. Now everything is fine ;-)
 

Imiglikos

Member
Hi guys,

I found one error ...

When a hero takes a die from a room ... and loses his life on the way to a tiger ... then when I approach a tiger, I don't have this bone anymore and the hero can't give it to a tiger ... there is no bone in the room either, because I took it out of the room once. The bone icon also disappears when the hero loses his life.

do you know how to fix it? that the hero, after obtaining the bone, could complete this task and, despite losing his life, give the bone to the tiger?


all the code below

obj_tiger
create


GML:
image_speed = 1;
isattacking = false
eatbone = false

alarm[0]

GML:
isattacking = false
sprite_index = spr_tiger_idle;
image_speed = 1;

step


GML:
//tiger attacks the player when he touches the trigger
if isattacking = true{
sprite_index = spr_tiger_attack;
image_speed = 2;
if !instance_exists (obj_tigerattack) {
instance_create(x,y-32,obj_tigerattack)
}
}

//if TIGER gets the bone it will stop attacking and change it's sprite
if eatbone = true {
sprite_index = spr_tiger_eatbones
image_speed = 1;
isattacking = false
instance_destroy(obj_trigger);
}
obj_tigerattack

create


GML:
alarm [0] = 3

Alarm[0]

GML:
instance_destroy();
COLLISION with hero


GML:
if obj_hero.timeDamage < 0
{
obj_hero.hp-=1;
obj_hero.timeDamage=room_speed*2
obj_hero.hspd = 3; //variable hspeed
obj_hero.vspd = 3;//variable vspeed

}

obj_hero

create



GML:
hasbone = false;
bones = false;

step

GML:
///tiger and hero

///if the hero touches the attack obj_trigger WITHOUT the bones, he will be attacked
if place_meeting(x,y,obj_trigger) && hasbone = false
with obj_tiger {
isattacking = true
alarm[0]=60
}
}
else with obj_tiger {
isattacking = false
}






//take bone

if place_meeting(x,y,obj_bones)
{
hasbone = true
bones = true
with obj_bones instance_destroy();
}


if hasbone = true {
with obj_tiger {
isattacking = false
}
}




//prevent tiger from attacking if you have bone
if hasbone = true {
with obj_tiger {
isattacking = false
}
}





//Give bone to tiger
if place_meeting(x,y,obj_trigger) && hasbone = true {
with obj_tiger {
eatbone = true
}



if !instance_exists  (obj_bones) and hasbone == false{  
instance_create(obj_tiger.x+32,obj_tiger.y+12, obj_bones)
}
bones = false;
}

draw GUI


GML:
if (bones) {
  draw_sprite(spr_bones, 1, 5, 140);
}
obj_bone

(obj_bone has no code)


obj_trigger

(obj_trigger has no code)

Thank you :)
 

TheouAegis

Member
When the hero dies, don't destroy it. Or if you really want to destroy it because that's all you are comfortable with, save bones to a global variable inside the Destroy Event, then change your create event to set bones to that global variable. Just make sure you initialize that variable at the very start of your game (before the player is ever created) so you don't get an unknown variable error.

Why are you using 2 variables that seemingly do the exact same thing, again? What did I miss?
 

Imiglikos

Member
When the hero dies, don't destroy it. Or if you really want to destroy it because that's all you are comfortable with, save bones to a global variable inside the Destroy Event, then change your create event to set bones to that global variable. Just make sure you initialize that variable at the very start of your game (before the player is ever created) so you don't get an unknown variable error.

Why are you using 2 variables that seemingly do the exact same thing, again? What did I miss?

Theo,
you missed some very interesting things;-)
I use two variables because one is for the bone sprite to display properly.
with one variable, when I gave the tiger a bone, the bone icon did not disappear from the room ... hence the two variables ...

As to the topic
The hero loses his life and I destroy him when he dies, because usually it should be like that ... at least I don't know any other solution ..
does he feel comfortable about it? You know, it's hard to say ... it's not about comfort, but rather about what I see in front of my eyes ... I always associate the death of a hero in games of this type with the fact that the hero dies and is reborn again ...


But I lean towards the latter solution .. you mentioned a global variable



I'm removing these two variables from the create obj_hero event


GML:
hasbone = false;
bones = false;
and I put a global variable here, e.g.

GML:
global.bones = 0;
then in the destroy event in obj_hero I set this variable to 1

GML:
global.bones = 1;

I understand that I also have to remove these two variables from the step event and replace this one global variable?
or maybe move all the code from the step obj_hero event to the step event in obj_tiger?
because I do not destroy the tiger because this object is not subject to destruction ..
How this is supposed to look like in my code?

Thank you
 
Last edited:

TheouAegis

Member
Ultimately, you are going to have a main menu screen, if you don't have one already. When the player selects a new game, that is when you set global.bones to 0. That way, nobody is going to reset the value of global.bones until you go back to the main menu and start a new game.

For making sure you don't lose the bone after giving it to the tiger and then dying, I would have a variable inside the player object itself, not a global variable and definitely not inside the tiger. Set that variable when the player gives the tiger a bone and then when the player dies check if that variable is set and set global.bones to it.
 

Imiglikos

Member
Ultimately, you are going to have a main menu screen, if you don't have one already. When the player selects a new game, that is when you set global.bones to 0. That way, nobody is going to reset the value of global.bones until you go back to the main menu and start a new game.

For making sure you don't lose the bone after giving it to the tiger and then dying, I would have a variable inside the player object itself, not a global variable and definitely not inside the tiger. Set that variable when the player gives the tiger a bone and then when the player dies check if that variable is set and set global.bones to it.

do these two non-global variables still remain the same in the code?

GML:
hasbone = false;
bones = false;
I have the main menu room... I understand that I need to set global.bones = 0 there before I go to the room with the scenery with the tiger in it?

ok here the player gives the tiger a bone ..

obj_hero

step


GML:
//Give bone to tiger
if place_meeting(x,y,obj_trigger) && hasbone = true {
with obj_tiger {
eatbone = true
global.bones =1;
}



if !instance_exists  (obj_bones) and hasbone == false{ 
instance_create(obj_tiger.x+32,obj_tiger.y+12, obj_bones)
}
bones = false;
}
obj_hero

step

GML:
if (hp <= 0 and global.live > 0) {
global.live--
 instance_destroy();
 with (instance_create(x,y,obj_hero_death)) {
  sprite_index = spr_hero_death
  image_xscale = other.image_xscale;
  respawn = true;
  respawnObject = obj_hero;
  respawnX = spawnX;
  respawnY = spawnY;
  global.bones = 1;
 }
}
and on the room the main menu before entering the scenery global.bones = 0;

I don't know if this is what it is supposed to look like ... if I understood you well ...
 

Imiglikos

Member
ok, I did as Theo described here .. it works fine now ..
only one problem remained.

when the enemy deals damage to the hero, the bone icon starts blinking ... it didn't blink before.
and the second thing ... when I have a bone and the hero dies, the bone icon is not displayed ...
these two problems arose when i use a global variable

Draw gui

GML:
if (bones) {
  draw_sprite(spr_bones, 1, 5, 140);
}
 
Top