Scrolling screen background issues

Started by jamesreg, Sun 03/02/2019 03:40:25

Previous topic - Next topic

jamesreg

My default screen size is 480 x 270 but I am using a 1400 x 2800 background

Beings the background is larger then the room size it is automatically a scrolling background.

What I need to achieve with this scene is the following:

1) I need the cursor to be able to move freely around the screen like normal but to cause the room to scroll
2) I need it to scroll smoothly
3) I need the mouse buttons to function
4) I need to have a GUI which will look like a view screen with a cutout that mouse clicks can pass though it will be roughly the size of the normal background room of 480x270 minus a few pixels around the 4 borders
5) I need the mouse targeting mode to be confined within the borders of that gui cutout but still scroll the screen
6) I need to be able to hit tab key and break out of the border area and be able to access other guis and tab again to return to the targeting cursor within the borders.
7) I need the screen to wrap around and continue to scroll when it hits any of the four borders smoothly and instantly

I have seen a few examples of a couple of these things in forums but I am confused about how to get it to all work the way I want and that many do it various different ways so some help getting this going would help a lot.

Ok I added this code from another post

Code: ags
function room_RepExec()
{
//Bridge facing front view
if (Bridge_Scene_Front==true) {
SetViewport(0, 0);
SetBackgroundFrame(0);

}
//Bridge facing back view
if (Brige_Scene_Back==true) {
SetViewport(480, 0);
SetBackgroundFrame(0);

}
//Close up Viewscreen view
if (Bridge_Scene_Viewscreen==true) {
SetViewport(960, 0);
SetBackgroundFrame(0);

}
//full star backgound for battle mode
if (Bridge_Scene_Battlemode==true) {
SetBackgroundFrame(1); 
ReleaseViewport();  
gBridge_Viewer_Full.Visible=true;

if (System.Windowed) mouse.SetBounds(0, 0, System.ViewportWidth - 1, System.ViewportHeight - 1);

int thisPositionX = mouse.x - System.ViewportWidth / 2;
  int thisPositionY = mouse.y - System.ViewportHeight / 2;
  // of course - AGS crashes if you don't check if the viewport is being changed beyond the boundaries
  int viewX = GetViewportX() + (thisPositionX - lastPositionX);
  int viewY = GetViewportY() + (thisPositionY - lastPositionY);
  if (viewX < 0) viewX = 0;
  else if (viewX >= Room.Width - System.ViewportWidth) viewX = Room.Width - System.ViewportWidth; 
  if (viewY < 0) viewY = 0;
  else if (viewY >= Room.Height - System.ViewportHeight) viewY = Room.Height - System.ViewportHeight;
  SetViewport(viewX, viewY);
  lastPositionX = thisPositionX;
  lastPositionY = thisPositionY;
 
  if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
    mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
    lastPositionX = 0;
    lastPositionY = 0;
    mouse.Visible=false;
    gTargetCursor.Centre();
  }
 if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
  mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  lastPositionX = 0;
  lastPositionY = 0;
}

}
}


I used a Gui as a target cursor and made the regular mouse cursor invisible.

I have to pick up the mouse and sit it back down to scroll over large areas. but i know the above code was for a game with 320x240 my base game is 480x270 and my scrolling background is 2800x1400  i think i changed the numbers of 80, 240, 80, 160  correctly I changed them to 210, 270, 210, 220 is that correct?

I also need to know how I would go about being able to use that GUI cursor to process clicks onto characters, objects etc like it is a mouse cursor.

I also need to be able to hit tab and restore normal mouse function over the entire screen or restore mouse function when on an open gui and tab again to return to gui target cursor mode.




Khris

Scrolling the entire screen works like this:

The x viewport range is 0 to Room.Width - System.ViewportWidth
The y viewport range is 0 to Room.Height - System.ViewportHeight

The mouse's x range is 0 to System.ViewportWidth - 1
Same for y.

Which means you need this in the room's RepExec:
Code: ags
  int x = FloatToInt(IntToFloat(mouse.x) / IntToFloat(System.ViewportWidth - 1) * IntToFloat(Room.Width - System.ViewportWidth), eRoundNearest);
  int y = FloatToInt(IntToFloat(mouse.y) / IntToFloat(System.ViewportHeight - 1) * IntToFloat(Room.Heigth - System.ViewportHeight), eRoundNearest);
  SetViewport(x, y);

jamesreg

#2
Quote from: Khris on Mon 04/02/2019 08:23:33
Scrolling the entire screen works like this:

The x viewport range is 0 to Room.Width - System.ViewportWidth
The y viewport range is 0 to Room.Height - System.ViewportHeight

The mouse's x range is 0 to System.ViewportWidth - 1
Same for y.

Which means you need this in the room's RepExec:
Code: ags
  int x = FloatToInt(IntToFloat(mouse.x) / IntToFloat(System.ViewportWidth - 1) * IntToFloat(Room.Width - System.ViewportWidth), eRoundNearest);
  int y = FloatToInt(IntToFloat(mouse.y) / IntToFloat(System.ViewportHeight - 1) * IntToFloat(Room.Heigth - System.ViewportHeight), eRoundNearest);
  SetViewport(x, y);


So your code above is all I need to make it scrolling?  I do not need what I had in there before which is this
Code: ags
if (System.Windowed) mouse.SetBounds(0, 0, System.ViewportWidth - 1, System.ViewportHeight - 1);
 
int thisPositionX = mouse.x - System.ViewportWidth / 2;
  int thisPositionY = mouse.y - System.ViewportHeight / 2;
  // of course - AGS crashes if you don't check if the viewport is being changed beyond the boundaries
  int viewX = GetViewportX() + (thisPositionX - lastPositionX);
  int viewY = GetViewportY() + (thisPositionY - lastPositionY);
  if (viewX < 0) viewX = 0;
  else if (viewX >= Room.Width - System.ViewportWidth) viewX = Room.Width - System.ViewportWidth; 
  if (viewY < 0) viewY = 0;
  else if (viewY >= Room.Height - System.ViewportHeight) viewY = Room.Height - System.ViewportHeight;
  SetViewport(viewX, viewY);
  lastPositionX = thisPositionX;
  lastPositionY = thisPositionY;
 
  if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
    mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
    lastPositionX = 0;
    lastPositionY = 0;
    mouse.Visible=false;
    gTargetCursor.Centre();
  }
 if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
  mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  lastPositionX = 0;
  lastPositionY = 0;


I get this error when trying the smaller code:

The code I had above made it scroll but the smaller code you gave me it does not scroll at all.


Let me explain everything I am trying to do with this scene.


The above image is my background for space combat mode in which I will need the scrolling screen
It is 3000x3000


This is GUI sample art which I will overlay on top it is room size which is 480x270
The cut out viable area in middle is 437x208.
I am wanting the mouse to be confined to that 437x209 area and scroll from there so your locked into that area to contol movement.
I am told I must use a gui as a target cursor and make the mouse invisible. Ideally I would rather have the mouse visable as the target cursor
but it is very jumpy and stuff when scrolling so I guess thats why it was suggested to use a gui as target cursor. My next step after this is figuring a couple things out.

Like I would want to hit tab and break out of the confines of the viewscreen and have full screen mouse mode with no scrolling to access guis and other things. then tab to go back into scroll mode again.
Also unsure how to now be able to use that target cursor gui as if it was a mouse and be able to fire on ships and do other interactions like scanning or such I may want to do now that its a gui not a mouse.

I also need to get the screen to wrap around at the 4 edges to give a 3d look and feel to it.

Please forgive me I have put together a hell of a game so far with basic ags knowledge but am attempting a few things outside my ability to finish this project up. I do appreciate all help I have learned so much and been able to do more and more because of the support of this forum so please forgive me the help has been immensely appreciated

do I need to put the room diminsions in the setviewport part of the script you gave me?

Snarky

OK, this is doable!

First, let's take a look at this:

Quote from: jamesreg on Sun 03/02/2019 03:40:25
7) I need the screen to wrap around and continue to scroll when it hits any of the four borders smoothly and instantly

The way to do this is to make the room overlap by one screen's width and height. So instead of making it 3000x3000 (assuming that's all "unique" background), it needs to be 3480x3270, and the strip to the right and on the bottom needs to match the left and the top. So when you "wrap around", first you're just seeing the copy, and then when you run out of overlap, we just jump back to the other side of the room again and keep going, giving the impression of a seamless transition. This does mean that you also have to copy the walkbehinds, hotspots and walkable areas, and if you have any objects or characters in the room, you need to teleport them over as well. So it could be some work, depending on exactly what you need.

Quote from: jamesreg on Mon 04/02/2019 14:07:02
So your code above is all I need to make it scrolling?  I do not need what I had in there before which is this

That depends. The problem is that these requirements are a little bit ambiguous:

Quote from: jamesreg on Sun 03/02/2019 03:40:25
1) I need the cursor to be able to move freely around the screen like normal but to cause the room to scroll
2) I need it to scroll smoothly

What Khris's code will do is to constantly nudge the background around slightly whenever you move the mouse, so that even though it's not all visible on screen at the same time, moving the mouse cursor to the top left brings that corner into view, moving it to the center brings the center into view, bottom right brings that corner into view, etc.

However, I don't think that's what you actually want (because for one thing, it doesn't really allow for wrapping around). My interpretation is that you want the background to stay still while you're moving the cursor across the screen, unless you move it to the edge, and then it should scroll in that direction. For that, you need slightly different code.

Quote from: jamesreg on Mon 04/02/2019 14:07:02
I am wanting the mouse to be confined to that 437x209 area and scroll from there so your locked into that area to contol movement.
I am told I must use a gui as a target cursor and make the mouse invisible. Ideally I would rather have the mouse visable as the target cursor
but it is very jumpy and stuff when scrolling so I guess thats why it was suggested to use a gui as target cursor.

Mmmno, that doesn't sound right. I don't see any reason why you can't just keep it as a normal cursor. You can confine it to move in only a certain area by resetting the Mouse.X or Mouse.Y coordinate if it goes out of bounds in repeatedly_execute_always() or late_repeatedly_execute_always(). If it's jumpy "and stuff" (?) when scrolling, that might be some error in the code you're using.

Sorry not to give you any sample code, I just don't have the time right now.

jamesreg

#4
Ok I have been working on this.

Here is what the scene currently is planned to do:

1) Room is currently set at 3000 x 3000 Scrolling loopable looking background

2) Normal Game room is is 480 x 270

3) The area within the viewscreen cutout gui which the mouse needs to stay in when scrolling is 437x209

3) The screen is a screen full of stars the mouse is set to scroll the screen around the stars with a GUI overlay of a view screen
     I tried different things along the way some suggest I use a centered gui and turn off the mouse. This does not work for me cause
     I want to process mouse clicks. So I used set it to follow the mouse as a target cursor. it looks to scroll more smoothly when I use a Gui
     I fixed this a bit by making the character invisible and having it follow the mouse to. But it is still a bit jerky around the mouse part not bad 
     but not as smooth looking as when i had the gui so if anyone has ideas on that part.

4) I have a hotkey by pressing the Z key is supposed to take me out of scrolling mode and restore the mouse to full screen mode to access GUI and such however I have a glitch and for some reason it will only work if in insert a Display command then cancle that text off the screen. So I have it saying "you are in scrolling mode" "You are out of scrolling mode" But I do not want any message at all just press Z and switch back and forth so If someone can see where my code is messed up at and why I need the display command to switch back and forth that be great.

4) I do not know how to wrap the screen around when you get to the top/bottom  left/write of screen I need to to wrap around to the opposite side of the screen. Can someone help with this.

Here is my room code

Code: ags
// room script file
int lastPositionX, lastPositionY;

//BEFORE ROOM LOAD SCRIPTS
function room_Load()
{
cEgo.Transparency=100; //Make Character invisible 
Bridge_Battle=true;    //Put room in Battle mode starting
}

//scripts that repeatidly fire
function room_RepExec()
{
  //Testing script to exit game 
  if (IsKeyPressed(eKeyEscape)) {
    QuitGame(0);
  }
  //End of Testing Script  
  
 //If Z key is pressed and mode is battle mode
  if (IsKeyPressed(eKeyZ) && Bridge_Battle==true) {
    
   Display("Navigation mode off."); //Display message that Scrolling mode is off
   mouse.Visible=true;     //Make mouse visable
   Bridge_Battle=false;    //Turn Battle mode off and restore full screen mose movement
  Mouse.Mode=eModePointer; //Turns mouse back into pointer mode
  //ReleaseViewport();
}
   // If Z key is pressed and battle mode is off
  if (IsKeyPressed(eKeyZ) && Bridge_Battle==false) {
   Display("Navigation Mode on.");  //Display Message Scrolling mode is on
   Mouse.Mode=eModeTarget; //Turns mouse back into a targeting cursor
   Bridge_Battle=true; //Turn battle mode and scrolling back on
   }
  
  //IF MODE IS Space Battle Mode
  //Scrolling script
  if (Bridge_Battle==true) {
     cEgo.x = mouse.x;
    cEgo.y = mouse.y;
    
    //Turn of Mouse Cursor and Turn on Targeting Cursor
    mouse.Mode=eModeTarget;
    mouse.Visible=true;
    gGui2.Visible=true;
    
  //Space Battle scrolling Mode
  //IF game is running in windowed mode
  if (System.Windowed) mouse.SetBounds(0, 0, System.ViewportWidth - 1, System.ViewportHeight - 1);
 
//Scrolling room script
int thisPositionX = mouse.x - System.ViewportWidth / 2;
  int thisPositionY = mouse.y - System.ViewportHeight / 2;
  // of course - AGS crashes if you don't check if the viewport is being changed beyond the boundaries
  int viewX = GetViewportX() + (thisPositionX - lastPositionX);
  int viewY = GetViewportY() + (thisPositionY - lastPositionY);
  if (viewX < 0) viewX = 0;
  else if (viewX >= Room.Width - System.ViewportWidth) viewX = Room.Width - System.ViewportWidth; 
  if (viewY < 0) viewY = 0;
  else if (viewY >= Room.Height - System.ViewportHeight) viewY = Room.Height - System.ViewportHeight;
  SetViewport(viewX, viewY);
  lastPositionX = thisPositionX;
  lastPositionY = thisPositionY;
 
  if (mouse.x < 118 || mouse.x > 236 || mouse.y < 118 || mouse.y > 236) {
    mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
    lastPositionX = 0;
    lastPositionY = 0;
    
   
  }
 if (mouse.x < 210 || mouse.x > 270 || mouse.y < 210 || mouse.y > 420) {
  mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  lastPositionX = 0;
  lastPositionY = 0;
 }
 //End of Space Battle Scrolling mode


  }
}



Also I used the code for the scrolling from another forum post of someone doing the same thing. Some numbers need to be adjusted for my game but not sure how to make the conversion that area is here.

Code: ags
 if (mouse.x < 118 || mouse.x > 236 || mouse.y < 118 || mouse.y > 236) {
    mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
    lastPositionX = 0;
    lastPositionY = 0;
    
   
  }
 if (mouse.x < 210 || mouse.x > 270 || mouse.y < 210 || mouse.y > 420) {
  mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  lastPositionX = 0;
  lastPositionY = 0;



Cassiebsg

4) Everything else seems too complicated for me, but just wanted to suggest to replace that Display with Wait(1); and see if that does the trick.  ;)
There are those who believe that life here began out there...

Snarky

#6
OK, it's good that you explain what you want to do as well as you can, so that we can plan ahead. However, with a task like this we always want to break it down into smaller problems, and focus on solving those one at a time. In this case, I recommend that we start with just the infinitely scrolling room. All the stuff about the GUI and locking the mouse to part of the screen and switching between modes can be ignored for now.

Quote from: jamesreg on Tue 05/02/2019 16:47:37
Here is what the scene currently is planned to do:

1) Room is currently set at 3000 x 3000 Scrolling loopable looking background

2) Normal Game room is is 480 x 270

...

4) I do not know how to wrap the screen around when you get to the top/bottom  left/write of screen I need to to wrap around to the opposite side of the screen. Can someone help with this.

Did you read my post? Did you understand it? Can you confirm what sort of scrolling behavior you actually want, or did I guess wrong?

This code looks more like you don't really want a mouse cursor at all, but instead just a targeting sight in the middle of the screen, and by moving the mouse around the background just moves. That's a third alternative interpretation of what you mean! (But in that case, I don't understand what you mean by saying that the mouse can't move outside a given region, if there is no moving mouse cursor.) Before we waste time helping you implement something that isn't what you're trying to do, please explain the scrolling behavior you want more precisely.

Anyway, in this case, what I would do is (Edit: slight clarification):

-Hide the cursor and just display the targeting sight as a GUI fixed to the middle of the screen
-Set the mouse position to the center of the screen
-Every loop:
  -get the x,y mouse coordinate
  -subtract the x,y coordinate of the center of the screen from this coordinate
  -Move the viewport by that distance (wrapping around, we'll get to this later)
  -reset the mouse position to the center of the screen

This is very close to what you're currently doing, except that you've put the last step behind an if clause that only happens if the mouse moves outside a certain region: I think this is the main reason why it is jerky. Also, you don't really need the thisPositionX and lastPositionX variables, since the lastPosition will always be the screen center, and the thisPosition is simply the mouse position.

There are a number of other problems with the code, too. For one thing, you're pointlessly moving the (invisible) player character around to match the mouse cursor. This is pointless: which part of a scrolling room the screen should show is defined by the viewport. Usually the viewport follows the player character around so you're in the center of the screen, but by calling SetViewport you can move it wherever you want, and then it no longer follows the character. Since you're calling SetViewport later in the script, there's absolutely no reason to move the character around.

Crimson Wizard

Quote from: Snarky on Tue 05/02/2019 17:43:54
-Hide the cursor and just display the targeting sight as a GUI fixed to the middle of the screen
-Every loop: get the x,y mouse coordinate
-subtract the x,y coordinate of the center of the screen from this coordinate
-Move the viewport by that distance
-reset the mouse position to the center of the screen

I have read this is roughly how they do in 1st person shooters.

Snarky

#8
As for the wrapping around, it's pretty simple, once you've set up the Room as I explained:

Code: ags
  // We've calculated the Viewport coordinates we want as explained above. Let's call them viewportX and viewportY
  int wrapWidth = Room.Width - System.ViewportWidth;
  int wrapHeight = Room.Height - System.ViewportHeight;
  viewportX = (viewportX + wrapWidth) % wrapWidth;
  viewportY = (viewportY + wrapHeight) % wrapHeight;
  SetViewport(viewportX, viewportY);


The % symbol is the modulo operator, which is basically a "wraparound" operation. For example, 19 % 12 gives you what 19:00 is on a 12-hour clock: 7:00 (though it will show 0 for 12). By doing a modulo by the room width/height minus the screen width/height and setting the top corner of the screen to that, we ensure that whenever we would go off the edge of the room, we wrap around to the other side.  The only other gotcha is that using modulo on a negative number also gives a negative number, so to avoid that (if we scroll off the left edge or top of the room), we add wrapWidth/Height to our X/Y coordinates first, to make sure it's positive. (Basically, this means that whenever we "scroll left", we instead scroll almost one whole "loop" around to the right, just minus the left-scroll bit. Since it all wraps around, it doesn't matter. Or to go back to the clock example: If it's 4 o'clock and we rewind the clock by 7 hours, what time was it then? If we just do (4-7) % 12 we get -3 o'clock, which is not quite what we want. Instead we add 12 to keep the hours positive: (-3 + 12) % 12  =  9 % 12  =  9 â€" it was 9 o'clock.)

jamesreg

#9
Ok to clarify as you asked the behavior I am wanting on the movement/mouse and such.

Basically in appearance I want it to appear there is a Target in the middle of the screen.
I want to be able to smoothly scroll around the screen.
I do not care if it is a cursor or a GUI as a target as long as I can still process mouse clicks on characters/objects in the room.
(So the idea you have of using a GUI, hiding the mouse, but centering it and still being able to process click sounds great but way to complicated for me to understand how to do. Most my game will be basic adventure game explore format which I can do but I really wanted to have this combat system in there which I admit is beyond my skills right now.)

What I will be doing in this scene is having Enemy ships (Characters or objects have not figured out which is best yet) Moving around randomly on the screen. You will hunt them down on the screen and when your target is on them you will fire your lasers/phasers with the left mouse click and fire torpedoes with the right mouse click. I will also have a hotkey that will change the cursor from target mode to scan mode where you will click and scan the object for additional information displayed. Most this you probably do not need to know but figured id explain the scene as much as possible so that if there is something I am wanting to do in the future your be seeing what I intend.


If I can get this working I already scripted arming the weapons, shields, torpedoes, Have code in there to take and give damage, drain weapons , repair them etc. It will be a nice little combat simulation thing if I get all this working.

---EDIT---
I removed the scripting to move the character around with the mouse.
I have restored a target GUI on the screen instead of the mouse being viable
Scene now scrolls smoothly.

Still need help with the centering the invisible mouse and that part

Snarky

#10
Quote from: jamesreg on Tue 05/02/2019 18:33:56
Ok to clarify as you asked the behavior I am wanting on the movement/mouse and such.

Basically in appearance I want it to appear there is a Target in the middle of the screen.
I want to be able to smoothly scroll around the screen.
I do not care if it is a cursor or a GUI as a target as long as I can still process mouse clicks on characters/objects in the room.

OK, that sounds like what I thought (most recently).

Quote from: jamesreg on Tue 05/02/2019 18:33:56
(So the idea you have of using a GUI, hiding the mouse, but centering it and still being able to process click sounds great but way to complicated for me to understand how to do.

Mmm, is it? You're literally like 90% of the way there.

QuoteWhat I will be doing in this scene is having Enemy ships (Characters or objects have not figured out which is best yet) Moving around randomly on the screen. You will hunt them down on the screen and when your target is on them you will fire your lasers/phasers with the left mouse click and fire torpedoes with the right mouse click. I will also have a hotkey that will change the cursor from target mode to scan mode where you will click and scan the object for additional information displayed. Most this you probably do not need to know but figured id explain the scene as much as possible so that if there is something I am wanting to do in the future your be seeing what I intend.

There could be complications here, particularly when it comes to the room wrapping around, but let's deal with that later on.

For now, try this room code:

Code: ags
// room script file

// Some handy variables
int centerX, centerY, wrapWidth, wrapHeight, viewportX, viewportY;

//BEFORE ROOM LOAD SCRIPTS
function room_Load()
{
  cEgo.Transparency=100; //Make Character invisible 
  Bridge_Battle=true;    //Put room in Battle mode starting

  // Just calculate some useful values:
  centerX = System.ViewportWidth/2;
  centerY = System.ViewportHeight/2;
  int wrapWidth = Room.Width - System.ViewportWidth;
  int wrapHeight = Room.Height - System.ViewportHeight;
}

// Moved all the stuff to do with the battle into its own function, to keep things tidy
void updateBattle()
{
  // TODO: Update ships and stuff

  mouse.Update(); // This makes sure we get the most up-to-date mouse coordinates
  // Calculate viewport scrolling
  int moveX = mouse.x - centerX;
  int moveY = mouse.y - centerY;

  // Move viewport, wrapping around
  viewportX = (viewportX + moveX + wrapWidth) % wrapWidth;
  viewportY = (viewportY + moveY + wrapWidth) % wrapWidth;
  SetViewPort(viewportX, viewportY);
}

//scripts that repeatedly fire
function room_RepExec()
{
  // Testing script to exit game 
  if (IsKeyPressed(eKeyEscape)) {
    QuitGame(0);
  }
  //End of Testing Script  
  
  // If Z key is pressed and mode is battle mode
  if (IsKeyPressed(eKeyZ) && Bridge_Battle==true) {

    Display("Navigation mode off."); // Display message that Scrolling mode is off
    mouse.Visible=true;     // Make mouse visible
    gGui2.Visible=false;     // Make target sight invisible
    Bridge_Battle=false;    // Turn Battle mode off and restore full screen mouse movement
    Mouse.Mode=eModePointer; // Turns mouse back into pointer mode
  }

  // If Z key is pressed and battle mode is off
  if (IsKeyPressed(eKeyZ) && Bridge_Battle==false) {
    Display("Navigation Mode on.");  //Display Message Scrolling mode is on
    Bridge_Battle=true; //Turn battle mode and scrolling back on

    viewportX = GetViewportX();
    viewportY = GetViewportY();

    // Turn off mouse and turn on target sight
    gGui2.Visible=true;
    mouse.Visible = false;
    // Center the (now invisible) mouse on the screen
    mouse.x = centerX;
    mouse.y = centerY;
  }

  if(Bridge_Battle)
    updateBattle();
}

jamesreg

#11
Failed to save room room1.crm; details below
room1.asc(107): Error (line 107): Variable 'wrapWidth' is already defined

Snarky

Oops, just delete the 'int' at the start of that line and next.

jamesreg

room1.asc(66): Error (line 66): variable 'Mouse::x' is read-only


Snarky

I didn't test the code (clearly), which means that there's going to be some trivial bugs like this. But they should be pretty easy to fix yourself, you know?

I mean, you see what the line is meant to do, right? And the error message is pretty clear about why it doesn't work. And you have, in this thread, examples of the correct way to do it (for example, check out line 66 in your last post with code). I have faith in you.

jamesreg

I tried changing it to:

Code: ags
mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2); 

like the code above

I also tried changing it to
Code: ags
mouse.SetPosition(240, 135);

with the middle based on the 480x270 Game Background size

and also
Code: ags
mouse.SetPosition(1500, 1500);

the scrolling background size middle

I get this line error
Code: ags
viewportX = (viewportX + moveX + wrapWidth) % wrapWidth;


with this message
interger divided by zero

The code I posted myself above earlier was just borrowed from another forum post message.
I read though it and understand what part of it does and stuff like that but am not a good
enough coder to really understand it all. I normally do not need stuff this complex.

Bare with me even my failed attempts is teaching me new commands and things I never played with before.



Crimson Wizard

#17
Quote from: jamesreg on Tue 05/02/2019 20:23:30
I get this line error
Code: ags
viewportX = (viewportX + moveX + wrapWidth) % wrapWidth;


with this message
interger divided by zero


I found few more mistakes in Snarky's code :)
Most important one, he declared wrapWidth and wrapHeight second time as local variables instead of assigning global ones.

In room_Load()
Code: ags

int wrapWidth = Room.Width - System.ViewportWidth;
int wrapHeight = Room.Height - System.ViewportHeight;

remove "int" in the beginning of both lines.

But of course if your room's size is equal to screen size the error will still occur (wrapWidth and Height will be zero).
So I suggest following change:
Code: ags

  // Move viewport, wrapping around
  if (wrapWidth > 0)
    viewportX = (viewportX + moveX + wrapWidth) % wrapWidth;
  if (wrapHeight > 0)
    viewportY = (viewportY + moveY + wrapHeight) % wrapHeight; // <------- notice I also replaced wrapWidth with wrapHeight here
  SetViewport(viewportX, viewportY);

Snarky

#18
Quote from: jamesreg on Tue 05/02/2019 20:23:30
Bare with me even my failed attempts is teaching me new commands and things I never played with before.

Yeah, sorry. It can be exasperating when it seems like people are just expecting to be hand-held through every single step instead of trying to figure things out themselves, but as long as you're making an effort we're good.

Well, the lines that didn't work were:

Code: ags
  mouse.x = centerX;
  mouse.y = centerY;


This doesn't work because, as the message says, mouse.x and mouse.y are read-only â€" you can't change them directly. However, we have the method mouse.SetPosition(). So the correct version is... ?

Spoiler
Code: ags
  mouse.SetPosition(centerX, centerY);
[close]

This is equivalent to your code:

Quote from: jamesreg on Tue 05/02/2019 20:23:30
I tried changing it to:

Code: ags
mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2); 

like the code above

... since centerX and centerY are set to precisely those values. (It's not really necessary to store the numbers as variables the way I did; I just think it makes things a little easier to follow. Arguably it would be better to have named them screenCenterX and screenCenterY or something like that to make it even clearer.) All your versions should avoid the crash, but only the first two will give the right behavior, and it's better to not hardcode the numbers directly.

Quote from: jamesreg on Tue 05/02/2019 20:23:30
I get this line error
Code: ags
viewportX = (viewportX + moveX + wrapWidth) % wrapWidth;


with this message
interger divided by zero

Hmm... that means wrapWidth is zero when the line is called. That should not happen, unless Room.Width == System.ViewportWidth. Are you setting Bridge_Battle to true anywhere else? If so, it could be that room_RepExec() runs before room_Load(), so wrapWidth hasn't been set yet. If that's the case, the simplest fix might be to change the declaration line (I think this will work â€" if not, you'll have to do them on separate lines):

Code: ags
// Some handy variables
int centerX, centerY, wrapWidth=1, wrapHeight=1, viewportX, viewportY;


Or alternatively make sure that Bridge_Battle is not true before you enter the room.

Quote from: Crimson Wizard on Tue 05/02/2019 21:29:13
I found few more mistakes in Snarky's code :)
Most important one, he declared wrapWidth and wrapHeight second time as local variables instead of assigning global ones.

Thanks, CW! We actually already covered that one, but the viewportY calculation correction is definitely needed. Well spotted. (My solution to "it will crash if the room width is same as the viewport width" is "don't do that", but yours certainly has merit too.)

Crimson Wizard

Quote from: Snarky on Tue 05/02/2019 21:36:26
Quote from: Crimson Wizard on Tue 05/02/2019 21:29:13
I found few more mistakes in Snarky's code :)
Most important one, he declared wrapWidth and wrapHeight second time as local variables instead of assigning global ones.

Thanks, CW! We actually already covered that one, but the viewportY calculation correction is definitely needed. Well spotted. (My solution to "it will crash if the room width is same as the viewport width" is "don't do that", but yours certainly has merit too.)

Oh right... but why these wrap values were 0 then? What's the size of the room and is room_Load() function is actually connected to room event?

SMF spam blocked by CleanTalk