您的位置:首页 > 其它

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

2017-08-04 11:03 155 查看






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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: