• 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!

Removing/Deleting Draw events

Wendell

Member
So, I'm quite new to Game Maker and I'm trying to make a previously drawed event (a draw_rectangle and a draw_text) to disappear after a mouse click, remembering that, to draw the text and triangle, I used the same mouse click.

So, how can I make them to disapper after a second click? They are being called by a script and being drawn by an object which is not in the room, it is only used to create the rectangle and the text above it.

Something like this:
Click = shows the rectangle and the text
Second click = removes both from screen
 
T

tserek

Guest
You need a counter variable and add 1 each time to that once mouse button is pressed?

create:
Code:
click=0;
draw:
Code:
if mouse_check_button_pressed(mb_left)
{
 click+=1;
}

if click mod 2 !=0
{
 // draw stuff..
}
 
Last edited by a moderator:
S

Sam (Deleted User)

Guest
draw:
Code:
if mouse_check_button_pressed(mb_left)
{
 click+=1;
}
It is a better practice to process things such as mouse and keyboard checks in the step event instead of draw AFAIK.
 

Wendell

Member
Well, it almost works... it draws the text, but it does not vanishes when I press the mouse button again.
 
S

Sam (Deleted User)

Guest
Try what @sp202 recommended. Boolean is a fancy way of saying true/false. I would give you a code snippet right now if I wasn't up all night.
 

Wendell

Member
The way @sp202 works, but the text shows and vanishes instantly, with one click. It does not wait for me to click again for it to disappear.
 

Wendell

Member
the draw event

Code:
if mouse_check_button_pressed(mb_right)
    {
    show = !show
    }
    
    if show
    {
            //caixa de texto inferior
            draw_set_color(c_black);
            draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,0);
            
            //borda da caixa de texto
            draw_set_color(c_white);
            draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,1);
            
            //texto mostrado
            draw_set_color(c_white);  //cor
            draw_set_halign(fa_left); //alinhamento esquerda
            draw_set_valign(fa_top);  //alinhamento topo
            draw_text_ext(view_xview[0]+8, view_yview[0]+190+8, print, font_size, maxLength);
            
    }
 

Wendell

Member
It works like this:

When mb_right is pressed a collision event is created in front of the player.

If the collision collides with anything that will show a text, it calls a script that shows the text.
 

sp202

Member
There doesn't seem to be a problem with the code you posted. Chances are it's an issue with the script feeding the string into the print variable.
 

Wendell

Member
When the player presses mb_right it will create a collision object.

This collision will check if it collided with something (a sign post, for example). If yes, then the sign post will draw the text.

How this text will be drawn is inside an object that is not in the room, the obj_text. It has all the text's configuration. The script uses those to draw the text and the rectangles.

I'm not sure where to put your boolean code, if is inside the object collision or the object sign post. I'm pretty sure the script is oko, because the text draws correctly, the only problem is, when I press mb_right (using your code) the text shows and vanishes really quick and shows even if the object collision is not colliding with the sign post (but to show the message the first time it must collide).

If I don't use your code the text shows, but does not vanishes.
 

sp202

Member
That sounds like a strange method for what it seems like you're trying to achieve. What exactly is the implementation in-game? Is the player clicking right mouse to read nearby signposts? Also, what do you mean by "inside an object that is not in the room"?
 

Wendell

Member
Yes, I'm trying to make a dialogue system.

Clicks > creates an object > if the object collides with the sign, draws a box and the text > clicks again, the text disappears

If you know how to do this, I will completely forget about this system.

All I need is a way to show a rectangle at the bottom with the text. When I click again, it disappears. But I must make a way for the object_player to be "near" the sign post, if not, it will be far a way and showing the text. Must like when you talk to an NPC, you must be near him to start a dialogue.
 

sp202

Member
Using collisions is a bit silly. Does the signpost contain the text? You could do something like the following:
Code:
inst=instance_nearest(player.x,player.y,signpost)
if point_distance(player.x,player.y,inst.x,inst.y)<32 //or however close you want the player to be
{
if mouse_check_button_released(mb_right)
{
show=!show
}

if show
{
//draw the rectangle and whatnot
}
}
else
{
show=false
}
 

Wendell

Member
@sp202 it works 99% perfect, the only problem is that it shows by click only the first time. If I walk and go near the sign it shows the text even if I don't press the mb_right.

Also, I'm using an Array on the Create Event to store the messages. Is there a way to show one message after the other and reset after it showed them all?
 
B

bojack29

Guest
Code:
//Draw
if (mouse_check_button_released(mb_left)){
     click = 1 - click;
}
if (click){
     //
     //
}
 
L

Laurent57

Guest
Hi! Without read all, maybe you have to put mouse_clear(yourmousebutton) somewhere.. This is a recurring problem on the forum..
 

sp202

Member
Go into debug mode and make sure that show is being set to false when you walk away from the signpost.
 
B

bojack29

Guest
Why not have the sign check for the player and if so display the text
 

Wendell

Member
@sp202 "Show" wasn't setting to false because of a missing "}". Problem solved!
If I store 2 strings into my "message" array and want to display them, one right after the other, using that code, how should I do? I did:

Code:
if message_current <= array_length_1d(message)
{
    message_current++;
}
It doesn't work. Remembering that, on the create event, is:

Code:
message[0] = "Hmm?"
message[1] = "What are you looking for?"
message_current = 0;
 

Wendell

Member
@sp202 I've just realized something... if I add other "signpost" event to show other messages (changing the reference to the new object, at the two first lines of your code), only the frist one works. The second just doesn't show anything.
 
Last edited:

sp202

Member
That is due to how you handle sending the signpost content to the text box. Post your code.
 

Wendell

Member
The signpost that works:
Code:
depth = -y-1;

inst = instance_nearest(obj_player.x,obj_player.y,obj_sign)
if point_distance(obj_player.x,obj_player.y,inst.x,inst.y) < 32 and (obj_player.face == UP) and obj_player.depth < obj_sign.depth
{
    if mouse_check_button_released(mb_right)
    {
    show = !show;
    
    }
    if show
    {
    
    //caixa de texto inferior
    draw_set_color(c_black);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,0);
                
    //borda da caixa de texto
    draw_set_color(c_white);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,1);

                  
    //texto mostrado
    draw_set_color(c_white);  //cor
    draw_set_halign(fa_left); //alinhamento esquerda
    draw_set_valign(fa_top);  //alinhamento topo
    draw_text_ext(view_xview[0]+8, view_yview[0]+190+8, message[message_current], 12, 300);
}
}else
    {
    show=false
    }
and the one who doesn't:
Code:
draw_self();
depth = -y-1;

inst = instance_nearest(obj_player.x,obj_player.y,obj_signpost2)
if point_distance(obj_player.x,obj_player.y,inst.x,inst.y) < 32 and (obj_player.face == UP) and (obj_player.depth < obj_signpost2.depth)
{
    if mouse_check_button_released(mb_right)
    {
    show = !show;
    
    }
    if show
    {
    
    //caixa de texto inferior
    draw_set_color(c_black);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,0);
                
    //borda da caixa de texto
    draw_set_color(c_white);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,1);

                  
    //texto mostrado
    draw_set_color(c_white);  //cor
    draw_set_halign(fa_left); //alinhamento esquerda
    draw_set_valign(fa_top);  //alinhamento topo
    draw_text_ext(view_xview[0]+8, view_yview[0]+190+8, message[message_current], 12, 300);
}
}else
    {
    show=false
    }
 

sp202

Member
There isn't really a good reason for having two separate objects for signposts if the only difference is their text content. You can use creation code in the room editor to assign IDs to signposts and then use that ID to draw the relevant text.
 

Wendell

Member
Any clue on how to do this? I mean, how do I assign an id for every Signpost in the room and use it to show it's own text?
 

sp202

Member
Right click on an object in the room editor and there should be the option to give it creation code, something like:
Code:
sign_id=1
Then in the signpost object when you call the script containing the messages, you'd use the sign_id as an argument and the script would return the relevant lines.
 
B

bojack29

Guest
There isn't really a good reason for having two separate objects for signposts if the only difference is their text content. You can use creation code in the room editor to assign IDs to signposts and then use that ID to draw the relevant text.
Why not just write the relevant text in the room creation event of each sign post?
 

Wendell

Member
Why not just write the relevant text in the room creation event of each sign post?
Well, it actually worked, but the problem is, if I have 3 messages, one stored in a different id of my "message" array, whenever I click to read the sign the messages run really fast and stops at the last one. You can't even read the first 2. Check:

DRAW EVENT:
Code:
draw_self();
depth = -y-1;

inst = instance_nearest(obj_player.x,obj_player.y,obj_sign)
if point_distance(obj_player.x,obj_player.y,inst.x,inst.y) < 32 and (obj_player.face == UP) and obj_player.depth < obj_sign.depth
{
    if mouse_check_button_released(mb_right)
    {
    obj_player.interacting = !obj_player.interacting;
    show = !show;
    message_count = 0;
    }
    if show
    {
    
    //caixa de texto inferior
    draw_set_color(c_black);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,0);
                
    //borda da caixa de texto
    draw_set_color(c_white);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,1);

                  
    //texto mostrado
    draw_set_color(c_white);  //cor
    draw_set_halign(fa_left); //alinhamento esquerda
    draw_set_valign(fa_top);  //alinhamento topo
    draw_text_ext(view_xview[0]+8, view_yview[0]+190+8, message[message_count], 12, 300);
    
    if message_count < message_max {
    message_count += 1;
    }   
        
    }
} else
    {
    show=false
    obj_player.interacting = false;
    
    }
    
mouse_clear(mb_right);
draw_set_color(c_black);
CREATION CODE:
Code:
message_max = 2

message [0] = "Message one.";
message [1] = "Message two.";
message [2] = "Message 3.";
This way it shows message one and two really fast and stops at the third. And when I click, they disappear. If I click again, the same thing. I need the messages to show only when I click, not automatically.
 

sp202

Member
@bojack29 Because that makes editing a pain. Much easier to store the text in one searchable script than scattered in different objects.

@Wendell Of course the messages are doing that, you're cycling through them at a message per step. You need to add the mouse click to the if statement.
 
B

bojack29

Guest
@sp202 Hm. I can see that. But at the same time you would be searching thru signs for it's id to find the correct match for it's dialogue box. That could be a mess too. Catch 22.
 
B

bojack29

Guest
And on the flip side I can't imagine a block that large. Can you imagine blocks of code that housed that much dialogue that's not seperated? Sheesh. That could be thousands of lines of code.
 

sp202

Member
Of course you'd use formatting, plenty of games do this sort of thing. sign_ids can easily be kept track of on paper, whereas writing out whole lines of dialogue is going to be a mess. There's really no better alternative.
 
B

bojack29

Guest
I would strongly disagree. A better method, IMO, would be to use arrays within the objects themselves to hold the dialogue information - like a character or sign. Assuming you build a dialogue handler to scroll the text, it would be a sinch to find the dialogue for each character and the ouput would be given to a text object to handle the scrolling - it makes lookup a breeze and output really easy.

If all the text is stored in a single object, lookup is a nightmare pouring thru thousands of lines of text. You would have to swap between objects to find the associated id and the corresponding index in the array to find the associated dialogue. Further you would have to construct ending and starting parameters to ensure that characters do not accidentally use the wrong dialogue. It sounds like a nightmare.

And lastly if you wanted to add dialogue you would literally have to shift the whole array up or down to include it. <- And that my friend is absolute madness.
 
Last edited by a moderator:

sp202

Member
I'm not sure how that is functionally different. Having the dialogue directly within the sign object only saves one step; opening up a script and finding the relevant section, roughly 3 seconds of work. A dialogue handler which displays all the text is the equivalent of the script containing all the dialogue.

Now if you made a dialogue handler that had a list of all the objects with text and you could click on each and edit its dialogue, that might makes thing more convenient. But that's a significant amount of infrastructure to set up.
 
B

bojack29

Guest
No. The idea is that the dialogue handler merely intreprets the information in any given object. The problem is holding all the data (presumably in an array) in any given object. If you wish to add dialogue to one character, or increase the array at any given point you have to shift the WHOLE array down -- and that could be hundreds of indexes. That is not an efficient way to handle dialogue. Further you would have to adjust all characters afterward to shift their dialogue id's to match the newly shifted array. It is far too much work for something so simple.
 

sp202

Member
All the dialogue isn't being stored in a single array, I think you've misunderstood what I meant by keeping dialogue in a script.
Code:
if sign_id=1
{
message_max=1
message[0]="this is the first message"
message[1]="this is the second"
}

if sign_id=2
{
message_max=2
message[0]="i'm another sign"
message[1]="i don't like sharing arrays"
message[2]="nothing personnel kid"
}
 
B

bojack29

Guest
But then you would have to swap between the signs individually to check their id's and then again in the dialogue object to match against their specific dialogue. How is that any different then just containing the information in the individual sign? Also the method I employed is by extension for all things - including characters. I should also mention that this invention does not involve checking against ids, and can so save time.
 

sp202

Member
I'm not sure what you mean by "swap between signs" but all that would happen is that the sign calling the script would provide its id and the script would handle all the dialogue content. The whole point of not storing the dialogue in individual objects is that
a) It's all in one place.
b) Unless we're creating entirely separate objects, we only have access to creation code so hardcoding dialogue into them means we forego control and dynamic message trees.
 
B

bojack29

Guest
The one advantage I can think of is multiple dialogues happening at the same time. In that case, a single object certainly wins in that regard.
 

sp202

Member
I think you're debating purely on the functionality and optimization side of things, while I'm emphasizing the convenience. In the absence of an external "dialogue handler", a script is the way to go.
 

Wendell

Member
@sp202
You mean at the first if statement, right? Well, now it actually cicle through all messages, but they appear and disappear with a single click.

Code:
inst = instance_nearest(obj_player.x,obj_player.y,obj_sign)
if point_distance(obj_player.x,obj_player.y,inst.x,inst.y) < 32 and (obj_player.face == UP) and (obj_player.depth < obj_sign.depth) and mouse_check_button_released(mb_right)
{
    obj_player.interacting = !obj_player.interacting;
    show = !show;
    
    if show
    {
    
    //caixa de texto inferior
    draw_set_color(c_black);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,0);
                
    //borda da caixa de texto
    draw_set_color(c_white);
    draw_rectangle(view_xview[0],view_yview[0]+190,view_xview[0]+319,view_yview[0]+239,1);

                  
    //texto mostrado
    draw_set_color(c_white);  //cor
    draw_set_halign(fa_left); //alinhamento esquerda
    draw_set_valign(fa_top);  //alinhamento topo
    draw_text_ext(view_xview[0]+8, view_yview[0]+190+8, message[message_count], 12, 300);
    
    message_count += 1;
          
    }
} else
    {
    show=false
    obj_player.interacting = false;
    
    }
 
Last edited:

sp202

Member
I meant this one:
Code:
if message_count<message_max
{
message_count+=1
}
You shouldn't just be blindly following my instructions, you should be understanding why you need to make the changes I tell you to. I'm sure that fix was well within your capabilities.
 
Top