I am trying to simulate a mouse click when a mousepad in the app is pressed and not moved.
if(isConnected && out!=null){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//save X and Y positions when user touches the TextView
initX =event.getX();
initY =event.getY();
mouseMoved=false;
break;
case MotionEvent.ACTION_MOVE:
disX = event.getX()- initX; //Mouse movement in x direction
disY = event.getY()- initY; //Mouse movement in y direction
/*set init to new position so that continuous mouse movement
is captured*/
initX = event.getX();
initY = event.getY();
if(disX !=0|| disY !=0){
out.println(disX +","+ disY); //send mouse movement to server
}
mouseMoved=true;
break;
case MotionEvent.ACTION_UP:
//consider a tap only if usr did not move mouse after ACTION_DOWN
if(!mouseMoved){
out.println(Constants.MOUSE_LEFT_CLICK);
}
}
}
return true;
}
});
}
I have tried this, but I can't figure out why it won't work. Every time I click on the mousepad the mouse moves. How can I solve this?
try it with an if-else and put the pressing first and the moving in the else-case.
I solved my problem by setting a margin.
int max = 2
int min = -2
case MotionEvent.ACTION_UP:
//consider a tap only if usr did not move mouse after ACTION_DOWN
if(disX <= max && disX >= min && disY <= max && disY >= min){
out.println(Constants.MOUSE_LEFT_CLICK);
mouseMoved=false;
break;
}
}
}
return true;
}
Related
I am trying to implement a touch event on my simple 2d game. I am trying to do something similar to this quick diagram I made in paint.
For e.g, if the user presses on the 'TOP' portion of the screen, the object moves up. If they press right, the object moves right etc.
However, I can't seem to figure out the maths required to select the bottom and the right sections of the screen.
ScreenX and ScreenY variables are the screen size, for reference.
Could somebody check my code and see what I have done wrong?
Java code
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (event.getY() < screenY / 5)
tank.changeDirection('UP');
else if (event.getY() > screenY / 5)
tank.changeDirection('DOWN');
else if (event.getX() < screenX / 2)
tank.changeDirection('LEFT');
else if (event.getX() > screenX / 2)
tank.changeDirection('RIGHT');
break;
case MotionEvent.ACTION_UP:
tank.changeDirection(0);
break;
}
return true;
}
Probably the "down" condition should be
//else if (event.getY() > screenY / 5)
// tank.changeDirection('DOWN');
else if (event.getY() > screenY * 4 / 5)
tank.changeDirection('DOWN');
The following code I wrote does what I want, a touch on the left or right side of the screen to move the sprite left or right and stop at the edge of the phone screen. The issue I'm having is when you do a fast motion of touching the right side of the screen, letting go while using another finger to touch the left side of the screen to change direction will yield a result of the sprite still moving to the right side of the screen despite you wanting to move left. In order to fix this, you need to let go completely for at least 0.5sec then press the other direction to start moving in that direction, which I don't want to have to live with. If anyone has any tips/help for this, please let me know!
MAIN ACTIVITY CLASS METHOD:
public boolean onTouchEvent(MotionEvent event){
int x = (int)event.getX();
switch(event.getAction()) {
case (MotionEvent.ACTION_DOWN):
CharacterSprite.touchedX = x;
break;
case (MotionEvent.ACTION_UP):
CharacterSprite.touchedX = 0;
break;
}
return super.onTouchEvent(event);
}
CHARACTERSPRITE CLASS METHOD:
public void update() {
if (touchedX != 0) {
if (touchedX < screenWidth / 2) {
if (!(xVelocity < 0)) {
xVelocity = xVelocity * -1;
}
if (!(x > 0)) {
touchedX = 0;
return;
}
x += xVelocity;
}
if (touchedX > screenWidth / 2) {
if (!(xVelocity > 0)) {
xVelocity = xVelocity * -1;
}
if (!(x < screenWidth - image.getWidth())) {
touchedX = 0;
return;
}
x += xVelocity;
}
}
}
The way you handling MotionEvent will not work for multitouch events. Each finger (action pointer) data stored as an array and you need to handle each entry separately. Here is the lesson on handling multitouch events:
https://developer.android.com/training/gestures/multi
I'm trying to develop my own game. But I have an issue with the onTouchEvent-Method. Little explanation before showing my code. I want to be able to control a flight with my finger. It Should always follow my finger. For that I implemented the MotionEvent.ACTION_MOVE case. The flight only can move on the left side of the screen. When I touch on the right side of the screen, it should shoot a bullet. And it should be possible to fly around and shoot simultaneously. Here is my Code:
public boolean onTouchEvent(MotionEvent event) {
int maskedaction= event.getActionMasked();
switch (maskedaction) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getX() > screenX / 2 && flight.toShoot == 0) {
flight.toShoot++;
}
break;
case MotionEvent.ACTION_MOVE: {
if (event.getX() < screenX / 2 - 100) {
flight.x = (int) event.getX() - 100;
flight.y = (int) event.getY() - 50;
}
break;
}
}
return true;
}
So that's the code. When I touch the left half of the screen, I can fly around with the plane. When I Touch the right side, I can shoot. But I cannot do it at the same time. I want to touch first the left half and fly around. By clicking on the right side, at the same time as i'm moving my finger on the left side, it should shoot a bullet.
I found out that when I click at the same time on both sides with one finger, then the plane shoots one bullet. If i release now the right finger(the finger that shoots when it touches the screen) I can fly around and while I'm flying around I can shoot simultaneously.
You can detect your touch by detecting IDs, https://developer.android.com/training/gestures/multi
You can do something like this :
int leftSideId = 0;
int rightSideId = 1;
public boolean onTouchEvent(MotionEvent event) {
int maskedaction= event.getActionMasked();
// Get the pointer ID
int mActivePointerId = event.getPointerId(0);
switch (maskedaction) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getX() > screenX / 2) {
rightSideId = mActivePointerId;
if(flight.toShoot == 0){
flight.toShoot++;
}
}else{
leftSideId = mActivePointerId;
}
break;
case MotionEvent.ACTION_MOVE: {
if (event.getX() < screenX / 2 - 100) {
if (mActivePointerId == leftSideId) {
flight.x = (int) event.getX() - 100;
flight.y = (int) event.getY() - 50;
}
}
break;
}
}
return true;
}
So I found a solution by myself.
public boolean onTouchEvent(MotionEvent event){
int amount=event.getPointerCount();
for (int i=0; i<amount; i++) {
float x = event.getX(i);
float y = event.getY(i);
if (x>screenX/2 && flight.toShoot==0){
flight.toShoot++;
}
if (x<screenX/2 -100 && flyingenabled)
{
flight.x = (int) x - 100;
flight.y = (int) y - 50;
}
}
return true;
}
Thats working for my problem. Easier than I thought.
Client Code
new Thread()
{
public void run()
{
mousePad.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(isConnected && out!=null){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//save X and Y positions when user touches the TextView
initX =event.getX();
initY =event.getY();
mouseMoved=false;
break;
case MotionEvent.ACTION_MOVE:
disX = event.getX()- initX; //Mouse movement in x direction
disY = event.getY()- initY; //Mouse movement in y direction
/*set init to new position so that continuous mouse movement
is captured*/
initX = event.getX();
initY = event.getY();
if(disX !=0|| disY !=0){
try
{
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(disX +","+ disY); // to write contents to output stream
l.makeConnection(v);
bw.newLine();
bw.flush();
}
catch (IOException e)
{
Log.i(DebuggString,e.getMessage());
}
out.println(disX +","+ disY); //send mouse movement to server
}
mouseMoved=true;
break;
}
}
return true;
}
});
}
}.start();
here is server code
else if(data.contains(","))
{
float movex=Float.parseFloat(data.split(",")[0]);//extract movement in x direction
float movey=Float.parseFloat(data.split(",")[1]);//extract movement in y direction
Point point = MouseInfo.getPointerInfo().getLocation(); //Get current mouse position
float nowx=point.x;
float nowy=point.y;
robot.mouseMove((int)(nowx+movex),(int)(nowy+movey));//Move mouse pointer to new location
movex = 0;
movey = 0;
nowx = 0;
nowy = 0;
}
There is no error no logcat or anything that comes but the server gets jam and does not takes any further commands. please help me out its my final year project.
its has a tonnes and tonnes of cordinates.. when i try to go with the loop the innitial points get blocked and cursor doesnt moves from that position at all.. dont know what to do
I can get the coordinates of the touch just fine from:
event.getX();
event.getY();
But I want to start from an origin point of 0,0.
So I can touch anywhere on the screen, and as I drag my finger upwards, it will increase the Y by increments of 1, as I drag my finger to the right, the X will increase by increments of 1. Movement to the left will decrease the X by -1, movement downwards will decrease the Y by increments of -1.
Is there a mathematical way to do this, or better yet a class or function?
Any guidance would be appreciated! Thanks!
just use:
event.getRawX();
event.getRawY();
that results in screen coordinates,
starting at 0,0 (upper left corner)
to width,height (lower right corner)
depending on device, but i think thats not new to you ;)
--- update ---
I think I've missunderstood you, sorry..
then try this:
int saved_x = -1;
int saved_y = -1;
#Override
public boolean onTouchEvent(MotionEvent event)
{
final int action = event.getAction();
final int pointer_index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pid = event.getPointerId(pointer_index);
int x = (int)event.getX();
int y = (int)event.getY();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
saved_x = x;
saved_y = y;
break;
case MotionEvent.ACTION_MOVE:
int relative_x = x - saved_x;
int relative_y = y - saved_y;
//move right --> relative_x increases by 'm' pixels of movement
//move left --> relative_x decreases by 'm' pixels of movement
//move down --> relative_y increases by 'm' pixels of movement
//move up --> relative_y decreases by 'm' pixels of movement
//use it :D
break;
case MotionEvent.ACTION_UP:
saved_x = -1; //-1 indicates "no finger on screen" -- just a feature :)
saved_y = -1; //-1 indicates "no finger on screen" -- just a feature :)
break;
}
return true;
}
I hope this is now what you wanted :)