Android: How to make animation starting from the last position? - android

I have an ImageButton that should change its position depending on the accelerator angle. Unfourtunately, i don't get how to start animation from the last position... Please, help me to understand. I guess, the problem is with RELATIVE_TO_SELF, ABSOLUTE things. Now animation starts in the same place. Thank You in advance :)
public void animateButton (float newAngle) {
if (animation != null) {
if (!animation.hasEnded()) {
return;
}}
float goalX = 0f;
float goalY = 0f;
if (newAngle == 0) {
return;
}
if (newAngle < 0 ) {
newAngle = Math.abs(newAngle) + 270;
}
if ((newAngle > 0) || (newAngle <= 15)) {
goalX = 0f;
goalY = - 1f;
} else if ((newAngle > 15) || (newAngle <= 30)) {
goalX = - 0.5f;
goalY = - 0.5f;
} else if ((newAngle > 30) || (newAngle <= 90)) {
goalX = - 1f;
goalY = 0f;
} else if ((newAngle > 90) || (newAngle <= 180)) {
goalX = - 0.5f;
goalY = 0.5f;
} else if ((newAngle > 180) || (newAngle <= 195)) {
goalX = 0f;
goalY = 1f;
} else if ((newAngle > 195) || (newAngle <= 240)) {
goalX = 0.5f;
goalY = 0.5f;
} else if ((newAngle > 240) || (newAngle <= 300)) {
goalX = 1f;
goalY = 0f;
} else if ((newAngle > 300) || (newAngle < 360)) {
goalX = 0.5f;
goalY = - 0.5f;
}
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, goalX, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, goalY);
animation.setDuration(1000);
animation.setRepeatCount(1);
animation.setRepeatMode(1);
animation.setFillAfter(true);
ib.startAnimation(animation);
}

If setFillAfter(boolean filled) not works you can use a Property animations. They change layout parameters, so you can start animation after she ends from the last position.
Also look this video.

Related

How do I keep from leaving the screen?

I do not speak English well.
We apologize if you do not understand the question.
LinearLayout _Main_Contact_Layout;
FrameLayout _Main_Frame;
ImageView _Main_Background;
private List<string> _DrawerList_Item;
private ListView _DrawerList;
float _X, _Y;
float _XX, _YY;
int offset = 0, duration = 100;
float scaleX = 1.0f, scaleY = 1.0f;
float maxZoomLimit = 2.6f, minZoomLimit = 1.0f;
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
_X = e.GetX();
_Y = e.GetY();
float _Start_X = 760, _Start_Y = 160;
float _End_X = 1150, _End_Y = 490;
WindowManagerLayoutParams _Params = new WindowManagerLayoutParams();
_Params.X = (int)e.RawX;
_Params.Y = (int)e.RawY;
LayoutInflater inflater = (LayoutInflater)this.GetSystemService(Context.LayoutInflaterService);
View _Popup = inflater.Inflate(Resource.Layout.Custom_Popup, null);
PopupWindow _Window = new PopupWindow(_Popup, WindowManagerLayoutParams.WrapContent, WindowManagerLayoutParams.WrapContent);
_Window.SetBackgroundDrawable(new BitmapDrawable());
_Window.OutsideTouchable = true;
TextView _SetupX = (TextView)_Popup.FindViewById(Resource.Id.x_text);
TextView _SetupY = (TextView)_Popup.FindViewById(Resource.Id.y_text);
_SetupX.Text = "X 좌표 : " + _X.ToString("#.##");
_SetupY.Text = "Y 좌표 : " + _Y.ToString("#.##");
DrawerLayout _lstDrawer = (DrawerLayout)v.FindViewById(Resource.Id._DrawerLayout);
if(_Start_X > _X | _Start_Y > _Y | _End_X < _X | _End_Y < _Y )
{
_Window.Focusable = true;
_Window.ShowAsDropDown(_Popup, _Params.X, _Params.Y);
_Window.ShowAtLocation(_Popup, GravityFlags.Left | GravityFlags.Top, 0, 0);
_lstDrawer.CloseDrawer((int)GravityFlags.Left);
}
else if (_Start_X < _X & _Start_Y < _Y & _End_X > _X & _End_Y > _Y & !_lstDrawer.IsDrawerOpen((int)GravityFlags.Left))
{
_lstDrawer.OpenDrawer((int)GravityFlags.Left);
_Window.ShowAsDropDown(_Popup, _Params.X, _Params.Y);
_Window.ShowAtLocation(_Popup, GravityFlags.Left | GravityFlags.Top, 0, 0);
}
else if (_lstDrawer.IsDrawerOpen((int)GravityFlags.Left))
{
_lstDrawer.CloseDrawer((int)GravityFlags.Left);
}
break;
case MotionEventActions.Move:
_XX = e.GetX() - _X;
_YY = e.GetY() - _Y;
//_Main_Background.SetX(_Main_Background.GetX() + _XX);
//_Main_Background.SetY(_Main_Background.GetY() + _YY);
_X = e.GetX();
_Y = e.GetY();
if (scaleX > 1.0f && scaleY > 1.0f)
{
_MoveToX(_XX);
_MoveToY(_YY);
Console.WriteLine("_XX : " + _XX.ToString());
Console.WriteLine("_YY : " + _YY.ToString());
}
break;
}
return true;
}
private void _MoveToX(float xX)
{
float futureX = _Main_Background.GetX() + _XX;
if (futureX > 0 | futureX < 500)
{
_Main_Background.SetX(futureX);
}
}
private void _MoveToY(float yY)
{
float futureY = _Main_Background.GetY() + _YY;
if (futureY > 0 | futureY < 500)
{
_Main_Background.SetY(futureY);
}
}
private void _Zoom_In(View v)
{
if (scaleX < maxZoomLimit && scaleY < maxZoomLimit)
{
Animation animation = new ScaleAnimation(scaleX, (scaleX + 0.2f), scaleY, (scaleY + 0.2f), _X, _Y);
scaleX += 0.2f;
scaleY += 0.2f;
animation.Interpolator = new DecelerateInterpolator();
animation.Duration = duration;
animation.StartOffset = offset;
animation.FillAfter = true;
v.StartAnimation(animation);
}
}
private void _Zoom_Out(View v)
{
if (scaleX > minZoomLimit && scaleY > minZoomLimit)
{
Animation animation = new ScaleAnimation(scaleX, (scaleX - 0.2f), scaleY, (scaleY - 0.2f), _X, _Y);
scaleY -= 0.2f;
scaleX -= 0.2f;
animation.Interpolator = new DecelerateInterpolator();
animation.Duration = duration;
animation.StartOffset = offset;
animation.FillAfter = true;
v.StartAnimation(animation);
}
}
I am worried about this for about a week.
How do I keep from leaving the screen?
Adjusting the scale? How do I touch the scale?
Zoom in and Zoom out using the Button
-> resolution
Moving images with Zoom in using Button
-> resolution
If you move it after Zoom in, start with moving the image to a strange place.
-> resolution
Layout out of range
-> resolution
Move only within layout range (Unresolved)
Modify the if condition in your _MoveTo method. The x, y is the coordinate of the top left corner of your view. Calculate the width and height of the imageview, make sure the x and y value is smaller than 0 and not smaller than the value of screenwidth minus the imageview width.
For example:
private void _MoveToX(float xX)
{
float futureX = _Main_Background.GetX() + xX;
if (futureX <=0 && futureX >=YourScreenWidth -(_Main_Background.Width * scaleX))
{
_Main_Background.SetX(futureX);
Console.WriteLine("futureY : " + (_Main_Background.Height * scaleX).ToString());
Console.WriteLine("futureX : " + futureX.ToString());
}
}
private void _MoveToY(float yY)
{
float futureY = _Main_Background.GetY() + yY;
if (futureY <= 0 && futureY >=YourScreenHeight- (_Main_Background.Height * scaleY))
{
_Main_Background.SetY(futureY);
Console.WriteLine("futureY : " + (_Main_Background.Height * scaleY).ToString());
Console.WriteLine("futureY : " + futureY.ToString());
}
}

AndEngine sprites are locked when setting velocity after collision in onManagedUpdate method

I have to create a game in which there is one player sprite and several(approx 30) other sprites who moves randomly on the screen without colliding within themselves. I have problem in avoiding collision, since when detecting collision all the moving sprites are locked.
Below is my code..In my code I have created two classes one is MainActivity( This is the main class which extends BaseGameActivity and creates approx 30 AnimatedSprites using the NewSprite class and contains a static array list 'playerSprite' of NewSprite objects(approx 30 objects created randomly) and the second is NewSprite( which extends AnimatedSprite and overloads the method onManagedUpdate() to prevent these moving AnimatedSprites from going offscreen and collision between them.)
I have only shown NewSprite class..
public class NewSprite extends AnimatedSprite{
public PhysicsHandler physicsHandler;
Random randPos;
public NewSprite(final float pX, final float pY, final ITiledTextureRegio pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
randPos = new Random();
float x1;
float y1;
while((x1 = randPos.nextFloat()) < 0.8f);
while((y1 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x1 *= -1;
if(randPos.nextInt() % 2 == 0)
y1 *= -1;
physicsHandler = new PhysicsHandler(this);
this.registerUpdateHandler(physicsHandler);
physicsHandler.setVelocity(x1 * 100, y1 * 100);
}
#Override
protected void onManagedUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
if(this.mX < 0){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mY < 0){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mX > (MainActivity.CAMERA_WIDTH - MainActivity.MONSTER_WIDTH)){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
x2 *= -1;
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
else if(this.mY > (MainActivity.CAMERA_HEIGHT - MainActivity.MONSTER_HEIGHT)){
this.move++;
float x2,y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
y2 *= -1;
physicsHandler.setVelocity( x2*40, y2*40);
this.prevX = this.mX;
this.prevY = this.mY;
}
for(int i=0 ; i < MainActivity.playerSprite.size(); i++){
if(( MainActivity.playerSprite.get(i)).collidesWith(this) || this.collidesWith(MainActivity.playerSprite.get(i))){
float x2, y2;
while((x2 = randPos.nextFloat()) < 0.8f);
while((y2 = randPos.nextFloat()) < 0.8f);
if(randPos.nextInt() % 2 == 0)
x2 *= -1;
if(randPos.nextInt() % 2 == 0)
y2 *= -1;
this.physicsHandler.setVelocity( x2*100, y2*100);
break;
}
}
super.onManagedUpdate(pSecondsElapsed);
}
Did you tried to put your code after the super.onManagedUpdate(pSecondsElapsed); ?

rotate image on every touch event

In my application, I have some images and when I tap on that image, it should be rotated by 90 degree. I am able to rotate image once but can't rotate on second tap. Can anyone help me to solve this problem? How can I rotate image on every touch event?
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.quartercircle1);
Matrix m = new Matrix();
imgvwQrtr1.setScaleType(ScaleType.MATRIX);
m.setRotate(90f, imgvwQrtr1.getDrawable().getBounds().width()/2, imgvwQrtr1.getDrawable().getBounds().height()/2);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
imgvwQrtr1.setImageBitmap(bm);
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new DragShadowBuilder(v);
v.startDrag(data, shadowBuilder, v, 0);
return true;
}
you need to create global variable like:
int degree = 0;
and in the code
.....
//shortest way
degree = degree + 90;
if(degree % 360 == 0) {
degree = 0;
}
//if(degree >= 270) {
//degree = 0;
//} else {
//degree+=90;
//}
m.setRotate(degree, imgvwQrtr1.getDrawable().getBounds().width()/2,
imgvwQrtr1.getDrawable().getBounds().height()/2);
....
try this
public static float getRotationAngle(final float x1, final float y1, final float x2, final float y2) {
final float CLOCK_WISE = 1.0f;
final float ANTI_CLOCK_WISE = -1.0f;
final float deltaX = Math.abs(x2 - x1);
final float deltaY = Math.abs(y2 - y1);
if (deltaX == 0) {
return 0.0f;
}
final float angle = (float) Math.toDegrees(Math.atan(deltaY / deltaX));
if (x1 <= x2 && y2 <= y1) {
return CLOCK_WISE * (90.0f - angle);
} else if (x2 <= x1 && y2 <= y1) {
return ANTI_CLOCK_WISE * (90.0f - angle);
} else if (x2 <= x1 && y1 <= y2) {
return ANTI_CLOCK_WISE * (90.0f + angle);
} else if (x1 <= x2 && y1 <= y2) {
return CLOCK_WISE * (90.0f + angle);
} else {
return 0.0f;
}
}

Drawing Line Effect on Touch Like Fruit Ninja or Veggie Samurai in And Engine

I want to draw a line in AndEngine with the effect of a blade similar to Fruit Ninja or Veggie Samurai.
Can anyone help me? and give a sample code?
Maybe, I am late but hope this will help others.
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
final float touchX = pSceneTouchEvent.getX();
final float touchY = pSceneTouchEvent.getY();
if (pSceneTouchEvent.isActionDown()) {
initTrail(touchX, touchY);
swipeGestureSprite = addSwipeSprite(touchX, touchY);
} else if (pSceneTouchEvent.isActionMove()) {
moveTrail(pSceneTouchEvent.getX(), pSceneTouchEvent.getY(), 0);
if (swipeGestureSprite != null) {
swipeGestureSprite.setX(touchX);
swipeGestureSprite.setY(touchY);
}
} else if (pSceneTouchEvent.isActionUp()) {
mScene.detachChild(this.particleSystem);
if (swipeGestureSprite != null) {
this.mScene.detachChild(swipeGestureSprite);
swipeGestureSprite = null;
}
return true;
}
return false;
}
private void initTrail(float mX, float mY) {
this.particleEmitter = new PointParticleEmitter(mX, mY);
this.particleSystem = new SpriteParticleSystem(particleEmitter, 1000, 1000, 5000, this.mRibbon, this.getVertexBufferObjectManager());
particleSystem.addParticleInitializer(new BlendFunctionParticleInitializer<Sprite>(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE));
particleSystem.addParticleInitializer(new ExpireParticleInitializer<Sprite>(1));
particleSystem.addParticleModifier(new ScaleParticleModifier<Sprite>(0, 1, 1, 0f));
particleSystem.addParticleModifier(new AlphaParticleModifier<Sprite>(0, 1, 1, 0));
this.mScene.attachChild(particleSystem);
}
private void moveTrail(float trailX, float trailY, int count) {
if (particleEmitter == null) {
initTrail(trailX, trailY);
}
particleEmitter.setCenter(trailX, trailY);
}
I think you have to use point particle effect and use line drawing algorithm in that to create line between points. Line drawn using particle represent more reality and also the particle represent the dynamic way so you can destroy it. Further you can ask.
EDIT : For particle generation you can use this code
public void generateParticles(float pX, float pY) {
pointParticleEmtitter = new PointParticleEmitter(pX, pY);
particleSystem = new ParticleSystem(pointParticleEmtitter, maxRate,
minRate, maxParticles, mParticleTextureRegion.deepCopy());
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
particleSystem.addParticleInitializer(new ColorInitializer(0.8f, 0.43f,
0.2f));
particleSystem.addParticleModifier(new AlphaModifier(1, 0, 0, 0.25f));
particleSystem.addParticleModifier(new ExpireModifier(0.25f));
gameObject.getScene().attachChild(particleSystem);
}
For Line algorithm you can use this one
public void drawLine() {
int x;
float y, m;
x = (int) previousX;
y = (int) previousY;
m = (currentY - previousY) / (currentX - previousX);
if (Math.round(previousX) == Math.round(currentX)) {
if (previousY < currentY) {
for (y = (int) previousY; y < currentY; ++y)
pointParticleEmtitter.setCenter(previousX, y);
} else {
for (y = (int) previousY; y > currentY; --y)
pointParticleEmtitter.setCenter(previousX, y);
}
} else {
if (previousX < currentX) {
for (x = (int) previousX; x < currentX; ++x) {
y = m * (x - previousX) + previousY;
pointParticleEmtitter.setCenter(x, y);
}
} else if (previousX > currentX) {
for (x = (int) previousX; x > currentX; --x) {
y = m * (x - currentX) + currentY;
pointParticleEmtitter.setCenter(x, y);
}
}
}
}

How to limit image pan boundary in Android imageView

I have an imageView with multitouch roughly based on this tutorial. One of the commenters there put together a semi-dirty method of limiting the image drag to the boundaries of the image, so that the image edge cannot be dragged beyond its edge. This method sorta works, but not entirely. It only limits drag of two edges.
Does anyone know a less messy and actually functional method for limiting image drag?
This is a highly important concept for android app development that is not adequately addressed....
I was thinking of the following ideas:
1) setScaleType(scaleType.fitXY) when zoom = 1.0F (i.e. min zoom), and drag only enabled when zoom > 1.0f
2) when zoom > 1.0f, setScaleType(scaleType.MATRIX), then you determine image bounds and screen dimensions, and in some way that is too smart for me, using an if statement you only allow drag when the image edge is not on the screen. I don't know how to declare that, is the thing.
anyways, for completeness, here is the limit pan code from that link. This seems to be the most popular suggestion on stackoverflow, but I think we can do better:
// limit pan
matrix.getValues(matrixValues);
float currentY = matrixValues[Matrix.MTRANS_Y];
float currentX = matrixValues[Matrix.MTRANS_X];
float currentScale = matrixValues[Matrix.MSCALE_X];
float currentHeight = height * currentScale;
float currentWidth = width * currentScale;
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
float newX = currentX+dx;
float newY = currentY+dy;
RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
if(diffUp > 0 ){
dy +=diffUp;
}
if(diffDown < 0){
dy +=diffDown;
}
if( diffLeft> 0){
dx += diffLeft;
}
if(diffRight < 0){
dx += diffRight;
}
matrix.postTranslate(dx, dy);
private void limitDrag(Matrix m, ImageView view) {
float[] values = new float[9];
m.getValues(values);
float transX = values[Matrix.MTRANS_X];
float transY = values[Matrix.MTRANS_Y];
float scaleX = values[Matrix.MSCALE_X];
float scaleY = values[Matrix.MSCALE_Y];
Rect bounds = view.getDrawable().getBounds();
int viewWidth = getResources().getDisplayMetrics().widthPixels;
int viewHeight = getResources().getDisplayMetrics().heightPixels;
if(viewHeight<=480)
{
_y_up=0;
}
if(viewHeight>480&&viewHeight<980)
{
_y_up=140;
}
int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;
int __width=width;
int __height=height;
width = viewWidth / 2;
height = viewHeight / 2;
//height = 200 ;
float minX = (-width) ;//* scaleX;
float minY = (-height) ;//* scaleY;
if ((transX) > (viewWidth)) {
//_x_left
transX = viewWidth;
} else if (transX < minX) {
transX = minX;
}
if ((-transX) > (viewWidth)) {
// _x_right
transX = -(viewWidth);
} else if (-transX < minX) {
transX = -(minX+30);
}
if ((transY) > (viewHeight)) {
// _y_up
transY =( viewHeight);
} else if (transY < minY) {
transY = (minY+_y_up);
}
if ((-transY) > (viewHeight)) {
// _y_down
transY = -(viewHeight);
} else if (-transY < minY) {
transY = -(minY+170);
}
values[Matrix.MTRANS_X] = transX;
values[Matrix.MTRANS_Y] = transY;
m.setValues(values);
}
call this above your view.setImageMatrix(matrix) ;
I realize this is rather old now, but try this. imageWidth and imageHeight are unscaled values.
private void limitDrag(Matrix m, ImageView view, int imageWidth, int imageHeight) {
float[] values = new float[9];
m.getValues(values);
float[] orig = new float[] {0,0, imageWidth, imageHeight};
float[] trans = new float[4];
m.mapPoints(trans, orig);
float transLeft = trans[0];
float transTop = trans[1];
float transRight = trans[2];
float transBottom = trans[3];
float transWidth = transRight - transLeft;
float transHeight = transBottom - transTop;
float xOffset = 0;
if (transWidth > view.getWidth()) {
if (transLeft > 0) {
xOffset = -transLeft;
} else if (transRight < view.getWidth()) {
xOffset = view.getWidth() - transRight;
}
} else {
if (transLeft < 0) {
xOffset = -transLeft;
} else if (transRight > view.getWidth()) {
xOffset = -(transRight - view.getWidth());
}
}
float yOffset = 0;
if (transHeight > view.getHeight()) {
if (transTop > 0) {
yOffset = -transTop;
} else if (transBottom < view.getHeight()) {
yOffset = view.getHeight() - transBottom;
}
} else {
if (transTop < 0) {
yOffset = -transTop;
} else if (transBottom > view.getHeight()) {
yOffset = -(transBottom - view.getHeight());
}
}
float transX = values[Matrix.MTRANS_X];
float transY = values[Matrix.MTRANS_Y];
values[Matrix.MTRANS_X] = transX + xOffset;
values[Matrix.MTRANS_Y] = transY + yOffset;
m.setValues(values);
}

Categories

Resources