Reputation: 41
Hi guys:) I'm playing around trying to draw with my Mainthreat onto a canvas. Basicly my aim is to get a rectangle, and when I touch it it changes the color. In the onCreate Method I create the rectangle and call the quadr1.setColor Method to give it a fill. Then i start the threat. Now the draw Method should just recall the quadr1.draw method, and redraw the rectangle with the same color. When I touch quadr1 the threat calls now quadr1.setColor again, instead of quadr1.draw. This should give it a new color provided by my RandomColor class (Works fine).
The problem now: While the threat is running the canvas just disappears to show "whats behind" and reapears with the next action again. It looks like a torture method for epileptics. I read about double buffering, but cant find any solution myself. How can I get it to show the rectangle with its fill stable, and just changes when I touch it?
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback{
private MainThread thread;
private Canvas canvas;
private Random random;
private SurfaceHolder holder;
RandomColor randomColor = new RandomColor();
private boolean colorChangeTouchInput;
private Quadr quadr1;
public GamePanel(Context context){
super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
this.holder = holder;
thread = new MainThread(holder);
randomColor = new RandomColor();
setFocusable(true);
}
class MainThread extends Thread{
private boolean running;
private SurfaceHolder surfaceHolder;
public MainThread(SurfaceHolder surfaceHolder){
this.surfaceHolder = surfaceHolder;
}
@Override
public void run(){
while(running) {
canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
if(colorChangeTouchInput=false) {
draw(canvas);
} else {
quadr1.setColor(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(canvas!= null){
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
private void draw(Canvas canvas) {
quadr1.draw(canvas);
}
public void setRunning(boolean b) {
running = b;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
int counter =0;
while(retry && counter <1000) {
counter++;
try {
thread.setRunning(false);
thread.join();
retry=false;
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder){
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int windowWidth = size.x;
int windowHeight = size.y;
canvas = null;
canvas = holder.lockCanvas();
quadr1 = new Quadr(0,0,windowWidth/2,windowHeight / 2, randomColor.getRandomColorA(), randomColor.getRandomColorR(), randomColor.getRandomColorG(), randomColor.getRandomColorB());
quadr1.setColor(canvas);
holder.unlockCanvasAndPost(canvas);
thread.setRunning(true);
thread.start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
SurfaceHolder holderTouch = getHolder();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
if(event.getX()>quadr1.getLeft() && event.getX()<quadr1.getRight() && event.getY()>quadr1.getTop() && event.getY()<quadr1.getBot()){
colorChangeTouchInput = true;
}
}
return super.onTouchEvent(event);
}
public boolean isColorChangeTouchInput() {
return colorChangeTouchInput;
}
}
This is my quadr class: (Works fine, also the Random color class, testet it on several ways.)
public class Quadr extends GameObject {
int left;
int top;
int right;
int bot;
int colorA[];
int colorR[];
int colorG[];
int colorB[];
int colorFixed;
Paint paint = new Paint();
Rect rect = new Rect();
Random rnd = new Random();
public Quadr(int left, int top, int right, int bottom, int colorA[], int colorR[], int colorG[], int colorB[]) {
this.left=left;
this.top=top;
this.right=right;
this.bot=bottom;
this.colorA=colorA;
this.colorR=colorR;
this.colorG=colorG;
this.colorB=colorB;
rect.set(left, top, right, bottom);
}
public void setColor(Canvas canvas){
int num = rnd.nextInt(3);
colorFixed = num;
paint.setStyle(Paint.Style.FILL);
rnd.nextInt(256));
paint.setARGB(colorA[num], colorR[num], colorG[num], colorB[num]);
canvas.drawRect(rect, paint);
}
public void draw(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setARGB(colorA[colorFixed], colorR[colorFixed], colorG[colorFixed], colorB[colorFixed]);
canvas.drawRect(rect, paint);
}
public int getLeft() {
return left;
}
public int getTop() {
return top;
}
public int getRight() {
return right;
}
public int getBot() {
return bot;
}
}
Thanks a lot in advance for any help!!
Upvotes: 0
Views: 136
Reputation: 7772
As far as I can see, the problem may be caused by colorChangeTouchInput
.
You are setting it as true
while intercepting the touch and, afterwards, you never set it to false
again. This will lead to the draw() method never being called in the thread. I suggest you add colorChangeTouchInput = false
after you call quadr1.setColor(canvas);
.
Upvotes: 1