Android SurfaceView如何跳转Activity?贪吃蛇游戏结束跳转GameOverActivity问题
解决方案
方法1:直接使用Context跳转(简单快速)
原理是你创建SnakeGamePanel时传入的context就是SnakeGameActivity的实例,直接用这个context启动Activity即可,注意加防重复触发的标记:
步骤1:修改SnakeGamePanel添加成员变量
public class SnakeGamePanel extends AbstractGamePanel { // 新增成员变量 private Context mContext; private boolean isGameOverHandled = false; // 修改原有构造方法 public SnakeGamePanel(Context context) { super(context); this.mContext = context; } // 其他原有代码保持不变...
步骤2:重置游戏结束标记
在onStart方法(游戏重新开始时会调用)里重置标记,避免二次开局后无法触发结束逻辑:
@Override public void onStart() { this.snake = new SnakeActor(100, 100); this.apple = new AppleActor(200, 50); this.score = new ScoreBoard(this); // 新增:重置游戏结束处理标记 isGameOverHandled = false; }
步骤3:添加跳转逻辑
在redrawCanvas的游戏结束分支里添加跳转代码:
@Override public void redrawCanvas(Canvas canvas) { if (this.snake.isEnabled()) { this.snake.draw(canvas); this.apple.draw(canvas); this.score.draw(canvas); } else { Paint p = getPaint(); p.setTextSize(50); p.setColor(Color.BLACK); canvas.drawText("Game over!", 100, 100, p); // 新增跳转逻辑 if (!isGameOverHandled) { isGameOverHandled = true; // 切换到主线程执行跳转,避免绘制子线程调用报错 post(new Runnable() { @Override public void run() { Intent intent = new Intent(mContext, GameOverActivity.class); // 可选:传递得分数据到结束页 intent.putExtra("final_score", score.getPoints()); mContext.startActivity(intent); // 可选:如果不需要返回游戏页,可以关闭当前Activity // ((Activity)mContext).finish(); } }); } } }
方法2:接口回调(解耦更优)
如果不想让SurfaceView直接持有Activity引用,用接口回调把事件抛给上层Activity处理,后续修改逻辑更灵活:
步骤1:定义回调接口
public interface OnGameOverListener { void onGameOver(int finalScore); }
步骤2:修改SnakeGamePanel添加回调支持
public class SnakeGamePanel extends AbstractGamePanel { private OnGameOverListener mGameOverListener; private boolean isGameOverHandled = false; // 设置回调的方法 public void setOnGameOverListener(OnGameOverListener listener) { this.mGameOverListener = listener; } // onStart里同样要重置isGameOverHandled标记,和方法1一致 @Override public void onStart() { // 原有逻辑不变 isGameOverHandled = false; } // redrawCanvas里的游戏结束分支改为触发回调 @Override public void redrawCanvas(Canvas canvas) { if (this.snake.isEnabled()) { // 原有逻辑不变 } else { // 原有绘制Game over的逻辑不变 if (!isGameOverHandled && mGameOverListener != null) { isGameOverHandled = true; post(new Runnable() { @Override public void run() { mGameOverListener.onGameOver(score.getPoints()); } }); } } } }
步骤3:SnakeGameActivity实现回调处理跳转
public class SnakeGameActivity extends com.codepath.simplegame.GameActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(R.style.AppTheme); switchFullscreen(); // 修改:先创建Panel实例,再设置回调 SnakeGamePanel gamePanel = new SnakeGamePanel(this); gamePanel.setOnGameOverListener(new OnGameOverListener() { @Override public void onGameOver(int finalScore) { Intent intent = new Intent(SnakeGameActivity.this, GameOverActivity.class); intent.putExtra("final_score", finalScore); startActivity(intent); // 可选:finish(); 关闭当前游戏页 } }); setContentView(gamePanel); } }
注意事项
- 一定要加
isGameOverHandled标记,redrawCanvas每帧都会执行,不加标记会重复启动大量Activity - 跳转逻辑要post到主线程执行,避免子线程操作UI组件报错
- 别忘了在
AndroidManifest.xml中注册GameOverActivity
内容的提问来源于stack exchange,提问作者laura
相关产品推荐
相关产品推荐

