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:
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.
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:
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?
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?
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;
}
I've used this, and it seems to work OK:
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.
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.
destx=(((mouse.x-gMap.X)*Room.Width)/gMap.Width)-System.ViewportWidth;
desty=(((mouse.y-gMap.Y)*Room.Height)/gMap.Height)-System.ViewportHeight;
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.
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).
Hmmm, interesting.
Then I still have the problem of the screen being offset.
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 ?
Aha! Turns out it -was- that the cursor wasn't centred properly ^_^ I am a fool.
Heh, you meaned the hotspot of the cursor as set at a wrong place ?
'Twas indeed.