我似乎在游戏线程中调用循环时遇到了一些麻烦,但我不确定问题是什么。我称它为好,我不确定为什么它不会调用循环。这是一个带注释的代码块:
public class GameThread<MainGamePanel> extends Thread
{
private static final String TAG = GameThread.class.getSimpleName();
private GameView myGameView;
private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
private boolean running;
public void setRunning(boolean running) {
this.running = running;
System.out.println("tag: setRunning"); //successful
}
public GameThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel)
{
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
System.out.println("tag: GameThread"); //successful
}
public void run(Activity activity)
{
System.out.println("tag: run"); //failed
myGameView = new GameView(activity);
this.myGameView = new GameView(activity);
Canvas canvas;
long tickCount = 0L;
Log.d(TAG, "Starting game loop");
while (running) {
tickCount++;
canvas = null;
// update game state
myGameView.onUpdate();
// render state to the screen
try
{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder)
{
// update game state
// draws the canvas on the panel
if (canvas != null)
((GameView) this.gamePanel).onDraw(canvas);
}
}
finally
{
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null)
{
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
Log.d(TAG, "Game loop executed " + tickCount + " times");
}
}
您可以看到我的打印件失败的位置。
以下是调用它的视图的注释版本:
public class GameView extends SurfaceView implements SurfaceHolder.Callback
{
Paint paint = new Paint();
public static GameView myGameView;
static int screenWidth;
static int screenHeight;
protected void onDraw(Canvas canvas)
{
System.out.println("tag: onDraw"); //failed
}
public void onUpdate()
{
System.out.println("tag: onUpdate"); //failed
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
return true;
}
private GameThread thread;
public GameView(Context context)
{
super(context);
// adding the callback (this) to the surface holder to intercept events
getHolder().addCallback(this);
// Get Screen Dimensions
screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
thread = new GameThread(getHolder(), this);
// make the GamePanel focusable so it can handle events
setFocusable(true);
System.out.println("tag: GameView"); //Successful
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
thread.setRunning(true);
thread.start();
System.out.println("tag: surfaceCreated"); //successful
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
while (retry)
{
try
{
thread.join();
retry = false;
}
catch (InterruptedException e)
{
// try again shutting down the thread
}
}
System.out.println("tag: SurfaceDestroyed"); //Successful
}
}
后者中的两个失败方法都应该在线程中的循环内调用。我试图通过&#34; thread = new GameThread(getHolder(),this)调用我的线程;&#34;但是我不确定为什么那不起作用。
我还有This作为启动所有内容的设置类,但这似乎工作正常,因为视图被调用,它似乎不会像以下那样运行它应该在其内部。
非常感谢任何帮助,谢谢。
答案 0 :(得分:0)
您应该在此处移动代码:
myGameView = new GameView(activity);
this.myGameView = new GameView(activity);
Canvas canvas;
long tickCount = 0L;
构造函数,因为它是GameThread的一部分,而不是Thread
。使用Implements Runnable
而不是Extends Thread
也是首选,因为它允许在线程的行为与被调用和执行的实际线程之间进行明确分离。
但是对于您的特定问题,您正在扩展已经有一个run()方法的Thread,该方法在thread.start()
被调用,默认为空,因此您的run(Activity activity)实现永远不会被召唤。如果要覆盖超类的方法,则需要使用@Override指定:
@Override
public void run()
{
//etc etc
}
详细说明切换到implements Runnable
:
public class GameThread<MainGamePanel> Implements Runnable
{
private static final String TAG = GameThread.class.getSimpleName();
private GameView myGameView;
private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
private boolean running;
public void setRunning(boolean running) {
this.running = running;
System.out.println("tag: setRunning"); //successful
}
public GameThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel, Activity activity)
{
super();
//myGameView = new GameView(activity); <-- redundant
this.myGameView = new GameView(activity);
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
System.out.println("tag: GameThread"); //successful
}
public void run()
{
System.out.println("tag: run");
Canvas canvas = null;
long tickCount = 0L;
Log.d(TAG, "Starting game loop");
while (running) {
tickCount++;
// update game state
myGameView.onUpdate();
// render state to the screen
try
{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder)
{
// update game state
// draws the canvas on the panel
if (canvas != null)
((GameView) this.gamePanel).onDraw(canvas);
}
}
finally
{
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null)
{
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
Log.d(TAG, "Game loop executed " + tickCount + " times");
}
}
将您的通话方式更改为:
Runnable gameThread = new GameThread(params);
new Thread(gameThread).start(); //(.start() will begin your run() method in the thread)
(无法告诉你在哪里传递了你的活动,但你也需要考虑到这一点。)