I'm creating a simple FPS game where the camera movement is controlled with the mouse. It's fairly simple to move the camera with the mouse when it's inside the window. But how can I make this work even when I'm OUT of the window?
I've heard some thing about fixing the mouse in the center of the screen, but I'm not sure how to get this to work.
I currently have the following:
public void mouseMoved(MouseEvent event) {
x = X;
y = Y;
X = event.getX();
Y = event.getY();
}
public void update() {
dX = X - x;
dY = Y - y;
x = X;
y = Y;
}
I've heard some thing about fixing the mouse in the center of the screen, but I'm not sure how to get this to work.
That is a very common way to do it. After you have checked how much your mouse has moved and used that information for camera movement, just move the cursor back to screen center.
Consider something like this:
Vec2 mouseDelta = getMousePosition();
camera.CalculateMovement(mouseDelta);
setMousePosition(0, 0);
You need to "capture" the mouse in your window, typically on the mouse down ( don't forget to release it ).
onMouseDown()
{
BeginCapture();
}
...
ReleaseCapture();
Related
I'm trying to zoom a grid in Processing and I am having trouble with applying the correct translation such that zooming is centered around the mouse position. I have searched the web for a while but nothing I try seems to work.
The screen size is width and height and the mouse position is mouseX and mouseY.
The code I have at the moment is below, but it zooms the grid (controlled by player.zoom) from the top left corner which is not what I want. To update the translation of the grid, player has the 2d vector player.translate.
void mouseWheel(MouseEvent event) {
float zoomFactor = 200.0f;
float scroll = event.getCount();
player.zoom -= scroll * player.zoom / zoomFactor;
// player.translate.x += something;
// player.translate.y += something;
}
If you need more details to answer I can link the repo with the source code.
I have created a very simple mock-up for you which will hopefully point you in the right direction into applying this to your player.
So this little demo shows the zooming in to the centre of an ellipse whilst keeping it as the central focus.
float scale = 1;
// displacement left/right
float xPan = 720;
// displacement up/down
float yPan = 450;
boolean zoomIn = true;
void setup() {
size(1440, 900);
}
void draw() {
// allows us to zoom into the center of the screen rather than the corner
translate(width/2, height/2);
scale(scale);
translate(-xPan, -yPan);
background(200);
// draws the ellipse in the center
ellipse(width/2, height/2, 100, 100);
// does the zooming
if (zoomIn) {
scale *= 1.01;
}
}
I suggest you to copy this into a new project and then comment out specific lines to try to understand what's going on and how you can transfer this over to your own project.
The same principles still apply, I didn't do this with mouse input in the effort of making the program as simple as possible.
I am making a pretty simple 2d game. I would like to have the character be able to hold a gun and it would aim where ever your cursor (or finger on iphone) is on the screen. I would also like the gun to be able to rotate depending on where your aiming to make the effect look better. It may be pretty difficult what I am exactly imaging of but heres an example of what I'm looking for http://www.kongregate.com/games/HotAirRaccoon/kids-vs-santa. I don't need any actual code, I would just need the logic to do this. Thanks for your time!
This is how you get the x and y coordinates of the mouse and you pass for movement. Different mouse events can be tracked using the logic of these coordinates:
public void mouseDragged(MouseEvent e) {
int dx = e.getX() - x;
int dy = e.getY() - y;
if (zrect.isHit(x, y)) {
zrect.addX(dx);
zrect.addY(dy);
repaint();
}
if (zell.isHit(x, y)) {
zell.addX(dx);
zell.addY(dy);
repaint();
}
x += dx;
y += dy;
}
}
I'm trying to create a simple Android game, a 2D action shooter which has 2 control sticks (circles) on the screen, the left one is movement control and the right one weapon control. Direction is being controlled by the position of your thumb relative to the circle’s center.
I've been following a tutorial on this site: http://www.kilobolt.com/day-7-creating-an-android-game-from-start-to-finish.html but it only gave me the base to work on. I have no programming experience so I'm quite lost now.
I got the movement working only on TOUCH_DOWN event, the hero moves to about where it should but to change direction I have to lift my thumb and touch the circle again. TOUCH_DRAGGED (or ACTION_MOVE) is broken because if I drag my finger across the circle the character moves really fast. I guess the problem is too many touch events are being handled, but I have no idea how to fix it.
How can I change this so that I can drag my thumb around the circle and the hero will change its direction instantly, and keep its speed constant all the time? Also the speed should be the same no matter how close or far from the center of the circle you touch.
private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN || event.type == TouchEvent.TOUCH_DRAGGED) {
if (inBounds(event, 50, 300, 150, 150, 'c')) {
ctrl.setX(event.x);
ctrl.setY(event.y);
ctrl.direction();
hero.move(ctrl.getDirX(), ctrl.getDirY());
}
}
if (event.type == TouchEvent.TOUCH_UP) {
if (inBounds(event, 0, 0, 35, 35,'r')) {
pause();
}
hero.stopMove();
}
}
hero.update();
The movement: hero's speedX and speedY are added to hero's centerX and centerY on every hero.update() call.
public void move(float x, float y) {
speedX += x * MOVESPEED;
speedY += y * MOVESPEED;
}
This method that handles the x & y speed. Found it here at stackoverflow, and because touch_down event is working ok, I guess it's doing it's job. Although I feel it's not exactly how it's supposed to be. L_STICK_C is a constant with values of 100 and 350 (center of the circle).
public void direction() {
dir.x = x - L_STICK_C.x;
dir.y = y - L_STICK_C.y;
double hyp = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
dir.x = (float) (dir.x / hyp);
dir.y = (float) (dir.y / hyp);
}
I suggest you look into some game programming tutorials. You usually would not move the character directly from the touch input. You'd set a game state variable once a game loop which would correspond to the position of your thumb inputs. Then you'd only update the hero once per game loop based on those inputs. This lets allows you to keep the game input control code, and hero code separate, and makes it re-usable for other parts of your game.
EDIT:
Based on your code, every time you drag your finger, you generate a bunch of dragged events. So you are adding onto your characters speed for each event. You should probably just be looking at the distance to center and x / y of the input on the last touch event, not all of them.
I m making desktop app in java swing. i made 3D image from my 2D image using PointArray[]. now i want to rotate image using MouseListener and MouseMotionListener.I used MouseRotate object to rotate myImage, but it not works well for that, MouseRotate rotate image with origin(0,0,0). but i want to rotate image using center point of image. means rotate image using center point not origin point. So, How can i do that?
Hmm, it's hard to tell without code, but I think you can just set up a transformation matrix and rotate it with that. Assuming the image is facing the front of the screen, you can try something like this:
public void mouseDragged(MouseEvent e)
{
int dx = e.getX() - x; //x should be a global variable
int dy = e.getY() - y; //same applies here
x = e.getX(); //to set x for the next update loop
y = e.getY();
double rotation = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
Transform3D transform = new Transform3D();
Matrix3d matrix = new Matrix3d();
transformG.getTransform(transform); //assuming the TransformGroup your image is in is transformG
transform.getRotationScale(matrix);
transform.rotZ(rotation);
transformG.setTransform(transform);
}
You can set up the rotation amount differently if you want, but this should give you an idea
I'm trying to rotate the camera around an object by using the touchscreen. The rotation around Y axis works fine (The X axis is disabled). Rotation around the X axis is really weird. when the Object (its a rocket) gets higher rocket.position().y++ & scene.camera().position.y++, the rotation around the x axis gets bigger and weird. If the rockets stops rocket.position().y = 500; & scene.camera().position.y = 500;, I can't rotate around x axis, I zoom in or out the object instead. With both axis enabled its weird as hell.
In initScene I set the camera to look at the center of the rocket.
Here's my code:
initScene:
scene.camera().position.z = 90;
scene.camera().target = raketeOBJ.position();
onTouchEvent:
public boolean onTouchEvent(MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}
if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}
if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;
xpos = me.getX();
ypos = me.getY();
touchTurn = xd / -200f;
touchTurnUp = yd / -200f;
return true;
}
try {
Thread.sleep(15);
} catch (Exception e) {
}
return super.onTouchEvent(me);
}
UpdateScene:
if (touchTurn != 0) {
scene.camera().position.rotateY(touchTurn);
touchTurn = 0;
}
if (touchTurnUp != 0) {
scene.camera().position.rotateX(touchTurnUp);
touchTurnUp = 0;
}
I think it is a view-orientation-issue. try basic android opengl example "rotating cubes", i think it is a similar behaviour.
To avoid this you have to transform display-coordinates into min3D object rotation-coordinates.
Think about moving your finger 1cm on display to the left, with 3D-object following your finger. This means x_display = x_object.
If you rotate your object, there is still a fixed connection between display and object.
(x_display = - 1cm) equals (x_object = -1cm)
at 90° & 270° your object will move xy-inverted, at 180° your object will move x-inverted.
use some sin/cos to overcome this.
edit: also rotationangle (object) = - rotationangle (camera)
One option is to rotate the container itself instead of the camera. In min3d you often work with an Object3dContainer as a class variable in your activity that displays the model. When you get your MotionEvent you can use the method rotation() from your Object3dContainer class and set x or y properties as appropriate.
You keep saying wierd, but you know that it doesn't describe what you see. Rotate is actually method of Number3d. It doesn't know about the target, so I guess rotation is done according the center, not according the rocket (Didn't quite check that, just a guess). There might be 2 solutions:
The easiest thing is to set the rocket to (0,0,0) and instead moving the rocket, move evertything else. Well that would be a stupid suggestion. Forget it.
The other solution is to calculate camera rotation traectory using sin() and cos()
There might be a third solution, but I didn't think a a lot about it and it might be wrong. What you have to do is move the camera like target is at (0,0,0), rotate and then return the camera.
Would look like something like this:
Number3d target = scene.camera.target;
Number3d cp = scene.camera.position.clone();
// move position like target is (0,0,0)
cp.x -= target.x;
cp.y -= target.y;
cp.z -= target.z;
cp.roateX(angle);
// restore offset
cp.x += target.x;
cp.y += target.y;
cp.z += target.z;
scene.camera.position.setAllFrom(cp);
You can try 3 but don't rely it'll do the job.