Estoy tratando de dibujar una bola en mi pantalla usando 3 clases. He leído un poco sobre esto y encontré un fragmento de código que funciona usando las 3 clases en una página, Playing with graphics in AndroidDraw de Android usando SurfaceView y Thread
He alterado el código para que tenga una bola que se mueve y cambia de dirección al golpear la pared como el imagen debajo de (esto está usando el código en el enlace).
Ahora me gusta separar las clases en 3 páginas diferentes para no hacer todo tan lleno de gente, todo está configurado de la misma manera.
Aquí están las 3 clases que tengo.
- BallActivity.java
- Ball.java
- BallThread.java
package com.brick.breaker;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class BallActivity extends Activity {
private Ball ball;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
ball = new Ball(this);
setContentView(ball);
}
@Override
protected void onPause() {
super.onPause();
setContentView(null);
ball = null;
finish();
}
}
package com.brick.breaker;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class Ball extends SurfaceView implements SurfaceHolder.Callback {
private BallThread ballThread = null;
private Bitmap bitmap;
private float x, y;
private float vx, vy;
public Ball(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
x = 50.0f;
y = 50.0f;
vx = 10.0f;
vy = 10.0f;
getHolder().addCallback(this);
ballThread = new BallThread(getHolder(), this);
}
protected void onDraw(Canvas canvas) {
update(canvas);
canvas.drawBitmap(bitmap, x, y, null);
}
public void update(Canvas canvas) {
checkCollisions(canvas);
x += vx;
y += vy;
}
public void checkCollisions(Canvas canvas) {
if(x - vx < 0) {
vx = Math.abs(vx);
} else if(x + vx > canvas.getWidth() - getBitmapWidth()) {
vx = -Math.abs(vx);
}
if(y - vy < 0) {
vy = Math.abs(vy);
} else if(y + vy > canvas.getHeight() - getBitmapHeight()) {
vy = -Math.abs(vy);
}
}
public int getBitmapWidth() {
if(bitmap != null) {
return bitmap.getWidth();
} else {
return 0;
}
}
public int getBitmapHeight() {
if(bitmap != null) {
return bitmap.getHeight();
} else {
return 0;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
ballThread.setRunnable(true);
ballThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
ballThread.setRunnable(false);
while(retry) {
try {
ballThread.join();
retry = false;
} catch(InterruptedException ie) {
//Try again and again and again
}
break;
}
ballThread = null;
}
}
package com.brick.breaker;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class BallThread extends Thread {
private SurfaceHolder sh;
private Ball ball;
private Canvas canvas;
private boolean run = false;
public BallThread(SurfaceHolder _holder,Ball _ball) {
sh = _holder;
ball = _ball;
}
public void setRunnable(boolean _run) {
run = _run;
}
public void run() {
while(run) {
canvas = null;
try {
canvas = sh.lockCanvas(null);
synchronized(sh) {
ball.onDraw(canvas);
}
} finally {
if(canvas != null) {
sh.unlockCanvasAndPost(canvas);
}
}
}
}
public Canvas getCanvas() {
if(canvas != null) {
return canvas;
} else {
return null;
}
}
}
Aquí es una imagen que muestra el resultado de estas clases.
He tratado de resolver esto, pero ya que soy bastante nuevo en el desarrollo de Android pensé que podía pedir ayuda.
¿Alguien sabe qué está causando que la bola se dibuje así? El código es prácticamente el mismo que el del enlace y he intentado experimentar para encontrar una solución, pero no tuve suerte.
Yepp que fija mi problema, en el método onDraw he añadido el lienzo línea. drawColor (Color.BLACK); antes de dibujar el balón para que la pantalla se llenara de negro, eliminando las películas no deseadas de bola verde. Thx mucho =) –
Por cierto, para una animación mucho más suave y más rápida, recomendaría usar OpenGL. el lienzo es solo para cosas simples, especialmente por ahora que la mayoría de los dispositivos todavía no tienen GPU ayudando con las cosas gráficas, ya que la mayoría todavía están en la versión Android "vieja" (pan de jengibre). –
excelente consejo =) Voy a perder el tiempo con el código anterior y luego crear un nuevo proyecto y hacer la misma lógica pero usando OpenGL. Thx para el consejo :) –