I am trying to simulate tap and joystick movement on screen using AccessibilityService.
In addition i'm getting my input from gamepad controller device. doing tap is ok and done. my problem is simulating joystick movement on screen.
I don't know how can i do continuous touch with GestureDescription, because of time duration that this function requires.
i have used this code for tap:
public void virtual_touch(int posX, int posY)
{
Path path = new Path();
path.moveTo(posX, posY);
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path, 10, 10));
//gestureBuilder.build();
boolean isDispatched = dispatchGesture(gestureBuilder.build(), new AccessibilityService.GestureResultCallback()
{
#Override
public void onCompleted(GestureDescription gestureDescription)
{
super.onCompleted(gestureDescription);
MyUtils.Log("onCompleted");
}
#Override
public void onCancelled(GestureDescription gestureDescription)
{
super.onCancelled(gestureDescription);
MyUtils.Log("onCancelled");
}
}, null);
MyUtils.Log("virtual_touch isDispatched : " + isDispatched);
}
For Continue Stroke Use this method may be this will help to you.
willContinue --
continueStroke
public GestureDescription.StrokeDescription continueStroke (Path path,
long startTime,
long duration,
boolean willContinue)
boolean: true if this stroke will be continued by one in the next gesture false otherwise. Continued strokes keep their pointers down when the gesture completes.
Related
I've been trying to learn scene2d and I'm having trouble getting a sprite/Actor to move when a key is held down. I've tried a few different methods but I can't seem to figure it out. This is the code I currently have, which moves the actor everytime i press the key but not when it is held down.
class Player extends Actor {
Sprite sprite = new Sprite(new Texture (Gdx.files.internal("character.png")));
public Player() {
setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
setTouchable(Touchable.enabled);
addListener( new InputListener() {
#Override
public boolean keyDown(InputEvent event, int keycode) {
if (keycode == Input.Keys.RIGHT) {
MoveByAction mba = new MoveByAction();
mba.setAmount(1f, 0f);
Player.this.addAction(mba);
}
return true;
}
});
}
#Override
protected void positionChanged() {
sprite.setPosition(getX(), getY());
super.positionChanged();
}
#Override
public void draw(Batch batch, float parentAlpha) {
sprite.draw(batch);
}
#Override
public void act(float delta) {
super.act(delta);
}
}
You can use a state mechanism for doing that. This can be a simple enum like that :
public enum PlayerMoveState {
RIGHT,
LEFT,
IDLE
}
Define a field below to your sprite typed PlayerMoveState like this :
PlayerMoveState moveState;
Set it's state to proper one according to Input.Keys.RIGHT, Input.Keys.LEFT in your keyDown method. Reset the state by setting it to IDLE in keyUp method which you need to override and implement.
#Override
public boolean keyUp(InputEvent event, int keycode) {
moveState = PlayerMoveState.IDLE;
}
Finally, write a simple switch case block in act method of your player.
#Override
public void act(float delta) {
super.act(delta);
switch(moveState) {
case RIGHT :
// Move right by using whatever method you want.
// Directly increasing x
// Increase x according to velocity you have defined.
// Use actions, little bit dangerous.
break;
case LEFT :
// Move left by using whatever method you want.
break;
case IDLE :
// Don't change x coordinate of your player.
break;
default :
break;
}
}
I'm not really sure if actor has a focus on itself to handle KeyUp/Down events and that's why I would avoid using listeners to move player.
Also changing the actor's position does not need actions - there is a simple setPosition() method in Actor class. You have also getX() and getY() methods to get current position of actor.
What would i do would be to check if any Key is down (by using Gdx.input not lisetners) and set position modified by some defined step like:
//Actor class
final float STEP = 1f;
...
#Override
public void act(float delta) {
super.act(delta);
if(Gdx.input.isKeyPressed(Keys.W))
this.setPosition(getX(), getY() + STEP);
if(Gdx.input.isKeyPressed(Keys.S))
this.setPosition(getX(), getY() - STEP);
if(Gdx.input.isKeyPressed(Keys.A))
this.setPosition(getX() - STEP, getY());
if(Gdx.input.isKeyPressed(Keys.D))
this.setPosition(getX() + STEP, getY());
}
the act() method is called in every render (if you are calling stage's act of course) so the movement will be continuous.
I'm using AndEngine and Box2d in android application.
How can I have just one event, attached to the "Game Scene", from where I can find out what is pressed, instead of putting an event on every button in "GameHud" and how to detect the hold of the buttons?
public class GameScene extends Scene{
public GameScene(){
GameHud hud = new GameHud(this,activity);
camera.setHUD(hud);
}
//catch the touch event here
}
public class GameHud extends HUD{
public GameHud(Scene scene, GameActivity activity){
Sprite leftArrow = new Sprite(75,75,leftArrowRegion,activity.getVertexBufferObjectManager())
{
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
//...
return true;
}
};
scene.registerTouchArea(this.leftArrow);
Sprite rightArrow = new Sprite(200, 75, rightArrowRegion, activity.getVertexBufferObjectManager())
{
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
//...
return true;
}
};
scene.registerTouchArea(this.rightArrow);
}
}
You can listen for touch events in the Scene with this:
setOnSceneTouchListener(new IOnSceneTouchListener() {
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
// do something with the touch event
return true; // or false if not handled
}
});
However, doing it this way will require you to calculate which, if any, button was clicked based on the (x, y) coordinates of the touch event. If you feel that this is a better approach rather than registering events on each button you are more than welcome to do that, but you will be redoing a lot of the logic that is already embedded in the engine.
If it is the logic of the touch events that you want to share between buttons, you can have each registered event call the same method with an id or something to differentiate the buttons. That will allow you to centralize the action logic and not have to repeat it for each button being pressed.
If neither of these approaches are what you are looking for, feel free to leave a comment on what is missing and I'll do my best to help you achieve it.
I have a custom View that will manage hundreds of discrete user-defined sequential drawing events. Rather than maintaining a collection of all of the individual text, line, shape updates and then redrawing them all during each onDraw, I grab a Bitmap of the canvas at the end of each onDraw and then start the next onDraw with that Bitmap. A description of my problem follows this snippet:
public class TestView extends View implements OnTouchListener {
private Paint mPaint;
private Bitmap mPrevCanvas;
private int mTouchCount = 0;
float mX = 50f;
float mY = 50f;
public TestView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
this.setDrawingCacheEnabled(true);
mPaint = new Paint();
mPaint.setTextSize(30f);
}
#Override
protected void onDraw(Canvas canvas) {
if (mTouchCount == 0) {
canvas.drawText("Touch screen to begin", 50f, 100f, mPaint);
} else {
if (mPrevCanvas != null) {
canvas.drawBitmap(mPrevCanvas, 0, 0, mPaint);
}
canvas.drawText(Integer.toString(mTouchCount), mX, mY, mPaint);
mPrevCanvas = getDrawingCache().copy(Bitmap.Config.ARGB_8888, false);
}
}
public boolean onTouch(View arg0, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
mX = event.getX();
mY = event.getY();
mTouchCount += 1;
invalidate();
}
return true;
}
}
It seems to be working okay for the first touch event, but then mPrevCanvas never gets updated again. In reviewing the previous questions related to getDrawingCache(), only getDrawingCache is not updated seemed relevant, but based on that user's self-discovered answer, that apparently wasn't the same problem.
When running this custom view, touching the screen displays a "1" at the position you touch. It then captures a Bitmap of the canvas with that "1" in it. Subsequent touches redisplay that Bitmap stored in mPrevCanvas (showing the "1" again at the same position), and then the new number representing the current touch event (e.g., "2", "3", etc.) Since I'm refreshing mPrevCanvas at the end of each onDraw, I expect each onDraw to begin by displaying a Bitmap containing the results of all of the previous touch events... but for some reason the mPrevCanvas Bitmap is never updated to include that anything except that initial event ("1").
I've (a) verified that isDrawingCacheEnabled() is still true during each pass through onDraw; (b) tried throwing in destroyDrawingCache() and buildDrawingCache() to no avail; (c) forced mPrevCanvas to null before the call to getDrawingCache() to make sure it's really getting updated; and (d) searched through my copy of O'Reilly's Java in a Nutshell on the hunch that maybe I have a java headspace problem rather than an Android API problem.
Q1: Why will getDrawingCache() only return a Bitmap containing that first call to canvas.drawText, but never with the results of any of the subsequent drawText calls?
Q2: Given that I'm doing it this way for resource efficiency, should I be using some other design pattern anyway?
Even its too late to reply for this, I thought it could help somebody searching for this to correct answer.
same question here (with reply)
I want to execute a function only when the actor on my stage is touched..
But the problem is the function gets executed irrespective of where its touched on the stage..
Even if its touched in some random place on stage the function is executed..
I want the function to execute only when the actor is touched..I have setbounds...Still its not working..
public Restart()
{
atlas = new TextureAtlas(Gdx.files.internal("pages-info.atlas"));
sprite = atlas.createSprite("restart");
this.touchable = true;
sprite.setBounds(x, y, sprite.getWidth(), sprite.getHeight());
}
public void draw(SpriteBatch batch,float parentAlpha)
{
batch.draw(sprite, x, y , width, height );
}
#Override
public Actor hit(float x, float y)
{
// TODO Auto-generated method stub
Gdx.app.log( FirstGame.LOG, " restart working " );
return null;
}
The hit method is not doing what you think it does. The hit method is for testing if the current actor intersects the given x,y or not, so its always called. (Its useful if you want to throw away "hits" because your actor is not rectangular.)
Use addListener to add an event listener to receive touch events and react to them.
does anyone knows how to use the blackberry JDE API to create a screen slide animation similar to Featured Items screen in the Blackberry App World? I am aware that in blackberry 5.0, there are some transition apis to perform that. But I am looking to do it for version 4.6 OS. It has the nice scrolling effect using the scrolling ball in blackberry bold.
Thanks.
As an alternative to the screenshot/Bitmap approach...
In the paint method of your screen you can use Graphics.pushContext(..) to push a clipping region and drawing offset. For best results, you'll want to do the transition in a runnable, and synchronize on the event lock. This will ensure that your screen can be dismissed in the middle of a transition.
Rough example:
class TransitionScreen extends Screen {
private int transitionOffset;
private boolean isTransitionHorizontal;
private ScreenTransition currentTransition;
public TransitionScreen(boolean isTransitionHorizontal) {
this.isTransitionHorizontal = isTransitionHorizontal;
transitionOffset = getTransitionMaximum(); // So the screen starts offset
}
protected void paint(Graphics graphics) {
// use transitionOffset as x or y depending on isTransitionHorizontal
graphics.pushContext(...);
}
protected void onExposed() {
transitionToOffset(0);
}
protected void onObscured() {
int target = getTransitionMaximum();
transitionToOffset(target);
}
private int getTransitionMaximum() {
return isTransitionHorizontal ? Display.getWidth() : Display.getHeight();
}
private void transitionToOffset(int target) {
if (currentTransition != null) {
currentTransition.stop();
}
currentTransition = new ScreenTransition(target);
getApplication().invokeLater(currentTransition);
}
}
class ScreenTransition implements Runnable {
private boolean animating;
private int target;
public ScreenTransitionUpdater(int target) {
this.target = target;
}
public void stop() {
animating = false;
}
public void run() {
while(animating) {
Object eventLock = getApplication().getEventLock();
synchronized(eventLock) {
// Interpolate myOffset to target
// Set animating = false if myOffset = target
invalidate();
}
}
}
}
No need to mark animating as volatile as it is ignored on this platform.
Maybe use a timer to change the coordinate position of the images in the paint method