2017-10-20 98 views
0

我不断收到错误画到画布 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); 

} 
} 

Player类 - 播放器类的方法

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

在你的draw()方法中,你锁定了Canvas,bu完成绘图后,不要解锁画布。所以,当你重新输入你的绘画方法时,Canvas仍然被锁定在先前的调用中。

完成绘图后,您可能需要添加unlockCanvasAndPost(Canvas canvas)。请参阅完整文档here

+0

我已经试过了,我在lockCanvas之前写了这行,然后它也给了我一个错误 – user200544

+0

你试图在你的位图绘制调用后解锁它吗?另外,你可以发布你的堆栈跟踪吗? – Submersed

+0

在Joystick类中,我不使用SurfaceHolder,所以我不知道如何调用unlockCanvasAndPost方法。 – user200544