gpt4 book ai didi

java - 西蒙说安卓游戏

转载 作者:行者123 更新时间:2023-12-01 14:10:25 24 4
gpt4 key购买 nike

最近,我一直在尝试完成一款 Android 版西蒙说游戏,但事情变得比预期更困难。

现在游戏即将完成,引擎工作正常,游戏逻辑运行良好等等......当序列必须在显示器中单独显示以便玩家可以复制它时,问题就出现了。

声音工作正常,但是当必须完成序列时,在方法完成之前不会绘制任何内容。

重要的是,每个 Action 之间必须进行暂停,为此我尝试了很多方法,每个 Action 都得到相同的结果:

  • Thread.sleep(...);
  • SystemClock.sleep(...);
  • AsyncTask 只是做了一些 sleep ,然后升起一个标志...
  • View.invalidate();
  • View.postInvalidate();

等等...

使用 SystemClock.sleep(...) 可以获得最佳结果,屏幕不显示任何内容,但其他一切都正常。

还需要解释的是,我没有使用可绘制对象或 xml 文件来绘制按钮,而是在 Canvas 上使用 Path 和 Paint 绘制形状,所有这些都在 SurfaceView 内。

我在这里放置了我认为无法正常工作的方法,项目中还有一些代码,但它似乎正在工作并且没有搞乱任何东西。

这是 SurfaceView 类,其中包含我们正在做的事情中最重要的方法:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

//Elementos del thread
public MySurfaceThread thread;
public boolean touched;
public boolean reproduciendo;
public boolean juega;
public boolean despierta;
public boolean llamaPausa;


//Colores
public int mediumOrchid = 0xBA55D3;
public int crimson = 0xDC143C;
public int gold = 0xFFD700;
public int cornFlowerBlue = 0x6495ED;
public int limeGreen = 0x32CD32;

public int darkOrchid = 0x9932CC;
public int fireBrick = 0xB22222;
public int goldenRod = 0xDAA520;
public int midNightBlue = 0x191970;
public int mediumSeaGreen = 0x3CB371;

public int[]colores = {mediumOrchid, crimson, gold, cornFlowerBlue, limeGreen};
public int[]tocados = {darkOrchid, fireBrick, goldenRod, midNightBlue, mediumSeaGreen};


//Coordenadas de pulsación
PointF click;

public int indice = 0;
public int repId;


private int correctas;
private Vector<Integer> secuencia = new Vector<Integer>();
private Random aleatorio;


//Sonido
SoundPool mp;
int idBell1;
int idBell2;
int idBell3;
int idBell4;


Activity padre;


public MySurfaceView(Context context, SoundPool mpObj, Random rnd) {
super(context);
getHolder().addCallback(this);
aleatorio = rnd;

//Soundloop
mp = mpObj;
idBell1 = mp.load(context, R.raw.sy01, 1);
idBell2 = mp.load(context, R.raw.sy02, 1);
idBell3 = mp.load(context, R.raw.sy04, 1);
idBell4 = mp.load(context, R.raw.sy06, 1);


}



@Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new MySurfaceThread(getHolder(), this);
thread.setRun(true);
thread.start();
Log.e("surfaceCreated", "Creado");






}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

boolean retry = true;
//Detenemos el hilo
thread.setRun(false);
while (retry){
try{
thread.join();
retry = false;
}
catch (InterruptedException e){}
}

}


@Override
public void onDraw(Canvas canvas){
if(reproduciendo){Log.e("onDraw", "Entro a onDraw desde repsec");}
//Fondo negro
canvas.drawColor(Color.BLACK);

//Creamos el pinceles
Paint pincel = new Paint();
pincel.setAntiAlias(true);
pincel.setStyle(Paint.Style.FILL);

if (touched){//Activates when user is touching the screen
int id = quePieza(click, canvas);
//Log.e("onDraw", touched + " " + id);
if(id != -1) colores[id] = tocados[id];
}

if(reproduciendo){//Activates when sequence must be shown, just changes colours in the color array conveniently
Log.e("onDraw", "repId = " + repId);
if(repId != -1){colores[repId] = tocados[repId];}
repId = -1;
correctas++;
Log.e("onDraw", "Correctas = " + correctas);
}
//Pintamos las piezas
for(int i = 0; i < colores.length; i++){
pincel.setColor(Color.rgb(Color.red(colores[i]), Color.green(colores[i]), Color.blue(colores[i])));
pintarPiezas(i, canvas, pincel);//Paint each button according to an int code (0 to 4)
}

//Pintamos el texto
pincel.setColor(Color.WHITE);
dibujarTexto(canvas, pincel);

//Reestablecemos colores originales
resetColor();
//Log.e("onDraw", "He terminado de pintar");



}

这是负责在显示屏中显示序列的方法:

public void reproducirSecuencia(final Canvas canvas){
reproduciendo = true;
//TODO: HACER QUE ESTO FUNCIONE!!
Log.e("reproducirSecuencia", "Entro a reproducir");

int i = 0;

while(i < secuencia.size()){

Object o = secuencia.elementAt(i);
int num = 0;
if (o instanceof Integer) {num = (Integer) o;}


SystemClock.sleep(1000);
i++;
reproducirSonido(num);
repId = num;
onDraw(canvas);
i++;



//Log.e("reproducirSecuencia", "repId = " + repId);
//Log.e("reproducirSecuencia", "Invoco a pintarPiezas");





//SystemClock.sleep(1000);
//try {Thread.sleep(1000);}
//catch (InterruptedException e) {e.printStackTrace();}
}

reproduciendo = false;
}

最后,这是游戏线程中运行的主要方法:

public void Play(Canvas canvas){


/*if(juega){
int piezaTocada = quePieza(click, canvas);
reproducirSonido(piezaTocada);
juega = false;
}
onDraw(canvas);*/

onDraw(canvas);

if (secuencia.isEmpty()){//Creamos el primer movimiento
crearMovimiento();
reproducirSecuencia(canvas);
}
else{//Sigue el juego
if(juega){//Esperamos a que haya una jugada
int piezaTocada = quePieza(click, canvas);//Method to find which button was pressed
//¿Coincide con lo que buscamos?
if(piezaTocada != 0){//Que no se cuente el botón central en el modo classic
reproducirSonido(piezaTocada);
if(esCorrecto(piezaTocada, secuencia.elementAt(indice), canvas)){//Check if user's move was correct or not
//Aumentamos el indice
indice++;
juega = false;//Acabamos con la jugada
if(indice > secuencia.size() - 1){//Hemos hecho toda la secuencia, ponemos un nuevo elemento y reiniciamos
//SystemClock.sleep(3000);

indice = 0;
crearMovimiento();

int buc = 0;
reproducirSecuencia(canvas);
}

}
else{//No es correcto...
gameOver(canvas);
}
}
}
}
}

我还放入了我的 Thread 类,因为它在播放序列时似乎被阻止了:

public class MySurfaceThread extends Thread {

private SurfaceHolder surface;
private MySurfaceView view;
private boolean run;
public boolean pausa;


//Metodo constructor
public MySurfaceThread(SurfaceHolder sh, MySurfaceView v){
this.surface = sh;
this.view = v;
}



public synchronized void pausar() {
pausa = true;
}

public synchronized void reanudar() {
pausa = false;
notify();
}

public synchronized void detener() {
run = false;
if (pausa) reanudar();
}


public void setRun(boolean r){
this.run = r;
}



public void run(){





//...
//Creamos un canvas
Canvas canvas;
//Mientras run sea true pintamos
while (run){


canvas = null;
try {

canvas = surface.lockCanvas(null);
//Usamos syncro
synchronized (surface){

if(canvas != null){//Si el canvas existe pintamos
view.Play(canvas);

}
while (pausa) {
try {
wait();
}
catch (Exception e) {
}
}
}
}
finally {
if (canvas != null){
//Liberamos el canvas y el soundPool
surface.unlockCanvasAndPost(canvas);
}
}


}

}

}

就是这样,我希望得到尽可能清晰的答案,因为这是我的第一个应用程序,而且我已经有一年的编码时间和几个月的 Android 尝试。

非常感谢!

路易斯。

最佳答案

不不不。不要在主线程中 hibernate ,它会阻塞你的 UI - 这正是你所经历的。您应该播放一种声音,然后设置一个计时器。一旦定时器到期,播放下一个声音,设置另一个定时器等等。

设置计时器的一种简单方法是使用 Handler.sendMessageAtTime

关于java - 西蒙说安卓游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18560909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com