GUIs, mouse clicks, various problems (SOLVED)

Started by Kinoko, Wed 08/11/2006 12:11:36

Previous topic - Next topic

Kinoko

This is the only piece of code in this game so far, so there really can't be aything conflicting. Whatever the problem is, it's here.

Basically, I have a room with one GUI in the top-left hand corner. The room background is 2040x2550 and the "map" GUI is 68x85. The map is a smaller version of the background and what I'd like is if you click on any given area of the GUI, the view scrolls to the corresponding area in the room.

This is the code I have so far:

Code: ags

		int ypos = 0;
		int xpos = 0;
		destx = ((mouse.x-gMap.X)*30)-640; //Establish the destination by converting
		desty = ((mouse.y-gMap.Y)*30)-480; //small map coords to large room coords
		if (destx<0) destx=0; //if destination is within 640x480, make
		if (desty<0) desty=0; //sure the dest coords don't go below 0
		
		int diffx = 0;
		int diffy = 0;
		if (GetViewportX()<destx) diffx = destx-GetViewportX(); //Establish the distance between
    else if (GetViewportX()>destx) diffx = GetViewportX()-destx; //current X,Y coords
		if (GetViewportY()<desty) diffy = desty-GetViewportY(); //and the destination X,Y coords
		else if (GetViewportY()>desty) diffy = GetViewportY()-desty;
		
		int speedx = (diffx/10)-(diffx%10); //Set speed so larger distances are 
		int speedy = (diffy/10)-(diffy%10); //covered in the same time ie. scrolls faster
		
	while ((ypos != desty) || (xpos != destx)) {
		SetViewport(xpos, ypos);
		Wait(1);
		if (ypos<desty) ypos+=speedy;
		else if (ypos>desty) ypos-=speedy;
		if (xpos<destx) xpos+=speedx;
		else if (xpos>destx) xpos-=speedx;
	}


Perhaps more convoluted than it needs to be, but it seems to me it should work. It half works, because when I click on areas of the map, the screen does move but often ends up going twice as far as it needs to on the Y axis, or occasionally in the wrong direction entirely.

I can't help but feel it's my maths which is wrong here, and/or the mouse recognition.

Any ideas?

Oh, I've also noticed that the mouse cursor doesn't go down to the bottom of the screen. It stops perhaps about 20 pixels short, and of course seems to go about that much higher off the top of the page. What on earth could be causing this? I've never really coded for mouse/cursor functions so I'm stumped.

Also, I have another GUI made up with almost the exact same properties as the map GUI (which shows up everytime) which I just can't get to appear on the screen. I can think of no reason whatsoever for this. Even if I code a gDebug.Visible = true; into the game start, it won't show up. And yet, the gMap GUI shows up, as it should.

Sorry to ask so much, its just baffling that I have all these problems when there's really no more to the game than what I've mentioned here.

Ashen

#1
All basic stuff, but worth checking:

Quote
It half works, because when I click on areas of the map, the screen does move but often ends up going twice as far as it needs to on the Y axis, or occasionally in the wrong direction entirely.

What resolution is your game? I'd guess 640x480, because of the "if destination is within 640x480, make sure the dest coords don't go below 0" comments - but SetViewport(...) (and by extention GetViewportX/Y()) use 320x240 coordinates.
Multiplying coords by 30 would make the destination double what it should be ("often ends up going twice as far as it needs to") and subtracting 640 or 480 could make the coords a screen above or right of where you intended ("or occasionally in the wrong direction entirely").

What if you try:
Code: ags

  destx = ((mouse.x-gMap.X)*15)-320; //Establish the destination by converting
  desty = ((mouse.y-gMap.Y)*15)-240; //small map coords to large room coords
  if (destx<0) destx=0; //if destination is within 320x240, make
  if (desty<0) desty=0; //sure the dest coords don't go below 0


EDIT:
I've done a little test, and I'm not so sure about changing the '*30' to '*15'. Made sense in my head, but seems to halve the final coords...
However, you're resetting xpos and ypos to 0 with the first two lines, but you don't reset the current Viewport coordinates. So, your diffx/y values will be off - this could be what's screwing up the destinaion coords instead/as well as the above. Either add a SetViewport(0,0); in there, or declare x/ypos outside the function, so they don't reset.

Quote
Oh, I've also noticed that the mouse cursor doesn't go down to the bottom of the screen. It stops perhaps about 20 pixels short, and of course seems to go about that much higher off the top of the page.

Not sure what this means, any chance of a screenshot? (Unless it's nice and obvious to someone else.)
Or, could it be due to the positoning of the 'Hotspot' on the cursor graphic? If the hotspot is 20 pixels from the top of the image, it might look like what you're dsescribing - compare the placement on the default 'Walk to' and 'Pointer' modes to see what I mean.
If you display the actual mouse coordinates somewhere, does it stop before it reaches y = 239, or just appear to?

Quote
Even if I code a gDebug.Visible = true; into the game start, it won't show up. And yet, the gMap GUI shows up, as it should.
What are the coordinates of gDebug (x, y, and z)? Could it be hiding behind another GUI, or off-screen somehow?
I know what you're thinking ... Don't think that.

SSH

The problem may be that if you keep adding speedx to xpos (similarly with y) then it may never actually reach destx. So you need to, each cycle, compare the difference and if the difference is less than speedx, just set xpos to destx, otherwise do the addition. Also, why not just use negative speeds instead of all those ifs?



Code: ags

diffx = destx-GetViewportX();
diffy = desty-GetViewportY(); 

int speedx = (diffx/10); //Set speed so larger distances are
int speedy = (diffy/10); //covered in the same time ie. scrolls faster

Wait(1);

xpos+=diffx%10; // Make sure we end up exactly on the spot
ypos+=diffy%10; 

while ((ypos != desty) || (xpos != destx)) {
  SetViewport(xpos, ypos);
  Wait(1);
  ypos+=speedy;
  xpos+=speedx;
}

12

Ashen

I've used this, and it seems to work OK:
Code: ags

int destx, desty;
int ypos, xpos;
#sectionstart gMap_Click  // DO NOT EDIT OR REMOVE THIS LINE
function gMap_Click(GUI *theGui, MouseButton button) {
  destx = ((mouse.x-gMap.X)*30)-320; //Establish the destination by converting
  desty = ((mouse.y-gMap.Y)*30)-240; //small map coords to large room coords
	
  if (destx<0) destx=0; //if destination is within 320x240, make
  if (desty<0) desty=0; //sure the dest coords don't go below 0
	
  int diffx = destx-GetViewportX(); //Establish the distance between
  int diffy = desty-GetViewportY(); //and the destination X,Y coords
	
  int speedx = (diffx/10)-(diffx%10); //Set speed so larger distances are
  int speedy = (diffy/10)-(diffy%10); //covered in the same time ie. scrolls faster
	
  while ((ypos != desty) || (xpos != destx)) {
    if (ypos != desty) {
      if ((speedy < 0 && ypos < desty) || (speedy > 0 && ypos > desty)) ypos = desty;
      else ypos+=speedy;
    }
    
    if (xpos != destx) {
      if ((speedx < 0 && xpos < destx) || (speedx > 0 && xpos > destx)) xpos = destx;
      else xpos+=speedx;
    }
    SetViewport(xpos, ypos);
    Wait(1);
  }
}
#sectionend gMap_Click  // DO NOT EDIT OR REMOVE THIS LINE


But, SSH's idea would probably save those messy if..'s at the end.
I know what you're thinking ... Don't think that.

SSH

Also, if you want to make your code more re-usable, you can use System.ViewportHeight instead of 240, System.ViewportWidth instead of 320, gMap.Width, gMap.Height and Room.Width
and Room.Height to get the total size of your room.

Code: ags

  destx=(((mouse.x-gMap.X)*Room.Width)/gMap.Width)-System.ViewportWidth;
  desty=(((mouse.y-gMap.Y)*Room.Height)/gMap.Height)-System.ViewportHeight;

12

Kinoko

Thanks guys! The combination of those codes seems to work pretty well. I appreciate it ^_^

One problem still in the way is that I've discovered although the game is set to 640x480, the screen size is only 320x240.

On top of that, the screen is 10 pixels off-centre. My cursor stops 10 pixels short of the bottom of the screen, calling that point on the Y-axes "240" (actually, "239" to be exact). Of course, it goes 10 pixels off the top of the screen too.

Yet, I originally set the game to 640x480 and that's what it says in Game Settings.

Gilbert

Yeah, in 640x480 the game coordinate system is still 320x240, so actually System.ViewportWidth will only return 320 or 400 (for 800x600 games), while System.ViewportHeight will only return 200, 240 or 300.
But still using these system parameters helps make the codes more portable (especially when you want to reuse them in some other games just by copying the codes, or maybe making a module).

Kinoko

Hmmm, interesting.

Then I still have the problem of the screen being offset.

Gilbert

About the screen-offcentering problem, did the same happen when you test the game in windowed mode?

Could it be just the monitor settings not properly adjusted when displaying in that mode ?

Kinoko

Aha! Turns out it -was- that the cursor wasn't centred properly ^_^ I am a fool.

Gilbert

Heh, you meaned the hotspot of the cursor as set at a wrong place ?

Kinoko


SMF spam blocked by CleanTalk