安卓自定义控件撞屏幕边缘按入射角反弹

来源:互联网 发布:javaweb项目 知乎 编辑:程序博客网 时间:2024/05/18 21:49

这个控件是通过SurfaceView每次重绘 并用 三角正切函数计算坐标位置  并记录控件运动轨迹方向 其中应该注意 个别方向的坐标计算  时间关系只做了 顺时针方向 逆时针时请参照更改

直接上源码 

public class MainActivity extends Activity implements Runnable, SurfaceHolder.Callback {    private SurfaceView sfv;    private SurfaceHolder holder;    private Thread thread;    private Paint paint;    private int screenWidth;    private int screenHeight;    private String myText = "adasd";    private Rect myBounds;     private int angle;    private float positionY = 30f; //控件高度     private float positionX = 0f;    private Status myStatus;    private float sX;//x反弹记录点    private float sY;//同上    private double tempTan;//保存正切值 提速计算    public enum Status {        LEFT_UP, UP, RIGHT_UP, RIGHT, RIGHT_DOWN, DOWN, LEFT_DOWN, LEFT    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        sfv = ((SurfaceView) findViewById(R.id.sfv));        holder = sfv.getHolder();        holder.addCallback(this);        thread = new Thread(this);        angle =30;        myStatus = RIGHT_DOWN;        myBounds = new Rect();    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        paint = new Paint();        paint.setColor(Color.RED);        paint.setTextSize(40);        paint.getTextBounds(myText, 0, myText.length(), myBounds);        thread.start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        screenWidth=width;        screenHeight=height;    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        thread.interrupt();    }    @Override    public void run() {        while (true) {            Canvas canvas = null;            try {                synchronized (holder) {                    canvas = holder.lockCanvas();                    canvas.drawColor(Color.WHITE);//                    if(myStatus== DOWN&&y==getResources().getDisplayMetrics().heightPixels-30){//                        canvas.drawText("asdasd",  x=(float)(y* (Math.tan(Math.PI/180*(90-10)))),y++, paint);//myStatus= UP;//                    }//else//                    {//                        canvas.drawText("asdasd",  x=(float)(y* (Math.tan(Math.PI/180*10))),y++, paint);//                    }                    switch (myStatus) {                        case RIGHT_DOWN:                            canvas.drawText(myText, positionX = sX+ (float) ((positionY-myBounds.height()) * (Math.tan(Math.PI / 180 * (angle)))), positionY++, paint);                            /*                            * 第一轨迹运动 xy轴增量成正比                            * */                            if (positionY >= screenHeight  ) {                                myStatus = RIGHT_UP;                                 sX = positionX;                                angle=90-angle;                            }                            if (positionX >= screenWidth - myBounds.width()) {                                myStatus = LEFT_DOWN;//撞墙转向                                sX=positionX;//记录位置                                sY=positionY;//同上                                angle=90-angle;//转角  可以换角计算 不做这一步                                tempTan=Math.tan(Math.PI / 180 * ( angle));//保存去正切值                            }                            break;                        case RIGHT_UP:                            canvas.drawText(myText, positionX =(float) (((sY-myBounds.height())*tempTan) -  ((positionY-myBounds.height()) * (tempTan))), positionY--, paint);//                            canvas.drawText(myText, positionX = 2* sX - timesX*(float) ((positionY-myBounds.height()) / (Math.tan(Math.PI / 180 * ( angle)))), positionY--, paint);                            if (positionX >= screenWidth - myBounds.width()) {                                myStatus = LEFT_UP;                            }                            if (positionY <= myBounds.height()) {                                myStatus = RIGHT_DOWN;                                sX=positionX;                            }                            break;                        case LEFT_DOWN:                            canvas.drawText(myText,positionX =  (float)((screenWidth-((screenHeight-sY)/tempTan))-myBounds.width()+((screenHeight-positionY)/tempTan)), positionY++, paint);                            if (positionX <= 0) {                                myStatus = RIGHT_DOWN;                            }                            if (positionY >= screenHeight ) {                                myStatus = LEFT_UP;                                sX=positionX;                                tempTan=Math.tan(Math.PI / 180 * (angle));                            }                            break;                        case LEFT_UP:                            canvas.drawText(myText, positionX =  (float) ((positionY-(screenHeight-(tempTan*sX)))/tempTan), positionY--, paint);                            if (positionY <= 0) {                                myStatus = LEFT_DOWN;                            }                            if (positionX <= 0) {                                myStatus = RIGHT_UP;                                sX = 0;                                sY=positionY;                                angle=90-angle;                                tempTan=(Math.tan(Math.PI / 180 * ( angle)));                            }                            break;                    }                    Thread.sleep(1);                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                if (canvas != null)                    holder.unlockCanvasAndPost(canvas);            }        }    }
}

原创粉丝点击