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:
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 game2) 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
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:
int thisPositionX = mouse.x - System.ViewportWidth / 2;
int thisPositionY = mouse.y - System.ViewportHeight / 2;
SetViewport(GetViewportX() + (thisPositionX - lastPositionX), GetViewportY() + (thisPositionY - lastPositionY));
lastPositionX = thisPositionX;
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):
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;
}
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:int lastPositionX, lastPositionY;
function repeatedly_execute() {
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;
}
}
(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.