I've created a SurfaceView and I've put an onTouchEvent on it, and the MotionEvent gets the whole screen, like this:
#Override
public boolean onTouchEvent (MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
if (!player.getPlaying()&& newGameCreated && reset) {
player.setPlaying(true);
player.fly(true);
lives = 3;
}
if (player.getPlaying()) {
if (!started) started = true;
reset = false;
player.fly(true);
}
return true;
}
if (event.getAction()==MotionEvent.ACTION_UP) {
player.fly(false);
return true;
}
// This is inside a class that extends SurfaceView
return super.onTouchEvent(event);
}
And I need to check touch on bitmap or not using x-y position of touch and do a different action if the condition is true, how can I do this on this onTouchEvent method?
You need to know coordinates of bitmap, his height and width. If you know all of it you can declare method:
public boolean clickedOnBitmap(final int x, final int y) {
return x > bitmap.x && x < bitmap.x + bitmap.width
&& y > bitmap.y && y< bitmap.y + bitmap.height;
}
Related
I am trying make a game such that when user click on shooter it changes its position and and shoots and if user click on shooted balls (or shoots as named in project) they disappear CODE HERE
Shooter.JAVA
public class shooter extends View {
//Consider all variables are declared
public shooter(int color, Context c) {
super(c);
paint = new Paint();
paint.setColor(color);
mContext = c;
}
public void move() {
//Moves Cannon On Click (CODE NOT SHOWN PURPOSELY)
invalidate();
}
public float getPosition()
{
return shootPoint;
}
public void draw(Canvas canvas)
{
super.draw(canvas);
// simply draws a rectangle (shooter)
cW=getWidth();
cH=getHeight();
center=new Point(cW/2,cH);
left=0; right=center.x; shootPoint=right/2;
canvas.drawRect(left,top,right,bottom,paint);
}
}
Another Java Class Named shoot.java is also there to make shoot balls when shootbutton is clicked
but I want that when user click on those balls(drawn on canvas ) they should reset
Main Game View Class
public class GameView extends FrameLayout implements View.OnClickListener {
//Consider all objects and variables are declared as used
public GameView(Context context, AttributeSet attrs) {
super(context,attrs);
//CONTAIN INITIALIZATION OF OBJECTS AS USED OF OTHER CLASSES
bullets = new ArrayList<shoot> ();
addView(cannon);
for (int i = 0; i < bullets.size(); i++ ) {
addView(bullets.get(i));
bullets.get(i).setOnClickListener(this);// an arrays of objects of shoot class
}
cannon.setOnClickListener(this);
level=3;level++;
}
#Override
public void onClick(View view) {
switch()// Here is the MAIN PROBLEM HOW SHOULD I DIFFERENTIATE THAT CANNON IS CLICKED OR //BULLETS LIKE USING VIEW.GETTAG()
{
case ----1:// WHAT CASE SSHOULD I WRITE
cannon.move();
break;
case ----2: // HERE ALSO
bullets.remove();
break;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawGameBoard(canvas);
try
{
Thread.sleep(5);
} catch (InterruptedException e) {
}
invalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
aliens.setBounds(0,0,width,height);
for (int i = 0; i < bullets.size(); i++ ) {
bullets.get(i).setBounds(0,0,width,height);
}
}
public void drawGameBoard(Canvas canvas) {
cannon.draw(canvas);
for ( int i = bullets.size() - 1; i >= 0; i--) {
if (bullets.get(i) != null) {
bullets.get(i).draw(canvas);
}
}
for (int i = explosions.size() - 1; i >= 0; i--) {
if (explosions.get(i) != null) {
if (!explosions.get(i).draw(canvas)) {
explosions.remove(i);
}
}
}
if (aliens != null) {
aliens.draw(canvas);
RectF guyRect = aliens.getRect();
for (int i = bullets.size() - 1; i >= 0; i--) {
if (RectF.intersects(guyRect, bullets.get(i).getRect())) {
explosions.add(new explosion(Color.RED,mContext, aliens.getX()-aliens.dst, aliens.getY()-aliens.dst));
aliens.reset();
bullets.remove(i);
break;
}
}
if (!aliens.move()) {
aliens = null;
}
}
}
// Whenever the user shoots a bullet, create a new bullet moving upwards
public void shootCannon() {
bullets.add(new shoot(Color.RED, mContext, cannon.getPosition(), (float) (height-100)));
}
}
I have showed the part of the code where I am having the problem that is the overridden function ONCLICK in GAMEVIEW.JAVA by comments like how to know what is clicked so todo their respected functions
please notify me if you didn't understand my question
If I understand the question correctly, you want to use one onClickListener function to handle the click events for both your cannon and your bullets.
Since both are different classes you may differentiate between them via '''instanceof'''.
That means your onClickListener would look something like this:
#Override
public void onClick(View view) {
if(view instanceof shooter) {
cannon.move();
}
else if(view instanceof shoot) {
bullets.remove();
}
}
I hope this helps you. If anything remains unclear I'll gladly response :)
If you want to know the coordinates of the touch which you can use to figure out, if an item is tapped,
consider using View.OnTouchListener instead of View.OnClickListener.
View.OnTouchListener has this function:
onTouch(View v, MotionEvent event)
How to use:
check if event is a tap: event.getAction() ==
MotionEvent.ACTION_DOWN
get the coordinates: event.getX() and event.getY()
And after that, replace cannon.setOnClickListener(this); with cannon.setOnTouchListener(this);
If there are any questions, do not hesitate to ask them!
I'd like to write a function that returns true if the mouse is over the canvass, and false if not.
My solution would basically look like this:
import java.awt.MouseInfo;
Point globalMouse;
boolean mouseOverCanvass() {
globalMouse = MouseInfo.getPointerInfo().getLocation();
boolean mouseInXRange = (canvass.X < globalMouse.X) && (globalMouse.X < canvass.X + width);
boolean mouseInYRange = (canvass.Y < globalMouse.Y) && (globalMouse.Y < canvass.Y + height);
if (mouseInXRange && mouseInYRange) {
return true;
} else {
return false;
}
}
The problem is that I can't find the canvass position. I found this solution to getting the location of the window, but this provides the coordinate including the top bar, whereas I'd like the location of the canvass within that window.
Override the mouseEntered() and mouseExited() methods provided by PApplet, using a boolean variable to keep track of the current mouse-over-canvas state:
boolean mouse_over = false;
#Override
public void mouseEntered() {
mouse_over = true;
}
#Override
public void mouseExited() {
mouse_over = false;
}
I am making an app that displays circles randomly on the screen. The circles are either red or green. The purpose of the app is so that when someone touches a green circle something good happens, like they get points added to their score. When a red circle is clicked something bad happens like a new activity is started and the page says you failed or something. Here is my code for this app. In this code i receive no errors, nothing in logcat, everything works just fine. The circles display randomly on the screen as well as the score which is by default 0. The problem i am having with this app is that when a red or a green circle is clicked nothing happens.
public DrawingView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
RectF rectf = new RectF(0, 0, 200, 0);
private static final int w = 100;
public static int lastColor = Color.BLACK;
private final Random random = new Random();
private final Paint paint = new Paint();
private final int radius = 230;
private final Handler handler = new Handler();
public static int redColor = Color.RED;
public static int greenColor = Color.GREEN;
int randomWidth = 0;
int randomHeight = 0;
public static int addPoints = 0;
private final Runnable updateCircle = new Runnable() {
#Override
public void run() {
lastColor = random.nextInt(2) == 1 ? redColor : greenColor;
paint.setColor(lastColor);
invalidate();
handler.postDelayed(this, 1000);
}
};
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
handler.post(updateCircle);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
handler.removeCallbacks(updateCircle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// your other stuff here
if(random == null){
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}else {
randomWidth =(int) (random.nextInt(Math.abs(getWidth()-radius/2)) + radius/2f);
randomHeight = (random.nextInt((int)Math.abs((getHeight()-radius/2 + radius/2f))));
}
canvas.drawCircle(randomWidth, randomHeight, radius, paint);
paint.setColor(Color.BLACK);
paint.setTextSize(150);
canvas.drawText("Score: " + addPoints, 120, 300, paint);
}
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true){
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
}else {
}
return true;
}
public boolean isInsideCircle(int x, int y){
if ((((x - randomWidth)*(x - randomWidth)) + ((y - randomHeight)*(y - randomHeight))) < ((radius)*(radius))){
return true;
}
return false;
}
}
Your view might not be implementing the View.OnTouchListener interface, hence it not calling the onTouch() method.
Your view is not being set a View.OnTouchListener via the view's View.setOnTouchListener(View.OnTouchListener) method.
Android Developer Reference - View.OnTouchListener
Either way it feels wrong to make a view implement this interface to listen to itself. Instead you may want to take a look at the View.onTouchEvent(MotionEvent event) method; perhaps it serves your purpose (or it should in this case). Listener interfaces are supposed to be implemented by external components. Say, for example, if you wanted to make your TextView listen every time a Button or ImageView is touched, you could extend TextView/Button and make them implement the Listener interface then pass it to you view as a parameter of its setOnTouchListener(View.OnTouchListener).
However, all views have a method called onTouchEvent(). This View.onTouchEvent() method should be used if you want to listen to events within the view itself, as it is by default called whenever the view is, well touched. Should you need a reference to the view itself with this approach, you call this since the view itself would be your current scope.
Android Developer Reference - View.onTouchEvent(MotionEvent event)
If you do it like this, all you would need to do in order to make your code work is change your onTouch() method to an override of onTouchEvent() like this: (Also added verification of touch action as suggested by Pooja and Tom so you don't take into account MOVE or UP events. Change DOWN for UP depending on when you want to trigger the event)
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true) {
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
this.getContext().startActivity(i);
} else {
addPoints++;
}
} else {
//Handle case not inside the circle
}
}
return true;
}
The onTouch method is meant to be used with OnTouchListener and would normally be defined outside your custom view class. For example:
this.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// touch handling code
return true;
}
});
In the case where you are looking for touch events inside your custom view, you should implement the onTouchEvent method. You may also want to check for either ACTION_UP or ACTION_DOWN or you will be processing multiple touch events.
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
if(isInsideCircle(x, y) == true) {
//Do your things here
if(redColor == lastColor){
Intent i = new Intent(v.getContext(), YouFailed.class);
v.getContext().startActivity(i);
} else {
addPoints++;
}
result = true;
}
}
return result;
}
See the following for more details:
Input Events
What's up everyone,
Thanks for your time.
I am making a Pong clone, and I want to restrict Box2D to two MouseJoints maximum; one MouseJoint maximum per paddle. The MouseJoints should be created only if one of the user's two touches lands within either of the two paddle's boundaries.
I am getting a weird result with my code. If my first touch lands within the left paddle and my second touch lands outside of either paddle, a second MouseJoint is created on the left paddle (see attached image).
Note: In addition to the two MouseJoints on the left paddle, there are two PrismaticJoints in the image; one attached to each paddle.
To no avail, I've tried all of the algorithms that I could think of or adapt from other people's code.
If a code solution example or link could be posted, I would be much obliged.
Here is my code:
public class MyScreen implements Screen, InputProcessor{
/*========some variables and methods omitted for clarity========*/
/*multiple mouse joint experiment*/
public MouseJoint mouseJoint[] = new MouseJoint[2];
Body hitBody[] = new Body[2];
Body tempBody;
public MyScreen(Pong game) {
this.game = game;
}
/*---------------------Screen interface methods--------------------------*/
//methods omitted for clarity
/*---------------------end Screen interface methods----------------------*/
/*---------------------InputProcessor interface methods------------------*/
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
testPoint.set(screenX, screenY, 0);
camera.unproject(testPoint);
// ask the world which bodies are within the given
// bounding box around the mouse pointer
hitBody[pointer] = null;
world.QueryAABB(callback, testPoint.x - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f);
hitBody[pointer] = tempBody;
// if we hit something we create a new mouse joint
// and attach it to the hit body.
if (hitBody[pointer] != null) {
MouseJointDef def = new MouseJointDef();
def.bodyA = groundBody;
def.bodyB = hitBody[pointer];
def.collideConnected = true;
def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y);
def.maxForce = 3000.0f * hitBody[pointer].getMass();
mouseJoint[pointer] = (MouseJoint)world.createJoint(def);
hitBody[pointer].setAwake(true);
} else {
}
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
if (mouseJoint[pointer] != null) {
world.destroyJoint(mouseJoint[pointer]);
mouseJoint[pointer] = null;
}
return false;
}
/**a temporary vector for delta target destination during touchDragged() method**/
Vector2 target = new Vector2();
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
if (mouseJoint[pointer] != null) {
camera.unproject(testPoint.set(screenX, screenY, 0));
mouseJoint[pointer].setTarget(target.set(testPoint.x, testPoint.y));
}
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
/*----------------end InputProcessor interface methods------------------*/
/*------------------------helper methods------------------------------------*/
/*android screen touch vector for a mouse joint*/
Vector3 testPoint = new Vector3(); //we instantiate this vector and the callback here so we don't irritate the GC
QueryCallback callback = new QueryCallback() {
#Override public boolean reportFixture (Fixture fixture) {
// if the hit fixture's body is the ground body
// we ignore it
if (fixture.getBody() == groundBody) return true;
if (fixture.testPoint(testPoint.x, testPoint.y)) {
tempBody = fixture.getBody();
return false;
} else
return true;
}
};
/*------------------------end helper methods-------------------------------*/
}
From what I can see the tempBody is never reset to null. What that means is that the first time you touch the pad it sets the tempBody to the touched paddle and then when you press outside the body the callback will not find a new body but not reset the testBody to null, so when you assign testBody to hitBody[pointer] it is setting it to the first paddle.
The way your touch down function should look like is:
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
testPoint.set(screenX, screenY, 0);
camera.unproject(testPoint);
// ask the world which bodies are within the given
// bounding box around the mouse pointer
hitBody[pointer] = null;
world.QueryAABB(callback, testPoint.x - 1.0f, testPoint.y - 1.0f, testPoint.x + 1.0f, testPoint.y + 1.0f);
hitBody[pointer] = tempBody;
// if we hit something we create a new mouse joint
// and attach it to the hit body.
if (hitBody[pointer] != null) {
MouseJointDef def = new MouseJointDef();
def.bodyA = groundBody;
def.bodyB = hitBody[pointer];
def.collideConnected = true;
def.target.set(hitBody[pointer].getPosition().x, hitBody[pointer].getPosition().y);
def.maxForce = 3000.0f * hitBody[pointer].getMass();
mouseJoint[pointer] = (MouseJoint)world.createJoint(def);
hitBody[pointer].setAwake(true);
} else {
}
tempBody = null;
return false;
}
This way the tempBody is always reset to null after use.
how to perform single touch on isActionMove() because when i move finger on sprites it takes multipal touch events and update scores twice thrice
mHardware[active] = new Sprite(pX, pY, java, this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionMove()) {
score++;
}
}
};
i cant use isActionDown because its a game like fruit ninja in which i need to move finger across screen
now problem is score is sometimes increasse by 2 sometimes by 3 because when i move finger on sprite application notices several short movements in place of one
you should use
private static boolean isFirstMove;
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionDown()) {
isFirstMove = true;
}
if (pSceneTouchEvent.isActionMove()) {
if(isFirstMove) {
score++;
isFirstMove = false;
}
}
if (pSceneTouchEvent.isActionUp()) {
isFirstMove = false;
}
});
If you found some what above answer correct for you then I have some suggestion in this.
You have to implement both scene and area touch event for your game scene.
SceneTouch event method contains two events isActionDown() and isActionUp() like in the following code.
public void onSceneTouchEvent(...){
if(pSceneTouchEvent.isActionDown()){
isFirstTouch=true;
return true;
} else if(pSceneTouchEvent.isActionUp()){
isFirstTouch=false;
return true;
}
return false;
}
Area Touch method contains only single event isActionMove() like in the following code.
public void onAreaTouch(...){
if(pSceneTouchEvent.isActionMove()){
if(isFirstMove) {
score++;
isFirstMove = false;
}
return true;
}
return false;
}
You have to follow above strategy because some time desire event not occur for your sprite so you don't get your desire result.
solution given by julien dumortier is working perfectly
static boolean isFirstMove=true;
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y) {
if (pSceneTouchEvent.isActionMove()) {
if(isFirstMove) {
score++;
isFirstMove = false;
}
}
});