libGDX跨平台游戏开发框架入门:开发一个小游戏之渲染和清屏

目录

前言

渲染桶

添加雨滴和渲染雨滴

清屏和回收对象实例


前言

在前面三章中(libGDX跨平台游戏开发框架入门:搭建开发环境和生成libGDX项目_汤姆猫不是猫的博客-CSDN博客_libgdx框架),(libGDX跨平台游戏开发框架入门:运行libGDX项目_汤姆猫不是猫的博客-CSDN博客),(libGDX跨平台游戏开发框架入门:开发一个小游戏之加载资源_汤姆猫不是猫的博客-CSDN博客)我们简单介绍了如何搭建libGDX开发环境和如何运行项目,以及项目中的模块作用等情况,对libGDX有了基本认识,以及通过加载资源篇,了解了libGDX资源管理相关的api内容,本章,我们将通过代码了解libGDX的图形渲染api。

为了更加清楚的描述每个api作用,我们将使用大量的代码和描述,来阐述每个api的作用和用途,所以我们将开发小游戏分为四个部分讲解,由于篇幅限制,我们分为三章讲解各个部分主要内容,最后一篇进行汇总: 1. 加载资源篇 2. 图形渲染、清屏和音效播放篇 3. 鼠标键盘输入和移动篇 4. 小游戏完整版汇总篇

本篇为渲染和清屏篇

渲染桶

是时候渲染我们的桶了。我们要做的第一件事是用深蓝色清除屏幕。只需将render()方法更改为如下所示: ```java

@Override
public void render() {
ScreenUtils.clear(0, 0, 0.2f, 1);

... more to come here ...

} ``` ScreenUtils.clear(r, g, b, a)中参数分别表示的是颜色中的红色、绿色、蓝色和 alpha 分量,每个分量都在 [0, 1] 范围内。

接下来,我们需要告诉我们的相机确保它已更新。相机使用称为矩阵的数学实体,负责设置用于渲染的坐标系。每次我们更改camera的属性(例如:位置)时,都需要重新计算这些矩阵。在我们的简单示例中,我们不这样做,但通常每帧更新一次相机是一个好习惯:

```java

camera.update();

``` 现在我们可以渲染我们的桶:

```java

batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(bucketImage, bucket.x, bucket.y);
batch.end();

``` 第一行告诉SpriteBatch使用camera指定的坐标系。如前所述,这是通过称为投影矩阵的东西完成的,camera.combined字段就是用来指定这种矩阵。从这里开始SpriteBatch将渲染坐标系中的所有内容。

接下来我们告诉SpriteBatch开始一个新的批量任务。为什么我们需要这个批量任务?这涉及到OpenGL渲染原理,理论上来说,如果每个图像都要让GPU去渲染一次,那样一个屏幕上这么多图像,每个都要渲染一次,显然效率太低。所以我们一次性把很多图像渲染任务一起交给opengl让它希望帮我们一次渲染出来,这样可以有效增加游戏帧率,降低gpu占用。

使用SpriteBatch有助于优化OpenGL渲染效率。它将记录SpriteBatch.begin()和之间的所有绘图命令SpriteBatch.end()。一旦我们调用SpriteBatch.end()后,它将立即提交我们提出的所有绘图渲染请求,从而大大加快渲染速度。这一切在开始时可能看起来很麻烦,但这正是以每秒 60 帧的速度渲染 500 个精灵和以每秒 20 帧的速度渲染 100 个精灵之间的区别。

添加雨滴和渲染雨滴

对于雨滴,我们保存一个Rectangle列表,每个Rectangle实例都保存雨滴的位置和大小。 ```java

private Array raindrops; ```

该Array数组是用来取代标准的Java集合像libGDX实用工具类ArrayList。后者的问题在于它们以各种方式产生垃圾。本Array类尝试尽量减少垃圾。libGDX 还提供其他垃圾收集器感知集合,例如hash-maps 或者sets 。

我们还需要跟踪上次生成雨滴的时间,因此我们添加另一个字段: ```java

private long lastDropTime; ```

我们将以纳秒为单位存储时间,这就是我们使用 long 的原因。

为了方便创建雨滴,我们将编写一个名为spawnRaindrop()的方法,该方法实例化一个Rectangle对象,并将其设置到屏幕顶部边缘的随机位置且添加到raindrops数组中。 ```java

private void spawnRaindrop() { 
    Rectangle raindrop = new Rectangle(); 
    raindrop.x = MathUtils.random(0, 800-64); 
    raindrop.y = 480; raindrop.width = 64; 
    raindrop.height = 64; 
    raindrops.add(raindrop); 
    lastDropTime = TimeUtils.nanoTime(); 
}

```

该方法不言自明。MathUtils是一个libGDX类提供各种数学计算相关的静态方法。在这种情况下,它将返回一个介于 0 和 800 - 64 之间的随机值。TimeUtils是另一个 libGDX 类,它提供了一些非常基本的日期时间相关的静态方法。在这种情况下,我们以纳秒为单位记录当前时间,稍后我们将根据该时间决定是否产生新的水滴。

在该create()方法中,我们现在实例化雨滴数组并生成我们的第一个雨滴:

我们需要在create()方法中实例化该数组: ```

raindrops = new Array(); spawnRaindrop(); 

```

接下来,我们向该render()方法添加几行代码,用于检查自我们产生新雨滴以来已经过去了多长时间,并在必要时创建一个新雨滴: ```java

if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop(); ```

我们还需要让雨滴移动,让雨滴以每秒 200 像素/单位的恒定速度移动。如果雨滴在屏幕底部边缘之下,则将其从数组中移除。 ```java

for (Iterator iter = raindrops.iterator(); iter.hasNext(); ) {
 Rectangle raindrop = iter.next(); 
 raindrop.y -= 200 * Gdx.graphics.getDeltaTime(); 
 if(raindrop.y + 64 < 0) 
    iter.remove(); 
} 

```

我们还需要渲染雨滴。把雨滴添加到SpriteBatch渲染代码中: ```java

batch.begin(); 
batch.draw(bucketImage, bucket.x, bucket.y); 
for(Rectangle raindrop: raindrops) { 
    batch.draw(dropImage, raindrop.x, raindrop.y); 
} 
batch.end(); 

```

最后一个判断逻辑:如果雨滴击中了桶,我们想要播放落下的声音并从数组中移除雨滴。只需将以下几行添加到雨滴的更新循环中: ```java

if(raindrop.overlaps(bucket)) {
     dropSound.play();
     iter.remove();
  }

```

Rectangle.overlaps()方法检查矩形是否与另一个矩形重叠。在这个例子中,我们让水滴音效自行播放并从数组中移除雨滴。

清屏和回收对象实例

用户可以随时关闭应用程序。对于我们这个简单的小游戏demo,没有什么特别需要做的事情。但一般来说,稍微清理我们之前创建的几个对象实例有利于降低内存占用,提高游戏运行性能。

任何实现Disposable接口并因此具有dispose()方法的libGDX类在不再使用后都需要手动清理。在我们的示例中,对于纹理、声音和音乐以及SpriteBatch. 作为优秀的程序猿,我们重写该ApplicationAdapter.dispose()方法如下: ```java

@Override public void dispose() { 
    dropImage.dispose(); 
    bucketImage.dispose(); 
    dropSound.dispose(); 
    rainMusic.dispose(); 
    batch.dispose(); 
} 

```

一旦回收了资源,就不应以任何方式访问它。

Disposables 通常是 Java 垃圾收集器不处理的资源。这就是我们需要手动处理它们的原因。libGDX 提供了多种方式来帮助进行资源管理。

到这里,我们已经了解了libGDX资源管理和图形渲染的api、音效播放以及如何清理对象实例,回收内存的内容。下一章我们将讲解如何使用鼠标和键盘等输入设备,然后通过鼠标或者键盘移动游戏中的精灵物体。

如果觉得博主写得还不错,欢迎“关注、点赞、收藏” 一键三连。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汤姆猫不是猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值