Author Topic: Camera following cursor?  (Read 875 times)  Share 

FrankT

  • The LP Treatment
Camera following cursor?
« on: 14 Aug 2012, 11:04 »
Would there happen to be some sort of code that makes the viewport follow the cursor, rather than the player character? As in, the screen scrolls to follow its position?

Andail

  • Global Moderator
  • Mittens Baronet
  • Cultured man of mystery
    • I can help with backgrounds
    •  
Re: Camera following cursor?
« Reply #1 on: 14 Aug 2012, 11:29 »
You can easily make one.
Under repeatedly execute you set the viewport to follow mouse.x and mouse.y. Easy as pie.
Or, if you're using the parallax module (which I believe disables viewport) you create a dummy character instead, and update its x and y position repeatedly.
Be vigilant, citizen!
Check out my GiP, The Samaritan Paradox
Also, check my blog at http://faravidinteractive.wordpress.com/

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Camera following cursor?
« Reply #2 on: 14 Aug 2012, 17:02 »
In case you're unsure about what the code has to look like exactly:

Code: Adventure Game Studio
  1.   SetViewport(mouse.x - System.ViewportWidth/2, mouse.y - System.ViewportHeight/2);

(You might have to include checks but I believe SetViewport ist robust when it comes to values outside the bounds.)
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

FrankT

  • The LP Treatment
Re: Camera following cursor?
« Reply #3 on: 14 Aug 2012, 23:36 »
Excellent! Thank you for the answers! ^^

FrankT

  • The LP Treatment
Re: Camera following cursor?
« Reply #4 on: 16 Oct 2012, 22:52 »
Hm... having a bit of trouble; I can't seem to scroll all the way to the right edge of my panel; how can I correct this?

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Camera following cursor?
« Reply #5 on: 16 Oct 2012, 23:13 »
Forget about the code I posted, it won't work.

The thing is, "the viewport follows the cursor" sounds pretty straightforward, but it actually isn't. Moving the mouse means that its position changes with regard to the room as well as the screen. Basically, when I move my mouse to the right, the viewpoint is also supposed to scroll to the right, but this system will only work if the mouse is moved back to the screen's center at the same time, so that its position in room coordinates doesn't change.
Since changing the mouse position, although possible, isn't recommend because a) the user might have to lift the mouse off of the table if the physical mouse can't be moved any further and b) the movement will get jittery due to the user interfering, direct movement of the viewport isn't going to work.

There are two ways I can think of:
1) The mouse position in relation to the screen's center determines viewport movement. So for instance if the mouse is at the right edge of the screen, the viewport will move quickly to right, and if it's just below the center, the viewport will scroll down slowly.
2) The mouse position is translated directly, i.e. mouse at 0,0 -> viewport is in top left corner; mouse at bottom right, viewport is all the way down and to the right.

Both of those are relatively easy to implement, I just don't have time right now to post some code.
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

Nefasto

  • Murphy's Ginea Pig
Re: Camera following cursor?
« Reply #6 on: 17 Oct 2012, 00:39 »
Another method from these steps :

1. Save mouse x and y position into variables. This will be the origin.
2. Save screen x,y position.
Begin Loop {
3. Check difference between the saved origin and the new mouse position (as it moves).
4. Increment the saved screen x,y with the resulting difference.
5a. Check if the x value is greater than the room width minus viewport width. If true, return the room width minus viewport width as screen x.
5b. Check if the y value is greater than the room height minus viewport height. If true, return the room height minus viewport height as screen y.
6a. Check if the x is less than 0. If true, return 0.
6b. Check if the y is less than 0. If true, return 0.
7. Set the screen position with the resulting x,y.
} End Loop

I don't have AGS on hand at the moment to code and test this, but this is the main idea. It has just one problems when the player clicks as the mouse is positionned practically at the borders of the screen.
« Last Edit: 17 Oct 2012, 00:43 by Nefasto »

Re: Camera following cursor?
« Reply #7 on: 17 Oct 2012, 02:57 »
Code: Adventure Game Studio
  1.   SetViewport(mouse.x - System.ViewportWidth/2, mouse.y - System.ViewportHeight/2);
Khris, I know you said the code won't work. But yeah, you're dead right. lol It wouldn't be able to move the viewport beyond the half of the system viewport width/height (assuming the viewport started 0,0). You forgot the Viewport x/y position, but even that is a pretty wacky camera.

Since changing the mouse position, although possible, isn't recommend because a) the user might have to lift the mouse off of the table if the physical mouse can't be moved any further and b) the movement will get jittery due to the user interfering, direct movement of the viewport isn't going to work.
Your A argument is what everyone needs to do while playing a first person 3D game while looking around. And I don't understand B. The camera being shaky because you're lifting your mouse and shifting it over?


FrankT, there are two types of screen movement you may be asking for (scrolling the viewport around a room larger than game resolution).
A) One where it follows the mouse like a first person shooter.
B) One where if your mouse moves in one direction and stops, the camera will constantly be moving around. Kind of like holding down on a joystick that controls the view (where it would keep spinning and spinning). To stop it you have to bring the cursor back to the center region of the screen. There's also just the edge boundaries like Starcraft where it will only move the viewport if you're near the edge.

I'm assuming you want the viewport to be centered on the cursor like an FPS game (unless the viewport is touching the edge of the room background).


This is what I would do, when you're in the mode where the center of the viewport is supposed to follow the cursor:

When this segment of gameplay starts, I would do three things:

1) In a windowed game I would set a cursor boundary of:
Code: Adventure Game Studio
  1. if (System.Windowed) mouse.SetBounds(0, 0, System.ViewportWidth - 1, System.ViewportHeight - 1);
This boundary prevents the cursor from leaving the window. ALWAYS remember to turn off this boundary whenever the menu is open, someone presses esc, or when the viewport isn't following the cursor anymore - that way you aren't angering any players because they can't leave the cursor from your game window without Alt-tabbing or quitting the game

2) I would then center the cursor in the center of the screen. You want the viewport to stay still until the mouse moves.

3) Turn off the cursor visiblity
Code: Adventure Game Studio
  1. mouse.Visible = false;
If you're going to have a cursor visible, you'll have to make a crosshair in the center of the screen with a GUI.

Next is the part where you move the viewport. It's pretty easy stuff:
Code: Adventure Game Studio
  1. int thisPositionX = mouse.x - System.ViewportWidth / 2;
  2. int thisPositionY = mouse.y - System.ViewportHeight / 2;
  3. SetViewport(GetViewportX() + (thisPositionX - lastPositionX), GetViewportY() + (thisPositionY - lastPositionY));
  4. lastPositionX = thisPositionX;
  5. lastPositionY = thisPositionY;

Lastly I would center the cursor to the center off the screen whenever it passes a certain boundary, like so (if this were a 320x240 game, I'd probably use a boundary like this):
Code: Adventure Game Studio
  1. if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
  2.   mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  3.   lastPositionX = 0;
  4.   lastPositionY = 0;
  5. }
You do NOT want to set the position of the mouse every gameloop. Since we do not have access to the float position of the cursor, the viewport would only move if the mouse actually moved 1 pixel from the center point between the last game loop. Which would mean the cursor would be stuck in the center if you're moving the mouse slowly. The player would have to quickly slide the mouse to have it move at all. So don't do that!


Basically the whole code:
Code: Adventure Game Studio
  1. int lastPositionX, lastPositionY;
  2.  
  3. function repeatedly_execute()  {
  4.   int thisPositionX = mouse.x - System.ViewportWidth / 2;
  5.   int thisPositionY = mouse.y - System.ViewportHeight / 2;
  6.   // of course - AGS crashes if you don't check if the viewport is being changed beyond the boundaries
  7.   int viewX = GetViewportX() + (thisPositionX - lastPositionX);
  8.   int viewY = GetViewportY() + (thisPositionY - lastPositionY);
  9.   if (viewX < 0) viewX = 0;
  10.   else if (viewX >= Room.Width - System.ViewportWidth) viewX = Room.Width - System.ViewportWidth;
  11.   if (viewY < 0) viewY = 0;
  12.   else if (viewY >= Room.Height - System.ViewportHeight) viewY = Room.Height - System.ViewportHeight;
  13.   SetViewport(viewX, viewY);
  14.   lastPositionX = thisPositionX;
  15.   lastPositionY = thisPositionY;
  16.  
  17.   if (mouse.x < 80 || mouse.x > 240 || mouse.y < 80 || mouse.y > 160) {
  18.     mouse.SetPosition(System.ViewportWidth / 2, System.ViewportHeight / 2);
  19.     lastPositionX = 0;
  20.     lastPositionY = 0;
  21.   }
  22. }
(I did not test anything)

Now there's numerous ways to do this. You didn't exactly give us much to work with on your question.
You could also add a smooth transition to where the cursor is actually pointing, instead of a crosshair design. But for this it requires a bit more work. You'd need a fake cursor by using a GUI. It's very possible, but it would be more like a drunken camera if you were moving the cursor around quite fast or doing zigzags. Of course the faster the cursor is moving, the faster the viewport should move, but it may look strange and delayed. I won't be posting code for this design.

Edit: I'm an idiot.. just a fixing a few copy/past issues.
« Last Edit: 17 Oct 2012, 03:20 by Ryan Timothy »

FrankT

  • The LP Treatment
Re: Camera following cursor?
« Reply #8 on: 17 Oct 2012, 12:23 »
I'm afraid you've all lost me there. :-\ Hm.. I think the edge boundary thing should work better. How's that work?

Re: Camera following cursor?
« Reply #9 on: 17 Oct 2012, 17:32 »
In what way are you lost? Have you even tried the code I provided at the bottom? Basically it's like the crosshair on an fps game, move the invisible cursor 10 pixels to the right, the viewport moves 10 pixels to the right. That's it. (assuming I didn't screw up on the code - I typed it all within the browser)

FrankT

  • The LP Treatment
Re: Camera following cursor?
« Reply #10 on: 17 Oct 2012, 18:34 »
In what way are you lost? Have you even tried the code I provided at the bottom?

Yes I did, but it wasn't the one my panel demands. Since the cursor always centres itself on the screen, I can't get it to reach any of the buttons. Can we have a look at the Starcraft style?

Stee

  • hatch?
    • I can help with play testing
    •  
    • I can help with proof reading
    •  
    • I can help with story design
    •  
    • I can help with web design
    •  
Re: Camera following cursor?
« Reply #11 on: 18 Oct 2012, 01:15 »
So you want an strategy style camera, where the map/background scrolls along when it reaches the end of the screen?
<ProgZMax> I got an idea - I reached in my pocket and pulled out my Galen. <timofonic2> Maybe I'm a bit gay, enough for do multitask and being romantical

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Camera following cursor?
« Reply #12 on: 18 Oct 2012, 13:16 »
Try this:
Code: Adventure Game Studio
  1. // in repeatedly_execute
  2.   int x = mouse.x, int y = mouse.y;
  3.   vw = System.ViewportWidth, vh = System.ViewportHeight;
  4.   vp_x_max = Room.Width - vw;
  5.   vp_y_max = Room.Height - vh;
  6.   x = (x*vp_x_max)/vw;
  7.   y = (y*vp_y_max)/vh;
  8.   SetViewport(x, y);
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

FrankT

  • The LP Treatment
Re: Camera following cursor?
« Reply #13 on: 18 Oct 2012, 19:35 »
It works! Thanks! You've saved my bacon this time!  :-D

Re: Camera following cursor?
« Reply #14 on: 01 May 2013, 12:23 »
Sorry for my scripting knowledge, i'm bad at that.
I tried to paste code in different places such as:
room script file
GlobalScript.ash
GlobalScript.asc

but everywhere i got this problem:
Expected integer valye after "="

looks like AGS somehaw cant undertand mouse.x and mouse.y values

Please help, thx

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Camera following cursor?
« Reply #15 on: 01 May 2013, 14:02 »
As is mentioned in the first line of the code, it needs to go inside the repeatedly_execute function.
If you want to use this in every room, open GlobalScript.asc, then find the function (you can use the dropdown menu at the top):
Code: Adventure Game Studio
  1. function repeatedly_execute()
  2. {
  3.   ...
  4. }

There's probably already stuff in there along with comments that explain where to put your own code.
Paste the code in there.

If you want to use this only in a certain room, add the room's repeatedly_execute event in the room editor, then open the room script and find the function called "room_RepExec()". Then paste the code in there.


(The reason why pasting the code outside a function didn't work is that AGS would have no idea when to call the code. AGS is event based, so every instruction (with a few exceptions) has to be inside a function. Basically, what you're supposed to do is tell AGS "when X happens, do Y". In what you tried, the "when X happens" part was missing.)
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"