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

这个控件是通过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);
            }
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值