我的画布上有一个对象需要根据用户输入进行旋转。当用户触摸屏幕,然后移动他们的手指时,应用程序会计算两个触摸事件之间的角度,这就是我需要我的Bitmap面对的角度。
这是一个带有测试位图的screenshot,我需要平面的鼻子面向输入确定的方向,然后随着输入的变化不断更新。
此GameView类在我的活动的ContentView中设置:
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
MainThread thread;
private Player player;
private Point playerPoint;
private float originX;
private float originY;
private float currX;
private float currY;
private float playerAngle;
public GameView(Context context){
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(),this);
setBackgroundColor(getResources().getColor(R.color.background));
setFocusable(true);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
@Override
public void surfaceCreated(SurfaceHolder holder) {
int width = this.getWidth();
int height = this.getHeight();
playerPoint = new Point(width/2, height*3/5);
player = new Player(this.getContext(), playerPoint,
getResources().getColor(R.color.colorAccent));
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
while(retry){
try{
thread.setRunning(false);
thread.join();
}catch(Exception e){
e.printStackTrace();
}
retry = false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN){
//System.out.println("Down");
originX = event.getX();
originY = event.getY();
}
currX = event.getX();
currY = event.getY();
//return super.onTouchEvent(event);
return true;
}
public float getTouchAngle(){
float dX = currX - originX;
float dY = currY - originY;
double angle = Math.atan2(dX,-dY);
angle *= 180;
angle /= Math.PI;
return (float) angle;
}
public void update(){
playerAngle = getTouchAngle();
//System.out.println(playerAngle);
player.update(playerAngle);
}
@Override
public void draw(Canvas canvas){
super.draw(canvas);
player.draw(canvas);
}
}
我有我的MainThread,它只调用GameView类的更新和绘制方法:
public class MainThread extends Thread {
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder holder;
private GameView gameView;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean b){
this.running = b;
}
public MainThread(SurfaceHolder holder, GameView gameView){
super();
this.holder = holder;
this.gameView = gameView;
//canvas = null;
}
@Override
public void run(){
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try{
canvas = this.holder.lockCanvas();
synchronized (holder){
this.gameView.update();
this.gameView.draw(canvas);
}
}catch(Exception e){
e.printStackTrace();
} finally {
if(canvas !=null){
try{
holder.unlockCanvasAndPost(canvas);
}catch(Exception e){
e.printStackTrace();
}
}
}
timeMillis = (System.nanoTime() - startTime/1000000);
waitTime = targetTime - timeMillis;
try{
if(waitTime > 0){
this.sleep(waitTime);
}
}catch(Exception e){
e.printStackTrace();
}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == MAX_FPS){
averageFPS = 1000 / ((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
//System.out.println(averageFPS);
}
}
}
}
然后我有了我的Player类,这是我一直试图让Bitmap旋转更新的地方:
public class Player implements GameObject {
//private Rect rect;
private int color;
private Paint paint;
private float angle;
private Bitmap icon;
private Point pos;
//private Matrix matrix;
public Player(Context context, Point pos, int color){
//this.rect = rect;
this.pos = pos;
this.color = color;
paint = new Paint();
//paint.setColor(color);
//paint.setStyle(Paint.Style.FILL);
paint.setFilterBitmap(true);
icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_action_name);
//matrix = new Matrix();
}
@Override
public void draw(Canvas canvas){
//Matrix matrix = new Matrix();
//matrix.setRotate(angle, 100, 100);
//canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.rotate(-angle,pos.x,pos.y);
System.out.println(angle);
canvas.drawBitmap(icon,pos.x-50,pos.y-50,paint);
//canvas.restore();
}
@Override
public void update(){
}
public void update(float angle){
this.angle = angle;
}
}
我最初尝试使用Matrix执行旋转,并且我最初使用它,但后来我做了更改,并且从那时起就无法完全旋转。
我可以判断角度是否正确计算,并且Player类中的角度变量正在更新,因为在触摸事件之后,如果我切换到另一个应用程序然后返回到此活动,则位图面临正确的方向。它不再是实时更新。我不知道我做了什么。
(所有注释的行都是我试图调整一些东西来修复它)
答案 0 :(得分:0)
我发现了这个问题。在多次更改我的代码以尝试让我的画布更新后,我尝试在我的setBackgroundColor()
课程中注释掉GameView
方法,然后突然又开始工作了。现在我只是在Canvas上设置背景颜色,它可以正常工作。如果有人能解释原因,我很乐意听到更多