Jump to content


Photo

Menu Trouble


  • Please log in to reply
28 replies to this topic

#1 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 22 January 2012 - 11:10 PM

STILL UNSOLVED...

Hopefully nobody steals what I have been working on, but in an effort to make things potentially easier for people to help me, here's the GMK: http://www.host-a.ne...tsArrays2.5.gmk

Okay, rephrasing and reorganizing some things so hopefully you wont have to run through the entire thread. Objects are color coded to be more distinguishable.

I am making a tower defense game. I wanted there to be a minimalist style menu system so that your screen is uncluttered whenever something isnt relevant (Basically, things fade out when not in use). My current problem exists with menu's. I have one menu set up in the top left corner that allows the player to simply overview towers and eventually their stats. When you hover over the square for the menu, it expands and a cascade of buttons comes down from it (9 buttons in total). Once scrolled over with the mouse there is a sprite drawn over the button to show which one you are currently over, this is called spr_select. I will post the code for obj_button (The square you scroll over) and obj_menu_button (the buttons that appear).

obj_button:
Create Event:
show=false;
alpha=0;
select=0;
time=20; // time the menu should use to move into place

Step Event:
// this controls image_alpha - max and min is to keep it between 0 and 1
alpha = min(1,max(0,alpha + (show-!show)*1/time))
image_alpha = 1-alpha; //alpha for menu - when it is gone then this should be clear
with(obj_menu_button)image_alpha = other.alpha*1; // give menu buttons the half the alpha. Old Value was 0.5 

if show=true{

// get the button number you are over if within menu area
if mouse_x>0 && mouse_x<32
&& mouse_y>0 && mouse_y<32*9{
  select = mouse_y div 32;
}

// if button pressed
if mouse_check_button_pressed(mb_left){
  show=false; // start closing down
  with(obj_menu_button){
    alarm[1]=other.time; // tell all menu buttons to start alarm 1
    vspeed=-((image_index*32)/other.time); // and move back up
  }
}

}

Mouse Enter:
if show=false{
  show=true; // start showing buttons
  for(i=1;i<10;i+=1)instance_create(x,y,obj_menu_button) // create the buttons
  image_yscale = image_yscale*(9)
}

Mouse Leave:
if show=true{
  show=false; // start hiding buttons
  with(obj_menu_button){
    alarm[1]=other.time; // tell all menu buttons to start alarm 1 which gets rid of them
    vspeed=-((image_index*32)/other.time); // and move back up
    }
image_yscale = image_yscale / (9) //Scale the main button back to 32x32
//put it outside of the width(obj_menu_button)
}
Draw Event:
// draw the button
draw_sprite_ext(sprite_index,image_index,x,y,1,1,0,c_white,image_alpha) //x,y,1,1,0,c_white...

// draw the info
draw_set_color(c_black)
draw_set_alpha(1)
draw_text(x+64,y,string(show)+ ' ' + string(alpha)+'#'+tower_text[(select+1)mod 10]) //Changes position of 'select 0 or 1' , 'alpha #' , and the name of the tower.

// make the buttons draw the text
with(obj_menu_button){
  draw_set_alpha(image_alpha) // using the alpha it currently has
  draw_text(x+36,y,string(image_index+1)) // draw its number +1 - This is the number beside the tower to signify which key to hit.
  if other.select = image_index draw_sprite(spr_select,0,x,y) // if selected - then draw selection rectangle
}



obj_menu_button:

Create Event:
image_index = instance_number(object_index)-1
image_speed=0;

if image_index < 0 { instance_destroy(); exit; }

alarm[0]=obj_button.time;
vspeed = (image_index*32)/alarm[0];

Alarm 0:
y=image_index*32
speed=0;

Alarm 1:
instance_destroy()



Now, my problem arises when I want to create the same system, but one that is activated through right clicking and can be placed anywhere on the screen. This is my current setup involving obj_rightclick_button (equal to obj_button) and obj_right_menu_button (equal to obj_menu_button) and spr_select2 (Same as spr_select but with different coloring). Most of the code is exactly the same with a few number tweaks here and there. The main problem is that spr_select2 will not draw over the scrolled over button.

Within the step event of obj_rightclick_button is:
if mouse_x>0 && mouse_x<928
&& mouse_y>0 && mouse_y<672

The numbers there are purely experimental. I tried that to see if I could give it a range of the whole games viewing area to see if it made a difference.

Anyways, this menu has two main differences of vanishing once the right mouse button is released and of course being much smaller (only two buttons)
Here is applicable code:

obj_rightclick_button:
Create Event:
//Same stuff, different location
show=true;
alpha=0;
select=0;
time=20; // time the menu should use to move into place

for(i=1;i<3;i+=1)instance_create(x-16,y-16,obj_right_menu_button) // create the buttons right as instance is created. using mouse enter didnt work when the mouse was already inside
  image_yscale = image_yscale*(2) //This menu is only 2 squares big

Step Event:
// this controls image_alpha - max and min is to keep it between 0 and 1
alpha = min(1,max(0,alpha + (show-!show)*1/time))
image_alpha = 1-alpha; //alpha for menu - when it is gone then this should be clear
with(obj_menu_button)image_alpha = other.alpha*1; // give menu buttons the half the alpha. Old Value was 0.5 

// this controls image_alpha - max and min is to keep it between 0 and 1
alpha = min(1,max(0,alpha + (show-!show)*1/time))
//image_alpha = 1-alpha; //alpha for menu - when it is gone then this should be clear
with(obj_right_menu_button)image_alpha = other.alpha*1; // give menu buttons the half the alpha. Old Value was 0.5 

if show=true{
// get the button number you are over if within menu area
if mouse_x>0 && mouse_x<928
&& mouse_y>0 && mouse_y<672
select = mouse_x && mouse_y;

}

Global Right Released:
if show=true{
  show=false; // start hiding buttons
  with(obj_right_menu_button){
    alarm[1]=other.time; // tell all menu buttons to start alarm 1 which gets rid of them
    vspeed=-((image_index*32)/other.time); // and move back up
    }
image_yscale = image_yscale / (2) //Scale the main button back to 32x32
//put it outside of the with(obj_menu_button)
instance_destroy(); //Destroys the menu after being done to allow the instance_number check on obj_create's right click event to reset to 0.
}

Draw Event:
//I havent fiddled much at all with this yet. Only thing that got changed was the 'with' statement and 'spr_select' now has a 2, to correspond to my eventual use of a different style button.

// draw the button
draw_sprite_ext(sprite_index,image_index,x,y,1,1,0,c_white,image_alpha) //x,y,1,1,0,c_white...

// draw the info
draw_set_color(c_black)
draw_set_alpha(1)
draw_text(x+64,y,string(show)+ ' ' + string(alpha)+'#'+tower_text[(select+1)mod 10]) //Changes position of 'select 0 or 1' , 'alpha #' , and the name of the tower.

// make the buttons draw the text
with(obj_right_menu_button){
  draw_set_alpha(image_alpha) // using the alpha it currently has
  draw_text(x+36,y,string(image_index+1)) // draw its number +1 - This is the number beside the tower to signify which key to hit.
  if other.select = image_index draw_sprite(spr_select2,0,x,y) // if selected - then draw selection rectangle
}


obj_right_menu_button:
Create Event:
image_index = instance_number(object_index)-1; //There can clearly only be one of these at a time. Releasing right mouse button, causes this to destroy itself.
image_speed=0;
//So image_index=0;

if image_index < 0 { instance_destroy(); exit; }

alarm[0]=obj_rightclick_button.time; //Changed to new instance. That is all. No further code touched on buttons.
vspeed = (image_index*32)/alarm[0];

Alarm 0:
speed=0;

Alarm 1:
instance_destroy()

Edited by Zealot644, 06 February 2012 - 08:02 PM.

  • 0

#2 c_raethke

c_raethke

    TeamSkyfire

  • GMC Member
  • 2008 posts

Posted 23 January 2012 - 12:57 AM

Does obj_menu_button have a draw event? Also, what is this:
select = mouse_x && mouse_y;
&& will return a boolean from 2 booleans, so in this case, both will be "true" if the mouse is inside/right of/below the window.
  • 0

#3 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 23 January 2012 - 02:06 AM

Does obj_menu_button have a draw event? Also, what is this:

select = mouse_x && mouse_y;
&& will return a boolean from 2 booleans, so in this case, both will be "true" if the mouse is inside/right of/below the window.


obj_menu_button does not have a separate draw event. It is drawn through the obj_button.

As for &&, I was just translating it to 'and' in my mind. I dont know what to change... it worked for the other one.
  • 0

#4 c_raethke

c_raethke

    TeamSkyfire

  • GMC Member
  • 2008 posts

Posted 23 January 2012 - 05:28 PM

What do you want that code to do?
  • 0

#5 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 24 January 2012 - 12:44 AM

What do you want that code to do?



I have a menu in the top left that reveals buttons when scrolled over. When you scroll over said buttons, a box appears over them called spr_select.

I copied this and changed the according code to create a smaller menu that appears with right clicked. It functions the same in every way except for the fact that spr_select2 (it's colored differently) doesnt move alongside the mouse.
  • 0

#6 torigara

torigara

    GMC Member

  • GMC Member
  • 6483 posts

Posted 24 January 2012 - 05:14 AM

As for &&, I was just translating it to 'and' in my mind. I dont know what to change... it worked for the other one.

That line "select = mouse_x && mouse_y;" is equivalent to:

if (mouse_x > 0 && mouse_y > 0) { // If both of mouse_x and mouse_y is evaluated as true
    select = 1; // the result is true (1)
}
else { // otherwise (i.e. mouse_x <= 0 or mouse_y <= 0)
    select = 0; // the result is false (0)
}

It will select the first item when the mouse is exactly at the top left corner of the room, or the second item otherwise. I don't think that is what you want, do you?

The "other one" doesn't quite look similar...

// get the button number you are over if within menu area
if mouse_x>0 && mouse_x<32
&& mouse_y>0 && mouse_y<32*9{
  select = mouse_y div 32;

It divides mouse_y by 32 and takes its quotient. Therefore:
  • select = 0 when mouse_y is between 0 and 31
  • select = 1 when mouse_y is between 32 and 63
  • select = 2 when mouse_y is between 64 and 95
  • ...
  • select = 8 when mouse_y is between 256 and 287
That is what the first one does. Now, along with this line, what do you expect the variable "select" be with respect to mouse_x and mouse_y?

 
The other problem is in the usage of the keyword other.

Draw Event:

draw_set_alpha(image_alpha) // using the alpha it currently has
  draw_text(x+36,y,string(image_index+1)) // draw its number +1 - This is the number beside the tower to signify which key to hit.
  if other.select = image_index draw_sprite(spr_select2,0,x,y) // Note: spr_select2. Otherwise, same as above.

The first one was used inside the with() statement:

with(obj_menu_button){
...
}

So, "other" was used to access the original self instance that is executing the code. The second one isn't inside with(), so you don't have to put it in front of variables.
...
if select == image_index draw_sprite(spr_select2, 0, x, y);

Edited by torigara, 24 January 2012 - 07:44 AM.

  • 0

#7 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 24 January 2012 - 08:54 PM

That is what the first one does. Now, along with this line, what do you expect the variable "select" be with respect to mouse_x and mouse_y?


There is a number that shows beside which is based on the value of select. That is all.

So, "other" was used to access the original self instance that is executing the code. The second one isn't inside with(), so you don't have to put it in front of variables.


I dont quite get what you're saying. I dont see anything wrong with this...That one refers to obj_menu while my second button refers to obj_rightclick_menu.
  • 0

#8 torigara

torigara

    GMC Member

  • GMC Member
  • 6483 posts

Posted 25 January 2012 - 01:38 AM

There is a number that shows beside which is based on the value of select. That is all.

Sorry, it doesn't help us to help you at all. All it tells is:
  • select will be something when mouse is somewhere in the top left region of the screen, (0,0)-(928,672)
Couldn't you elaborate it a bit more, so we can actually help you? For your instance, the first code divides the region at the top left of the screen into 9 sections vertically, then assigns select for each section.
    0             32 <- mouse_x
  0 +------------+
    | select = 0 |
 32 +------------+
    | select = 1 |
 64 +------------+
    | select = 2 |
 96 +------------+
    | select = 3 |
128 +------------+
    | select = 4 |
160 +------------+
    | select = 5 |
192 +------------+
    | select = 6 |
224 +------------+
    | select = 7 |
256 +------------+
    | select = 8 |
288 +------------+
 ^
 |
mouse_y
As to the second one, we guess that you want to divide the region into two sections vertically. However, the region is no longer at the top left of the screen. Right?
    (??)          928 <- mouse_x
(??)+------------+
    | select = 0 |
(??)+------------+
    | select = 1 |
672 +------------+
  ^
  |
mouse_y
Tell us other three numbers indicated by "??" in the above picture (and correct the given two if necessary), then we could come up with right expressions.


I dont quite get what you're saying. I dont see anything wrong with this...That one refers to obj_menu while my second button refers to obj_rightclick_menu.

I mean, there is the huge difference that the first one is enclosed in the with() {...} statement while the second one isn't. The keyword "other" was necessary in the first case, but should no longer be there in the second.

Edited by torigara, 25 January 2012 - 01:47 AM.

  • 0

#9 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 26 January 2012 - 12:35 PM

The numbers indicated by ?? would be changed I guess depending on where the person right clicks. You can bring up the menu anywhere (It's going to be used for towers hopefully) so it changes depending on where the mouse is when you click. If there was a way to refer to the coordinates like this:

(01)          928 <- mouse_x
(02)+------------+
    | select = 0 |
(03)+------------+
    | select = 1 |
672 +------------+
  ^
  |
mouse_y
 //01 - Would be 0 in relation to where obj_rightclick_menu was created
//02 - Would be 0 in relation to where obj_rightclick_menu was created
//03 - Would be 32 in relation to where obj_rightclick_menu was created
//04 - Doesnt exist, but if it did it would be 64 in relation to where obj_rightclick_menu was created.
//## - So on and so forth, but in the same style of 32 pixels each time like in the original menu.
// Attempt at making sense.

As for the 'other' stuff, I'm still not sure what you're saying.

Here (I guess I didnt explain well enough): http://www.host-a.ne...tsArrays2.5.gmk

Test it out and maybe you'll see what I'm trying to do :)

Apologies on the late reply. I'm in the middle of exams so most of my leisure time has been spent studying :(

Edited by Zealot644, 26 January 2012 - 12:46 PM.

  • 0

#10 torigara

torigara

    GMC Member

  • GMC Member
  • 6483 posts

Posted 27 January 2012 - 03:49 AM

So, you want it relative to the position of obj_rightclick_menu.x and obj_rightclick_menu.y, right? That 928 and 627 don't look to be correct values either, they should be relative to that point as well. And now we can tell each section is 32 pixels height. The only number left unknown to us is the width of the section.
         RX+0         RX+(??)
          |            |
          v            v

RY+0  --> +------------+
          | select = 0 |
RY+32 --> +------------+
          | select = 1 |
RY+64 --> +------------+

where
RX = obj_rightclick_menu.x
RY = obj_rightclick_menu.y
(??) = width of the section
Ok, some progress. This part of your code:

if mouse_x>0 && mouse_x<928 //Was originally 32 in place of 928. These two were part of my attempts at having spr_select2 be drawn in the proper place instead of restricted to the top left in a column. 
&& mouse_y>0 && mouse_y<672 //Was originally 32*9 in place of 672.
select = mouse_x && mouse_y;

Should be this.
if (mouse_x > obj_rightclick_menu.x
 && mouse_x < obj_rightclick_menu.x + (??)
 && mouse_y > obj_rightclick_menu.y
 && mouse_y < obj_rightclick_menu.y + 32*2)
    select = (mouse_y - obj_rightclick_menu.y) div 32;

As for the 'other' stuff, I'm still not sure what you're saying.

I don't see how it is so hard to eliminate extra six letters those are no longer needed. I'm simply saying that this part (the second draw event) has a problem...

Draw Event:

draw_set_alpha(image_alpha) // using the alpha it currently has
  draw_text(x+36,y,string(image_index+1)) // draw its number +1 - This is the number beside the tower to signify which key to hit.
  if other.select = image_index draw_sprite(spr_select2,0,x,y) // Note: spr_select2. Otherwise, same as above.

namely the third line. This is wrong:
if other.select = image_index draw_sprite(spr_select2,0,x,y) // Note: spr_select2. Otherwise, same as above.
This is correct (extra white spaces are inserted to indicate which part needs change.)
if       select = image_index draw_sprite(spr_select2,0,x,y) // Note: spr_select2. Otherwise, same as above.
This bases on the assumption that those three lines are the entire code in the draw event. In case your actual second draw event has "with ()" statement above those lines, that's another story.

Edited by torigara, 27 January 2012 - 08:00 AM.

  • 0

#11 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 28 January 2012 - 10:02 PM

With the code changes you have put there, did it allow spr_select2 to be drawn over the appropriate square?

What would go in place of ?? , would it be 32? and what is the purpose of checking of mouse x is greater than or less than the x of obj_rightclick_menu?
if (mouse_x > obj_rightclick_menu.x
 && mouse_x < obj_rightclick_menu.x + (??)
 && mouse_y > obj_rightclick_menu.y
 && mouse_y < obj_rightclick_menu.y + 32*2)
    select = (mouse_y - obj_rightclick_menu.y) div 32;

As for the 'other' part, I was still under the impression that it was required to refer to another part of the code within the object. If it isnt required, then I shall remove it.

Edited by Zealot644, 29 January 2012 - 05:51 AM.

  • 0

#12 c_raethke

c_raethke

    TeamSkyfire

  • GMC Member
  • 2008 posts

Posted 28 January 2012 - 10:10 PM

The "other" keyword is used to refer to either the other object in a collision event, or in a case where you are referring to a different object's code (using the "with" statement, it executes the code from a different object's point of view, so other would refer to the calling object's variables). As long as you create a variable inside an object in GM (a local variable) that object can access it whenever it wants by using the variable name. To access another object's variable however, you need to use (otherobject's id).variable. The other acts as the id for the other object.

The mouse checking is to check wether the arrow is inside a rectangle. Most sprites have their "origin", or (x,y) position, at the top left corner (0,0), or relative, (x,y). So you need to check that the mouse x is greater than x, and mouse y is greater than y. You also need to make sure the mouse x is LESS THAN the x position plus the width of the sprite, and the mouse y is LESS than the y position plus the height of the sprite, to make sure you are only selecting it when the mouse is within the boundaries of the sprite.

Whenever I need to check if the mouse is inside a certain area, I usually create a "mouse_in_rectangle(x1,y1,x2,y2) script so I can easily just call it to return a true/false if the mouse is in the specified rectangle.

Edited by c_raethke, 28 January 2012 - 10:12 PM.

  • 0

#13 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 29 January 2012 - 05:49 AM

Okay. Good explanation.

I'm still trying to figure out where to go with this code...I never thought that something as simple as making a sprite draw in the correct spot would be so difficult =\
  • 0

#14 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 29 January 2012 - 05:56 AM

This bases on the assumption that those three lines are the entire code in the draw event. In case your actual second draw event has "with ()" statement above those lines, that's another story.


Well, there is one more line that I didnt include (thinking it wasnt of much importance) and it involves brackets... :P

with(obj_right_menu_button){
  draw_set_alpha(image_alpha) // using the alpha it currently has
  draw_text(x+36,y,string(image_index+1)) // draw its number +1 - This is the number beside the tower to signify which key to hit.
  if select = image_index draw_sprite(spr_select2,0,x,y) // if selected - then draw selection rectangle

So, what now?

Edited by Zealot644, 31 January 2012 - 04:57 PM.

  • 0

#15 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 31 January 2012 - 05:01 PM

Well, after experimenting myself for a few hours...No idea =\
  • 0

#16 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 02 February 2012 - 10:38 PM

BUMP ... Please, somebody =\
  • 0

#17 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 04 February 2012 - 12:44 AM

Considering remaking this topic.

Is there literally nobody who can help?
  • 0

#18 greep

greep

    Menaces with Spikes

  • GMC Member
  • 2297 posts
  • Version:GM7

Posted 04 February 2012 - 01:06 AM

Don't make a new topic, just repost the entirety of what your code looks like now and restate exactly what it's doing/the problem is. I can't follow this whole thread.
  • 0

#19 Zealot644

Zealot644

    GMC Member

  • New Member
  • 266 posts
  • Version:GM8

Posted 04 February 2012 - 07:11 AM

I have edited and updated my post. It should be easier to follow now.
  • 0

#20 greep

greep

    Menaces with Spikes

  • GMC Member
  • 2297 posts
  • Version:GM7

Posted 04 February 2012 - 08:49 AM

grrr... when you updated your post you never changed the code to what people suggested, nor did you actually state what the problem is. So I had to read the whole thread anyways :whistle:

So, I ASSUME the problem is you are having select not selecting the correct button? (I've no idea, the problem isn't stated!) First of all, what exactly do you want to select the button? You say the first menu selects based on the height of your mouse. The second one... ??? We're not mindreaders, I'm as confused as the rest of the people in this thread. If you want it the same thing, then torigora's code is 100% correct. What did you try and what is it doing?

I'm sorry, but I have no idea what's going on or what you want :/ Honestly, I think you should make 2-3 screenshots showing what your first menu looks like and how it works in a few stages, and telling PRECISELY what you want the second menu to do (like, explaining to children simple). If you do that, I guarantee you'll get better help. The problem we're having is not coding, but deciphering what you're doing and what you want.

TBH, I'm guessing your entire code could be scrapped and written in about 10 lines if done correctly, but honestly I can't tell for sure without knowing what you want.

Edited by greep, 04 February 2012 - 09:01 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users