I want to rotate my object when I PRESS_DOWN button and stop rotating when I PRESS_UP.
I tried to do it with OnTouchListener but seems there is no way to kmow that button is still pressed. For example I touch button 1st time, and there is 1st touch event raised with ACTION_DOWN, but then if I keep my finger not moving nothing will happen (no more events). Or if I will move it very fast there will be different speed of raising on touch event ACTION_MOVE. Different speed that depends on finger's speed moves is unacceptable for my task. So I decided to start timer (that do rotating with fixed speed) when ACTION_DOWN raised and to cancel TimerTask when ACTION_UP is raised, it works good, just like I need. But I think it's not the best solution or even the worst. Please give me an advice of other possible solutions.
Your solution of using a timer is good, and is what you are supposed to you.
If you are running an animation, you cannot rely on UI events, you have to have a separate thread or timer for periodic updates.
Using timer is a good way. To my knowledge, I think using a simple if-else may solve your problem more efficiently. For example,
boolean state = true;
if(state)
{
// do the code for ACTION_DOWN
}
else
{
// do the code for ACTION_UP
state = true;
}
Give a loop to this if statement, as many times you want. But I don't know, whether this solution meets your requirements, or not.
Related
Right now, the object moves a certain increment each time I manually click a button, but its actually suppose to move on its own across the screen on its own once the button is clicked. I tried calling timer.start(); various times in my code. As well as, setting up an 'if' statement in the actionPerformed method that checks for a button being pressed and then calls timer.start() as a result. But, it didn't get the object to move on its own.
Can anyone lead me in the right direction? Am I not writing the code right? Or is does this problem have something to do with java swing timer.
PS. I am new to java,
And this is part of my code :
public void actionPerformed(ActionEvent e){
if (e.getSource() == rightBtn) {
objXpos += objMoveIncrement;
direction.equals("Right");
}
if (e.getSource() == leftBtn) {
direction.equals("Left");
objXpos -= objMoveIncrement;
}
repaint();
}
}
**edit
the timer is suppose to start once a button is clicked, and the timer is what allows the object to move across the screen
this problem have something to do with java swing timer.
No.
Am I not writing the code right?
That would be the problem.
the timer is suppose to start once a button is clicked
And how does the Timer stop? What happens if you click "right" and then "down"?
Without knowing the exact requirements it is hard to give an exact solution.
So I would suggest that one solution is to just start the Timer when your program starts.
Then in the ActionListener for each button, you change the direction.
Then when the ActionListner for the Timer is invoked, you simply move the object based on the current direction and then repaint the object.
Generally you would use Key Bindings for something like this. So when you press a key you start the Timer and when you release the key you stop the Timer. Check out the Motion With Key Bindings example from Motion Using the Keyboard for a working example of this approach.
I wrote a fade in fade out method for views. It works perfectly, but, as I understand, each view's animation is handled by a separate thread in the background, tackled by the android system.
That is a problem, because, I want to blink and the same pace.
Is it possible to do that? I tried to put my blinking method in a runnable and restart it every time a new View starts its animation, but it is not working because 1. you cannot simply restart a thread, 2. even if you can, the Animation will be handled by the system with different threads each running independently anyway.
How should I do this?
Let me narrate my goal again: I tap on a view, it starts blinking, fade in fade out style, using a method I wrote. Then I tap on another, both blinking at the same pace, with the first one perhaps noticeably changes its original blinking pace to be in sync with the 2nd one. Then I tap on another, another... no matter how many I enable blinking animation on, these views all fade in and fade out at the same pace.
Can you offer any advice? Either a specific one or a general one.
So I've recently been abusing Google for an answer, however just can't find one, and my head's starting to ache. I've recently released my second game on the Google Play Store, and only now have I been getting feedback that the people aren't too crazy about the button pressing mechanics (same mechanics as the first game). My game can be found here if you want to give it a go, unfortunately I don't have an HTML version hosted elsewhere.
Making the game, I used LibGDX, and for the UI, I've used Scene2D that comes with LibGDX. My game requires that you press the green "bug" button to get a point (the "bug" buttons cycle around at random), you are forced to play against a timer, so you would obviously want to go faster for a higher score (think Piano Tiles).
Now, to the problem at hand, one of the game modes in my new game is called "Zen", two buttons, one gives you 1 point, the other 2 points. The problem I'm experiencing is that if you hold both "bug" (bottom right and bottom left) buttons down, and release one of the buttons, the released one triggers a score increase, and the other button resets as if it was never pressed on in the first place (even if your finger is still on it). Here's the code for my Scene2D buttons (working off memory, don't have my code near me at the moment):
// All is initialized correctly, no crashes, here's the part about the listener.
leftBugButton.addListener(new ChangeListener()
{
#Override
public void changed(ChangeEvent event, Actor actor)
{
// Run code here when button has been released.
}
}
// And the right hand button's code. Initialization is perfect, no problems.
rightBugButton.addListener(new ChangeListener()
{
#Override
public void changed(ChangeEvent event, Actor actor)
{
// Run code here when button has been released.
}
}
Getting to my question, what I want to go for is that if a button press has been completed (pressing and then releasing), I don't want the other buttons to reset to an unpressed state.
Any tips, or perhaps a different Listener I should use, or even dumping Scene2D for these buttons (using sprites with InputListener for example)? Any help would be greatly appreciated.
Thanks in advance,
TV
Don't use ChangeListener for that, use a ClickListener (button.addClickListener(new ClickListener...)) and handle your process on touchUp event, ChangeListener gonna process if ANYTHING on the button change and it's not a good approach to handle a button release event.
Found my problem, I kept rebuilding the Stack after every button press, resulting in the odd behavior, opted instead for a .setStyle() on my buttons which is working a lot better.
Hi Everyone,
in the game I develop with AndEngine, there are a lot of sprites running around. Now every of this sprites has a TouchArea registered to the scene, because I display some informations about the sprite when it is touched. The Scene itself has a OnSceneTouchListener that I use for moving the camera around and to zoom.
My problem is, that every time the user moves the camera (by touching the display somewhere and moving his finger around) the OnAreaTouched() method of any sprite, that is accidentally under the finger, gets called, when the movement is finished (finger gets lifted). I already limited the triggering events to event.getAction()==UP (before it was a real mess of called touchAreas) but this is not enough. If the user is zooming or moving the camera, the sprites touchAreas should not be activated.
Is there any way I can distinguish between an OnAreaTouched-event and an OnSceneTouched-event? Which one is called first and can I suppress the other?
This is my OnSceneTouched() method (simplified):
public boolean onSceneTouchEvent(Scene scene, final TouchEvent event) {
boolean isZooming = event.getMotionEvent().getPointerCount() >= 2;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// REMEMBER FIRST TOUCHPOINT, TO KNOW IN WHICH DIRECTION TO MOVE
this.touchPoint = new Point(event.getMotionEvent().getX(), event.getMotionEvent().getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (isZooming) {
// DO SOME ZOOM STUFF
} else {
// DO SOME MOVEMENT STUFF
}
return true;
}
OK, actually this is not very interesting - but as you can see I always return true to signal that the touch event was handled. Still the OnAreaTouched() gets called
This is a typical OnAreaTouched() Method of a sprite:
public boolean onAreaTouched(final TouchEvent touchEvent, float touchAreaLocalX, float touchAreaLocalY) {
if (touchEvent.getAction() == TouchEvent.ACTION_UP) {
// DISPLAY INFORMATION ABOUT THE SPRITE
return true;
}
return false;
}
You see, there is nothing special to it. So I hope someone can help me out here to find a solution how to suppress the OnAreaTouch-event when the OnSceneTouch-event should be used. Maybe I can somehow catch the event.getAction()==UP in the OnSceneTouched()-Method??
I hope I could explain the problem good enough for you to understand (sorry, it's not that easy for me : ). Any help is much appreciated, and thank you for you time!
regards
Christoph
edit:
After experimenting with MahdeTo's suggestion to tag the event somehow I found out the following:
the TouchEvent that triggers the OnSceneTouchEvent() Method is not the same as the one triggering the OnAreaTouched() Method.
OnAreaTouched() gets called 20 ms later than OnSceneTouchEvent()
the event calling OnAreaTouched() starts actually when the user puts his finger down on the display (than he moves it around and the OnSceneTouchEvent() gets called multiple times), when he then lifts his finger the first event stops and gets handled. (I tried it out by measuring the time)
So I came up with the solution to measure how long a touch event lasted. If the event is longer than 200 ms, I guess the user wanted not to simply click but move or zoom (because these actions usually take longer). So now the OnAreaTouched() method gets only called when someone really meant to click and not accidentally swiped over the area.
but it's still not a good solution and I would really appreciate if anyone knows more about controlling such events.
thank you
I have recently written a fairly complicated application using touch controls - pressing buttons on the screen, pinch zooming, rotating and moving objects with two fingers and more. What I ended up doing was iteratively improving the application and adding rules controlling how to respond to different combinations of touch events. Whenever something was wrong, I recorded the sequence of TouchEvents and added rules so that the misbehaving action was handled.
You can also create boolean switches that prevent the onAreaTouched to execute, just add a condition that, for example if you want to touch an object, checks whether doNotTouchObject is true or false.
Another thing I found useful were touch mode switchers. I wrote several methods that completely change the behavior when user touches the screen. I believe you can switch them on the go, so it should be possible to call scene.setOnAreaTouchListener(touchListener) while you are touching the screen.
Since un/registering touch areas is blazing fast, simply unregistering certain touch areas while you perform some action is a possibility. After the action is completed, reregister them again.
I used a combination of all of the above and it works rather well, but it is essential to keep the code clean, otherwise debugging or implementing new features will be a pain.
maybe you can use the TouchDetector.
use the clickDetector instead of process TouchUp event, then only the detected click event is processed by the sprites;
use the scroll detector for the Scene Scrolling too;
enable the SceneTouchListenerBinding and TouchAreaBinding will also help you to by pass all the unintended in-progress events.
I'm experiencing some strange behaviour when using a stylus with swing.
I am interpreting pressing the button on the side of the stylus(RIGHT) and pressing the stylus down(LEFT) as a "Grab" event, but occasionally (more often than 0), events are just being dropped.
The JavaDocs for MouseEvent are pretty explicit about how multibutton presses are handled if executed one at a time (left down, right down, right up, left up) but say nothing about simultaneous button presses.
I'm left to wonder, would they be emitted as two mousePressed events, or as one with the button mask set for both buttons, or something else entirely?
Thanks.
I'd interpret the API doc as simultaneous button presses being simply not possible:
When multiple mouse buttons are pressed, each press, release, and click results in a separate event.
So there should be separate events. The problems you observe could be due to errors in your code, the stylus' driver, the hardware, or Swing (this is in decreasing order of likelihood as I see it :)
I'd try to diagnose the problem by logging events at different levels, if possible.
Simultaneous button presses are processed as two separate mousePressed events. Run the Mouse Events Demo to see them processed separately.
As I recall, there's no way to handle simultaneous button presses. What I used to do to ensure that multiple buttons being pressed at once were treated as such was I would have a boolean variable for each button and when it was pressed, I would set it to true and when it was released, I would set the boolean to false. Then when it came time to perform an action, I would check for the boolean variables (sometimes I would have the actionlistener redirect to the method call for determining what action was to happen next after setting the booleans). This doesn't work if the only thing you want to do is them being pressed at the exact same time, but if you're just trying to get combinations to work, then that's how I did it. This was about 4 years ago, before Java 5, so I may be wrong about that.