libgdx实例分析小记(二)

 

GameScreen
 public GameScreen (Game game) {
  super(game);
  state = GAME_READY;  //游戏状态
  guiCam = new OrthographicCamera(320, 480);
  guiCam.position.set(320 / 2, 480 / 2, 0);
  touchPoint = new Vector3();
  batcher = new SpriteBatch();
  worldListener = new WorldListener() {
   @Override
   public void jump () {
    Assets.playSound(Assets.jumpSound);
   }

   @Override
   public void highJump () {
    Assets.playSound(Assets.highJumpSound);
   }

   @Override
   public void hit () {
    Assets.playSound(Assets.hitSound);
   }

   @Override
   public void coin () {
    Assets.playSound(Assets.coinSound);
   }
  };
  world = new World(worldListener);
  renderer = new WorldRenderer(batcher, world);

//暂停按钮
  pauseBounds = new Rectangle(320 - 64, 480 - 64, 64, 64);
//恢复按钮
  resumeBounds = new Rectangle(160 - 96, 240, 192, 36);
//退出按钮
  quitBounds = new Rectangle(160 - 96, 240 - 36, 192, 36);
  lastScore = 0;
  scoreString = "SCORE: 0";
 }

//逻辑,不同情况通过不同的函数处理
 @Override
 public void update (float deltaTime) {
  if (deltaTime > 0.1f) deltaTime = 0.1f;

  switch (state) {
  case GAME_READY:
   updateReady();
   break;
  case GAME_RUNNING:
   updateRunning(deltaTime);
   break;
  case GAME_PAUSED:
   updatePaused();
   break;
  case GAME_LEVEL_END:
   updateLevelEnd();
   break;
  case GAME_OVER:
   updateGameOver();
   break;
  }
 }

//状态机
 private void updateReady () {
  if (Gdx.input.justTouched()) {
   state = GAME_RUNNING;
  }


 }

//运行状态
 private void updateRunning (float deltaTime) {
  if (Gdx.input.justTouched()) {
//将点击点由窗口位置转换为世界坐标系
   guiCam.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));

   if (OverlapTester.pointInRectangle(pauseBounds, touchPoint.x, touchPoint.y)) {
    Assets.playSound(Assets.clickSound);
    state = GAME_PAUSED;
    return;
   }
  }


//
  if (Gdx.app.getType() == Application.ApplicationType.Android) {
   world.update(deltaTime, Gdx.input.getAccelerometerX());
  } else {
   float accel = 0;
   if (Gdx.input.isKeyPressed(Keys.DPAD_LEFT)) accel = 5f;
   if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) accel = -5f;
   world.update(deltaTime, accel);
  }
  if (world.score != lastScore) {
   lastScore = world.score;
   scoreString = "SCORE: " + lastScore;
  }
  if (world.state == World.WORLD_STATE_NEXT_LEVEL) {
   state = GAME_LEVEL_END;
  }
  if (world.state == World.WORLD_STATE_GAME_OVER) {
   state = GAME_OVER;
   if (lastScore >= Settings.highscores[4])
    scoreString = "NEW HIGHSCORE: " + lastScore;
   else
    scoreString = "SCORE: " + lastScore;
   Settings.addScore(lastScore);
   Settings.save();
  }
 }


World
上面大量用了这个类,这个应该是游戏的逻辑中心

 

 private void updatePaused () {
  if (Gdx.input.justTouched()) {
   guiCam.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));

   if (OverlapTester.pointInRectangle(resumeBounds, touchPoint.x, touchPoint.y)) {
    Assets.playSound(Assets.clickSound);
    state = GAME_RUNNING;
    return;
   }

   if (OverlapTester.pointInRectangle(quitBounds, touchPoint.x, touchPoint.y)) {
    Assets.playSound(Assets.clickSound);
    game.setScreen(new MainMenuScreen(game));
    return;

   }
  }
 }
这段基本没有什么,就是点击按钮的逻辑

 @Override
 public void present (float deltaTime) {
  GLCommon gl = Gdx.gl;
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  gl.glEnable(GL10.GL_TEXTURE_2D);

  renderer.render();

  guiCam.update();
  batcher.setProjectionMatrix(guiCam.combined);
  batcher.enableBlending();
  batcher.begin();
  switch (state) {
  case GAME_READY:
   presentReady();
   break;
  case GAME_RUNNING:
   presentRunning();
   break;
  case GAME_PAUSED:
   presentPaused();
   break;
  case GAME_LEVEL_END:
   presentLevelEnd();
   break;
  case GAME_OVER:
   presentGameOver();
   break;
  }
  batcher.end();
 }

这个是渲染逻辑,
renderer.render()
WorldRenderer
 public void render () {
  if (world.bob.position.y > cam.position.y) cam.position.y = world.bob.position.y;//一直以bob的位置为观察点
  cam.update();
  batch.setProjectionMatrix(cam.combined);
  renderBackground();
  renderObjects();
 }


//很简单的贴图
 public void renderBackground () {
  batch.disableBlending();
  batch.begin();
  batch.draw(Assets.backgroundRegion, cam.position.x - FRUSTUM_WIDTH / 2, cam.position.y - FRUSTUM_HEIGHT / 2, FRUSTUM_WIDTH,
   FRUSTUM_HEIGHT);   //注意贴图是以观察点为中心贴图,这里不用屏幕坐标,充分考虑了手机的尺寸可能变化,
  batch.end();
 }

 public void renderObjects () {
  batch.enableBlending();
  batch.begin();
  renderBob();
  renderPlatforms();
  renderItems();
  renderSquirrels();
  renderCastle();
  batch.end();
 }

 private void renderBob () {
  TextureRegion keyFrame;
  switch (world.bob.state) {
  case Bob.BOB_STATE_FALL:
   keyFrame = Assets.bobFall.getKeyFrame(world.bob.stateTime, Animation.ANIMATION_LOOPING);   //掉落的状态
   break;
  case Bob.BOB_STATE_JUMP:
   keyFrame = Assets.bobJump.getKeyFrame(world.bob.stateTime, Animation.ANIMATION_LOOPING);   //跳起的状态
   break;
  case Bob.BOB_STATE_HIT:
  default:
   keyFrame = Assets.bobHit;
  }

  float side = world.bob.velocity.x < 0 ? -1 : 1;
  if (side < 0)
   batch.draw(keyFrame, world.bob.position.x + 0.5f, world.bob.position.y - 0.5f, side * 1, 1);
  else
   batch.draw(keyFrame, world.bob.position.x - 0.5f, world.bob.position.y - 0.5f, side * 1, 1);
 }


Assets里面保存了bob的一些Animation
items = loadTexture("data/items.png");
bobJump = new Animation(0.2f, new TextureRegion(items, 0, 128, 32, 32), new TextureRegion(items, 32, 128, 32, 32));
bobFall = new Animation(0.2f, new TextureRegion(items, 64, 128, 32, 32), new TextureRegion(items, 96, 128, 32, 32));

Animation
 public TextureRegion getKeyFrame (float stateTime, boolean looping) {
  int frameNumber = (int)(stateTime / frameDuration);

  if (!looping) {
   frameNumber = Math.min(keyFrames.length - 1, frameNumber);
  } else {
   frameNumber = frameNumber % keyFrames.length;
  }
  return keyFrames[frameNumber];
 }

通过上面的操作来取得一个动态的图片

下面大同小异
 private void renderPlatforms () {
  int len = world.platforms.size();
  for (int i = 0; i < len; i++) {
   Platform platform = world.platforms.get(i);
   TextureRegion keyFrame = Assets.platform;
   if (platform.state == Platform.PLATFORM_STATE_PULVERIZING) {
    keyFrame = Assets.brakingPlatform.getKeyFrame(platform.stateTime, Animation.ANIMATION_NONLOOPING);
   }

   batch.draw(keyFrame, platform.position.x - 1, platform.position.y - 0.25f, 2, 0.5f);
  }
 }

 private void renderItems () {
  int len = world.springs.size();
  for (int i = 0; i < len; i++) {
   Spring spring = world.springs.get(i);
   batch.draw(Assets.spring, spring.position.x - 0.5f, spring.position.y - 0.5f, 1, 1);
  }

  len = world.coins.size();
  for (int i = 0; i < len; i++) {
   Coin coin = world.coins.get(i);
   TextureRegion keyFrame = Assets.coinAnim.getKeyFrame(coin.stateTime, Animation.ANIMATION_LOOPING);
   batch.draw(keyFrame, coin.position.x - 0.5f, coin.position.y - 0.5f, 1, 1);
  }
 }

 private void renderSquirrels () {
  int len = world.squirrels.size();
  for (int i = 0; i < len; i++) {
   Squirrel squirrel = world.squirrels.get(i);
   TextureRegion keyFrame = Assets.squirrelFly.getKeyFrame(squirrel.stateTime, Animation.ANIMATION_LOOPING);
   float side = squirrel.velocity.x < 0 ? -1 : 1;
   if (side < 0)
    batch.draw(keyFrame, squirrel.position.x + 0.5f, squirrel.position.y - 0.5f, side * 1, 1);
   else
    batch.draw(keyFrame, squirrel.position.x - 0.5f, squirrel.position.y - 0.5f, side * 1, 1);
  }
 }

 private void renderCastle () {
  Castle castle = world.castle;
  batch.draw(Assets.castle, castle.position.x - 1, castle.position.y - 1, 2, 2);
 }


回到刚才的一段,主要画面绘制完毕,下面绘制不同状态的不同画面
  batcher.begin();
  switch (state) {
  case GAME_READY:
   presentReady();
   break;
  case GAME_RUNNING:
   presentRunning();
   break;
  case GAME_PAUSED:
   presentPaused();
   break;
  case GAME_LEVEL_END:
   presentLevelEnd();
   break;
  case GAME_OVER:
   presentGameOver();
   break;
  }

绘制一串文字
 private void presentReady () {
  batcher.draw(Assets.ready, 160 - 192 / 2, 240 - 32 / 2, 192, 32);
 }

 private void presentRunning () {
  batcher.draw(Assets.pause, 320 - 64, 480 - 64, 64, 64);
  Assets.font.draw(batcher, scoreString, 16, 480 - 20);
 }

 private void presentPaused () {
  batcher.draw(Assets.pauseMenu, 160 - 192 / 2, 240 - 96 / 2, 192, 96);
  Assets.font.draw(batcher, scoreString, 16, 480 - 20);
 }

 private void presentLevelEnd () {
  String topText = "the princess is ...";
  String bottomText = "in another castle!";
  float topWidth = Assets.font.getBounds(topText).width;
  float bottomWidth = Assets.font.getBounds(bottomText).width;
  Assets.font.draw(batcher, topText, 160 - topWidth / 2, 480 - 40);
  Assets.font.draw(batcher, bottomText, 160 - bottomWidth / 2, 40);
 }

 private void presentGameOver () {
  batcher.draw(Assets.gameOver, 160 - 160 / 2, 240 - 96 / 2, 160, 96);
  float scoreWidth = Assets.font.getBounds(scoreString).width;
  Assets.font.draw(batcher, scoreString, 160 - scoreWidth / 2, 480 - 20);
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值