libgdx教程_使用libgdx进行Android游戏开发–一天中的原型,第1b部分

本文是libgdx游戏开发教程的第一部分,主要介绍了如何使用libgdx创建游戏的基本屏幕,包括游戏的主屏幕概念,以及如何使用OrthographicCamera和ShapeRenderer进行渲染。文章详细讲解了如何创建屏幕、渲染世界、处理输入,同时提供了台式机和Android平台的启动器实现。通过实例展示了如何实现MVC模式,并为Bob和块添加了图像。最后,文章提到了未来开发计划,如地形交互、动画和更多屏幕功能。
摘要由CSDN通过智能技术生成
libgdx教程

libgdx教程

创造游戏并展现世界

要将世界渲染到屏幕上,我们需要为其创建一个屏幕,并告诉它渲染世界。 在libgdx中,有一个名为Game的便利类,我们将把StarAssault类重写为StarAssault提供的Game类的子类。

关于屏幕

一个游戏可以包含多个屏幕。 甚至我们的游戏也将具有3个基本屏幕。 “开始游戏”屏幕,“播放”屏幕和“游戏结束”屏幕。 每个屏幕都与发生的事情有关,彼此之间并不关心。 例如,“开始游戏”屏幕将包含菜单选项“播放”和“退出” 。 它具有两个元素(按钮),并且关注于处理这些元素上的单击/触摸。 它不知疲倦地渲染这两个按钮,并且如果单击/触摸了“播放”按钮,它将通知主游戏加载“播放屏幕”并摆脱当前屏幕。 播放屏幕将运行我们的游戏,并将处理与游戏有关的所有内容。 达到“游戏结束”状态后,它会告诉主游戏过渡到“游戏结束”屏幕,其唯一目的是显示高分并收听“重播”按钮上的单击。

现在,让我们重构代码并仅创建游戏的主屏幕。 我们将跳过屏幕的开始和游戏。

GameScreen.java

package net.obviam.starassault.screens;

import com.badlogic.gdx.Screen;

public class GameScreen implements Screen {

 @Override
 public void render(float delta) {
  // TODO Auto-generated method stub
 }

 @Override
 public void resize(int width, int height) {
  // TODO Auto-generated method stub
 }

 @Override
 public void show() {
  // TODO Auto-generated method stub
 }

 @Override
 public void hide() {
  // TODO Auto-generated method stub
 }

 @Override
 public void pause() {
  // TODO Auto-generated method stub
 }

 @Override
 public void resume() {
  // TODO Auto-generated method stub
 }

 @Override
 public void dispose() {
  // TODO Auto-generated method stub
 }
}

StarAssault.java将变得非常简单。

package net.obviam.starassault;

import net.obviam.starassault.screens.GameScreen;

import com.badlogic.gdx.Game;

public class StarAssault extends Game {

 @Override
 public void create() {
  setScreen(new GameScreen());
 }
}

GameScreen实现了非常类似于ApplicationListenerScreen接口,但是它添加了2个重要方法。show() –当主游戏激活该屏幕时调用hide() –当主游戏激活另一个屏幕时调用

StarAssault仅实现了一种方法。 create()无非就是激活新实例化的GameScreen 。 换句话说,它创建了它,调用了show()方法,随后将在每个周期调用其render()方法。

GameScreen将成为下一部分的焦点,因为它是游戏的生存地。 请记住,游戏循环是render()方法。 但是要渲染一些东西,我们首先需要创造世界。 可以在show()方法中创建世界,因为我们没有任何其他屏幕可以打断我们的游戏玩法。 当前,仅在游戏开始时才显示GameScreen

我们将在类中添加两个成员并实现render(float delta)方法。

private World world;
 private WorldRenderer renderer;

 /** Rest of methods ommited **/

 @Override
 public void render(float delta) {
  Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
  Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  renderer.render();
 }

world属性是World实例,其中包含块和Bob。renderer是一个类,它将在屏幕上绘制/渲染世界(我很快就会展示出来)。render(float delta)让我们创建WorldRenderer类。WorldRenderer.java

package net.obviam.starassault.view;

import net.obviam.starassault.model.Block;
import net.obviam.starassault.model.Bob;
import net.obviam.starassault.model.World;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;

public class WorldRenderer {

 private World world;
 private OrthographicCamera cam;

 /** for debug rendering **/
 ShapeRenderer debugRenderer = new ShapeRenderer();

 public WorldRenderer(World world) {
  this.world = world;
  this.cam = new OrthographicCamera(10, 7);
  this.cam.position.set(5, 3.5f, 0);
  this.cam.update();
 }

 public void render() {
  // render blocks
  debugRenderer.setProjectionMatrix(cam.combined);
  debugRenderer.begin(ShapeType.Rectangle);
  for (Block block : world.getBlocks()) {
   Rectangle rect = block.getBounds();
   float x1 = block.getPosition().x + rect.x;
   float y1 = block.getPosition().y + rect.y;
   debugRenderer.setColor(new Color(1, 0, 0, 1));
   debugRenderer.rect(x1, y1, rect.width, rect.height);
  }
  // render Bob
  Bob bob = world.getBob();
  Rectangle rect = bob.getBounds();
  float x1 = bob.getPosition().x + rect.x;
  float y1 = bob.getPosition().y + rect.y;
  debugRenderer.setColor(new Color(0, 1, 0, 1));
  debugRenderer.rect(x1, y1, rect.width, rect.height);
  debugRenderer.end();
 }
}

WorldRenderer只有一个目的。 获取世界的当前状态并将其当前状态呈现到屏幕上。 它有一个公共的render()方法,该方法由主循环( GameScreen )调用。 渲染器需要访问world因此我们在实例化渲染器时将其传递。 第一步,我们将渲染元素的边界框(块和鲍勃),以查看到目前为止的内容。 在OpenGL中绘制图元非常繁琐,但是libgdx带有ShapeRenderer ,这使此任务非常容易。重点说明。

#14 –将world声明为成员变量。#15 –我们声明一个OrthographicCamera。 我们将使用此相机从正交摄影法“看”世界。 当前世界很小,只能放在一个屏幕上,但是当我们需要一个宽广的水准并且Bob在其中移动时,我们将不得不跟随Bob移动摄像机。 它类似于现实生活中的相机。 有关正射投影的更多信息,请参见此处#18ShapeRenderer被声明。 我们将使用它为实体绘制图元(矩形)。 这是一个辅助渲染器,可以绘制诸如线,矩形,圆之类的图元。 对于熟悉基于画布的图形的人来说,这应该很容易。#20 –以world为参数的构造函数。#22 –我们创建的相机的视口为10个单位宽和7个单位高。 这意味着用单位块(宽度=高度= 1)填充屏幕将导致在X轴上显示10个框,在Y轴上显示7个框。重要:这与分辨率无关。 如果屏幕分辨率为480×320,则480像素代表10个单位,因此一个框将为48像素宽。 这也意味着320像素代表7个单位,因此屏幕上的框将为45.7像素高。 这将不是一个完美的广场。 这是由于长宽比。 在我们的情况下,长宽比为10:7。#23 –这条线将摄像机定位在房间中间。 默认情况下,它查看房间的角落(0,0)。 相机的(0,0)位于普通相机的中间。 下图显示了世界和相机设置坐标。

#24 –相机的内部矩阵已更新。 每次对摄像机进行操作(移动,缩放,旋转等)时,都必须调用update方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值