我不断将错误画到画布上 Error
当我尝试在用户移动操纵杆后向画布绘制画布时,错误仍然发生 它总是写我“无法锁定帆布,帆布已锁定”
我是游戏开发方面的初学者而且很抱歉,如果您需要更多详细信息,而且我会向您发送更多信息,那么问题有点不清楚
主要课程 - 主要活动
package app.shahardagan.Raven;
import android.graphics.Point;
import android.os.Bundle;
import android.app.Activity;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class Main extends Activity {
RelativeLayout layout_joystick;
ImageView image_joystick, image_border;
GameEngine gameEngine;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a Display object to access screen details
Display display = getWindowManager().getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
size.set(display.getWidth(),display.getHeight());
layout_joystick = (RelativeLayout)findViewById(R.id.layout_joystick);
gameEngine = new GameEngine(this,size.x,size.y);
setContentView(gameEngine);
}
@Override
protected void onResume(){
super.onResume();
gameEngine.resume();
}
@Override
protected void onPause(){
super.onPause();
gameEngine.pause();
}
}
GameEngine类 - 负责绘制玩家并更新游戏
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class GameEngine extends SurfaceView implements Runnable {
JoyStickClass js;
// This is our thread
private Thread gameThread = null;
// This is new. We need a SurfaceHolder
// When we use Paint and Canvas in a thread
// We will see it in action in the draw method soon.
private SurfaceHolder ourHolder;
// A boolean which we will set and unset
// when the game is running- or not.
private volatile boolean playing;
// Game is paused at the start
private boolean paused = true;
// A Canvas and a Paint object
private Canvas canvas;
private Paint paint;
// How wide and high is the screen?
private int screenX;
private int screenY;
// This variable tracks the game frame rate
private long fps;
// This is used to help calculate the fps
private long timeThisFrame;
private Context context;
private Player player;
private Drawable playerImage;
public GameEngine(Context context, int x, int y) {
// This calls the default constructor to setup the rest of the object
super(context);
this.context = context;
// Initialize ourHolder and paint objects
ourHolder = getHolder();
paint = new Paint();
// Initialize screenX and screenY because x and y are local
screenX = x;
screenY = y;
prepareLevel();
}
private void prepareLevel(){
player = new Player(context,screenX,screenY);
}
public void PlayerControls(Context context,RelativeLayout layout_joystick, ImageView image_joystick, ImageView image_border){
js = new JoyStickClass(context, layout_joystick, R.drawable.image_button);
js.setStickSize(150, 150);
js.setLayoutSize(500, 500);
js.setLayoutAlpha(150);
js.setStickAlpha(100);
js.setOffset(90);
js.setMinimumDistance(50);
layout_joystick.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
js.drawStick(arg1);
if(arg1.getAction() == MotionEvent.ACTION_DOWN || arg1.getAction() == MotionEvent.ACTION_MOVE) {
int direction = js.get8Direction();
if(direction == JoyStickClass.STICK_UP) {
} else if(direction == JoyStickClass.STICK_UPRIGHT) {
player.setMovementState(Player.UP);
} else if(direction == JoyStickClass.STICK_RIGHT) {
} else if(direction == JoyStickClass.STICK_DOWNRIGHT) {
} else if(direction == JoyStickClass.STICK_DOWN) {
} else if(direction == JoyStickClass.STICK_DOWNLEFT) {
} else if(direction == JoyStickClass.STICK_LEFT) {
} else if(direction == JoyStickClass.STICK_UPLEFT) {
} else if(direction == JoyStickClass.STICK_NONE) {
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
}
return true;
}
});
}
// Runs when the OS calls onPause on BreakoutActivity method
public void pause() {
playing = false;
try {
gameThread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
}
// Runs when the OS calls onResume on BreakoutActivity method
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
@Override
public void run() {
while (playing) {
// Capture the current time in milliseconds in startFrameTime
long startFrameTime = System.currentTimeMillis();
// Update the frame
// Update the frame
if(!paused){
update();
}
// Draw the frame
draw();
// Calculate the fps this frame
// We can then use the result to
// time animations and more.
timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
private void draw() {
// Make sure our drawing surface is valid or game will crash
if (ourHolder.getSurface().isValid()) {
// Lock the canvas ready to draw
canvas = ourHolder.lockCanvas();
// Draw the background color
canvas.drawColor(Color.argb(255, 26, 128, 182));
// Draw everything to the screen
// Choose the brush color for drawing
paint.setColor(Color.argb(255, 255, 255, 255));
canvas.drawBitmap(player.getBitmap(),player.getX(),screenY - player.getHeight(),paint);
}
}
private void update() {
player.update(fps);
}
}
玩家类 - 玩家类方法
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.RectF;
public class Player {
// RectF is an object that holds four coordinates - just what we need
private RectF rect;
private Bitmap bitmap;
// How long will our paddle will be
private float length;
private float height;
// X is the far left of the rectangle which forms our paddle
private float x;
private float y;
// Which ways can the player move
final int STOPPED = 0;
public static final int UP = 1;
public static final int UPRIGHT = 2;
public static final int RIGHT = 3;
public static final int DOWNRIGHT = 4;
public static final int DOWN = 5;
public static final int DOWNLEFT = 6;
public static final int LEFT = 7;
public static final int UPLEFT = 8;
// Is the paddle moving and in which direction
private int playerMoving = STOPPED;
private int playerSpeed;
public Player(Context context,int screenX, int screenY){
rect = new RectF();
length =screenX/10;
height = screenX/10;
x = screenX;
y= 0;
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.eagle_fly);
bitmap = Bitmap.createScaledBitmap(bitmap,(int)length,(int)height,false);
playerSpeed = 350;
}
public RectF getRect(){
return rect;
}
public Bitmap getBitmap(){
return bitmap;
}
public float getX(){ return x; }
public float getHeight(){return height;}
private float getLength(){return length;}
public void setMovementState(int state){
playerMoving = state;
}
void update(long fps){
if(playerMoving == LEFT){
x = x - playerSpeed / fps;
}
if(playerMoving == RIGHT){
x = x + playerSpeed / fps;
}
rect.top = y;
rect.bottom = y+ height;
rect.left = x;
rect.right = x + length;
}
}
欢乐棒课
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
public class JoyStickClass {
public static final int STICK_NONE = 0;
public static final int STICK_UP = 1;
public static final int STICK_UPRIGHT = 2;
public static final int STICK_RIGHT = 3;
public static final int STICK_DOWNRIGHT = 4;
public static final int STICK_DOWN = 5;
public static final int STICK_DOWNLEFT = 6;
public static final int STICK_LEFT = 7;
public static final int STICK_UPLEFT = 8;
private int STICK_ALPHA = 200;
private int LAYOUT_ALPHA = 200;
private int OFFSET = 0;
private Context mContext;
private ViewGroup mLayout;
private LayoutParams params;
private int stick_width, stick_height;
private int position_x = 0, position_y = 0, min_distance = 0;
private float distance = 0, angle = 0;
private DrawCanvas draw;
private Paint paint;
private Bitmap stick;
private boolean touch_state = false;
public JoyStickClass (Context context, ViewGroup layout, int stick_res_id) {
mContext = context;
stick = BitmapFactory.decodeResource(mContext.getResources(),
stick_res_id);
stick_width = stick.getWidth();
stick_height = stick.getHeight();
draw = new DrawCanvas(mContext);
paint = new Paint();
mLayout = layout;
params = mLayout.getLayoutParams();
}
public void drawStick(MotionEvent arg1) {
position_x = (int) (arg1.getX() - (params.width / 2));
position_y = (int) (arg1.getY() - (params.height / 2));
distance = (float) Math.sqrt(Math.pow(position_x, 2) + Math.pow(position_y, 2));
angle = (float) cal_angle(position_x, position_y);
if(arg1.getAction() == MotionEvent.ACTION_DOWN) {
if(distance <= (params.width / 2) - OFFSET) {
draw.position(arg1.getX(), arg1.getY());
draw();
touch_state = true;
}
} else if(arg1.getAction() == MotionEvent.ACTION_MOVE && touch_state) {
if(distance <= (params.width / 2) - OFFSET) {
draw.position(arg1.getX(), arg1.getY());
draw();
} else if(distance > (params.width / 2) - OFFSET){
float x = (float) (Math.cos(Math.toRadians(cal_angle(position_x, position_y))) * ((params.width / 2) - OFFSET));
float y = (float) (Math.sin(Math.toRadians(cal_angle(position_x, position_y))) * ((params.height / 2) - OFFSET));
x += (params.width / 2);
y += (params.height / 2);
draw.position(x, y);
draw();
} else {
mLayout.removeView(draw);
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
mLayout.removeView(draw);
touch_state = false;
}
}
public int[] getPosition() {
if(distance > min_distance && touch_state) {
return new int[] { position_x, position_y };
}
return new int[] { 0, 0 };
}
public int getX() {
if(distance > min_distance && touch_state) {
return position_x;
}
return 0;
}
public int getY() {
if(distance > min_distance && touch_state) {
return position_y;
}
return 0;
}
public float getAngle() {
if(distance > min_distance && touch_state) {
return angle;
}
return 0;
}
public float getDistance() {
if(distance > min_distance && touch_state) {
return distance;
}
return 0;
}
public void setMinimumDistance(int minDistance) {
min_distance = minDistance;
}
public int getMinimumDistance() {
return min_distance;
}
public int get8Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 247.5 && angle < 292.5 ) {
return STICK_UP;
} else if(angle >= 292.5 && angle < 337.5 ) {
return STICK_UPRIGHT;
} else if(angle >= 337.5 || angle < 22.5 ) {
return STICK_RIGHT;
} else if(angle >= 22.5 && angle < 67.5 ) {
return STICK_DOWNRIGHT;
} else if(angle >= 67.5 && angle < 112.5 ) {
return STICK_DOWN;
} else if(angle >= 112.5 && angle < 157.5 ) {
return STICK_DOWNLEFT;
} else if(angle >= 157.5 && angle < 202.5 ) {
return STICK_LEFT;
} else if(angle >= 202.5 && angle < 247.5 ) {
return STICK_UPLEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
public int get4Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 225 && angle < 315 ) {
return STICK_UP;
} else if(angle >= 315 || angle < 45 ) {
return STICK_RIGHT;
} else if(angle >= 45 && angle < 135 ) {
return STICK_DOWN;
} else if(angle >= 135 && angle < 225 ) {
return STICK_LEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
public void setOffset(int offset) {
OFFSET = offset;
}
public int getOffset() {
return OFFSET;
}
public void setStickAlpha(int alpha) {
STICK_ALPHA = alpha;
paint.setAlpha(alpha);
}
public int getStickAlpha() {
return STICK_ALPHA;
}
public void setLayoutAlpha(int alpha) {
LAYOUT_ALPHA = alpha;
mLayout.getBackground().setAlpha(alpha);
}
public int getLayoutAlpha() {
return LAYOUT_ALPHA;
}
public void setStickSize(int width, int height) {
stick = Bitmap.createScaledBitmap(stick, width, height, false);
stick_width = stick.getWidth();
stick_height = stick.getHeight();
}
public void setStickWidth(int width) {
stick = Bitmap.createScaledBitmap(stick, width, stick_height, false);
stick_width = stick.getWidth();
}
public void setStickHeight(int height) {
stick = Bitmap.createScaledBitmap(stick, stick_width, height, false);
stick_height = stick.getHeight();
}
public int getStickWidth() {
return stick_width;
}
public int getStickHeight() {
return stick_height;
}
public void setLayoutSize(int width, int height) {
params.width = width;
params.height = height;
}
public int getLayoutWidth() {
return params.width;
}
public int getLayoutHeight() {
return params.height;
}
private double cal_angle(float x, float y) {
if(x >= 0 && y >= 0)
return Math.toDegrees(Math.atan(y / x));
else if(x < 0 && y >= 0)
return Math.toDegrees(Math.atan(y / x)) + 180;
else if(x < 0 && y < 0)
return Math.toDegrees(Math.atan(y / x)) + 180;
else if(x >= 0 && y < 0)
return Math.toDegrees(Math.atan(y / x)) + 360;
return 0;
}
private void draw() {
try {
mLayout.removeView(draw);
} catch (Exception e) { }
mLayout.addView(draw);
}
private class DrawCanvas extends View{
float x, y;
private DrawCanvas(Context mContext) {
super(mContext);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(stick, x, y, paint);
}
private void position(float pos_x, float pos_y) {
x = pos_x - (stick_width / 2);
y = pos_y - (stick_height / 2);
}
}
}
答案 0 :(得分:0)
在draw()方法中,您将锁定Canvas,但在完成绘制后不会解锁Canvas。因此,当您重新进入draw方法时,Canvas仍然会锁定前一次调用。
完成绘图后,您可能需要添加unlockCanvasAndPost(Canvas canvas)
。请参阅完整文档here。