Java – Android – create animated images of simulation type for mobile

I want to create a controller like simulator to move my character in the XML layout (which looks like Playstation or X@R_153_2419 @Similar on controller – circular simulation)

My first plan was to simply use the image view and place four transparent buttons on the image view to allow movement, but it was a bit boring and wanted to be really creative, but I was hard to find any type of document and wasn't sure where to start

Basically, what I'm looking for is an image that looks like a simulation (see below), and then the user can press and move the animation, which will trigger the relevant position movement Ideally, I would also like to have this, so that users can automatically animate by clicking on the right side of the simulation, and then trigger the correct action

I'm not sure if this is feasible. I want to implement it in my XML layout, or if it's easier, it can be created programmatically

Solution

See the last edit

----------------------------------------------

You must implement gesturedetector Ongesturelistener interface, and use ondown and onscroll methods to detect gestures, and then use the OnDraw (canvas C) method of the view to redraw the simulated bitmap (and convert it) after modifying its position (if you want to use matrix)

You can also use ontouchevent: onup event on gesturedetector in this answer

---------------------------------------------------------------------------------------

Edit this is an attempt, not a bitmap, but a drawcircle method:

It's not too complicated. I write it very fast, so it must be improved, but its working principle is very good:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class AnalogueView extends View {

    float x,y;
    double r,t;
    int cx,cy,w,h;
    final int RADIUS = 20;
    Paint black = new Paint();
    Paint grey = new Paint();
    Paint white = new Paint();

    private int toDo;

    public AnalogueView(Context context,AttributeSet attrs) {
        super(context,attrs);
        black.setColor(Color.BLACK);
        grey.setColor(Color.GRAY);
        white.setColor(Color.WHITE);
        black.setFlags(Paint.ANTI_ALIAS_FLAG);
        white.setFlags(Paint.ANTI_ALIAS_FLAG);
        grey.setFlags(Paint.ANTI_ALIAS_FLAG);
    }
    @Override
    protected void onSizeChanged(int w,int h,int oldw,int oldh) {
        this.w = w;
        this.h = h;
        cx = w/2;
        cy = h/2;
        x = cx;y=cy;
        super.onSizeChanged(w,h,oldw,oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawMyStuff(canvas);
        switch (toDo) {
        case 1:
            center();
            break;
        default:
            break;
        }

    }

    private void drawMyStuff(final Canvas canvas) {
        canvas.drawCircle(cx,w/2,black);
        canvas.drawCircle(cx,w/2-5,grey);
        canvas.drawCircle(cx,w/2-10,black);
        canvas.drawCircle(x,y,RADIUS+2,white);
        canvas.drawCircle(x,RADIUS,grey);
    }

//  n2p : normal to polar coordinates conversion
//  p2n : polar to normal coordinates conversion
//  R : distance to polar center 
//  T : polar angle
    double n2pR(double x,double y){
        return distance(x,cx,cy);
    }

    double n2pT(double x,double y){
        return Math.atan2((y-cy),(x-cx));
    }

    double p2nX(double r,double t){
        return r*Math.cos(t) + cx;
    }



    double p2nY(double r,double t){
        return r*Math.sin(t) + cy;
    }

    double n2pR(){
        return distance(x,cy);
    }

    double n2pT(){
        return Math.atan2((y-cy),(x-cx));
    }

    double p2nX(){
        return r*Math.cos(t) + cx;
    }

    double p2nY(){
        return r*Math.sin(t) + cy;
    }

    double distance(double x1,double y1,double x2,double y2 ){
        return Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN :
            updatePosition(event);
            break;

        case MotionEvent.ACTION_MOVE :
            updatePosition(event);
            break;

        case MotionEvent.ACTION_UP :
            toDo = 1; 
            center(); 
            break;
        default :break;

        }

        return true;
    }

    private void center(){
        if(r>15){
            r-=15;
        }else{
            toDo=0;
            r=0;
        }
        x = (float) p2nX();
        y= (float) p2nY();
        invalidate();
    }

    void updatePosition(MotionEvent e){
        r= Math.min(w/2-RADIUS,n2pR(e.getX(),e.getY()));
        t = n2pT(e.getX(),e.getY());
        x = (float) p2nX();
        y =(float) p2nY();

        invalidate();
    }
}

This is how to add it to the layout:

<yourpackage.AnalogueView
    android:id="@+id/analogueView1"
    android:layout_width="80px"
    android:layout_height="80px"
     />

In order to detect different simulated events, you can add a listener with the required method definition and use the interface in analogview. Then, when you want to implement the behavior of analogview, you just need to add an implementation for the interface by calling setter (it is similar to setonclicklistener of button) In this way, you will have a fully encapsulated analogview that you can reuse in any other application

-------------------------------------------------------------------------------

Last edit: use listener to handle events:

I embedded a listener using analogueview. Now you can use it like onclicklistener,

The setonmovelistener method is used to provide the implementation of two methods:

onMaxMoveInDirection(double polar_angle_of_direction) and 
onHalfMoveInDirection(double polar_angle_of_direction)

This is the new code of analogueview (there is no major modification, but the interface definition, movelistener field and trigger the action in updateposition):

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class AnalogueView extends View {

    OnMoveListener moveListener;


    float x,e.getY());
        x = (float) p2nX();
        y =(float) p2nY();


        if(moveListener != null)
            if(r == w/2-RADIUS)
                moveListener.onMaxMoveInDirection(t);
            else if(r >= w/4-RADIUS/2)
                moveListener.onHalfMoveInDirection(t);

        invalidate();
    }

    public void setOnMoveListener(OnMoveListener listener){
        moveListener =listener;
    }

    public interface OnMoveListener{
        public void onHalfMoveInDirection(double polarAngle);
        public void onMaxMoveInDirection(double polarAngle);
    }
}

Here is how to provide implementation:

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

import com.analog.AnalogueView.OnMoveListener;



public class MainActivity extends Activity {
    AnalogueView analogue;
    TextView showMoveEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        showMoveEvent = (TextView) findViewById(R.id.showMoveEvent);
        analogue = (AnalogueView) findViewById(R.id.analogueView1);
        analogue.setOnMoveListener(new OnMoveListener() {

            @Override
            public void onMaxMoveInDirection(double polarAngle) {
                showMoveEvent.setText("max move in "+polarAngle+" direction");
            }

            @Override
            public void onHalfMoveInDirection(double polarAngle) {
                showMoveEvent.setText("half move in "+polarAngle+" direction");

            }
        });
    }



}

Result: display the event in the text field:

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>