• 5、使用Libgdx设计一个简单的游戏------雨滴


    (原文:http://www.libgdx.cn/topic/49/5-%E4%BD%BF%E7%94%A8libgdx%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E6%B8%B8%E6%88%8F-%E9%9B%A8%E6%BB%B4

    在深入研究Libgdx提供的API之前,我们先来创建一个简单的游戏来感受一下libgdx各个功能。这里将简单的对一些功能做介绍。

    使用的技术:

    • 文件訪问

    • 清除屏幕

    • 渲染图片

    • 使用相机

    • 主要的输入

    • 播放音效

    项目设置
    首先创建一个libgdx项目,移步到这里

    • 应用名称(Application name):drop

    • 包名(Package name):cn.libgdx.drop

    • 游戏类(Game class):Drop

    生成项目之后,将其导入到eclipse中(须要记住,是Gradle项目)。

    游戏设计思路
    游戏思路非常easy:

    • 使用一个桶雨滴

    • 桶在屏幕底部

    • 雨滴随机从屏幕顶部下载。加速下落

    • 玩家能够水平拖动桶

    • 游戏没有结束

    Assets文件

    点击下载资源文件

    我们须要一些图片和音效来让游戏变得更好。对于图像来说我们须要设置分辨率为800*480像素(在Android中要设置为横向(landscape ))。假设设备没有这个分辨率,我们须要设置适用屏幕。
    为了让资源文件在游戏中可用。我们必须将资源文件放到Android项目的assets目录下。

    一共四个文件:drop.wav。rain.mp3。droplet.png和bucket.png。

    把他们放到drop-android/assets/目录下。

    配置启动类
    准备完之前的配置后。我们须要改动desktop项目的启动类。打开drop-desktop项目下的DesktopLauncher.java文件。我们须要设置窗体为800*480,设置窗体标题为“雨滴”。代码例如以下:

    package cn.libgdx.drop.desktop;

    import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
    import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
    import cn.libgdx.drop.Drop;

    public class DesktopLauncher {
    public static void main (String[] arg) {
    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
    config.title="雨滴";
    config.width=800;
    config.height=480;
    new LwjglApplication(new Drop(), config);
    }
    }

    找到Android项目(即drop-android)。须要设置应用的屏幕方向。所以须要改动项目根文件夹AndroidManifest.xml文件,设置android:screenOrientation="landscape"。代码例如以下:

    <?

    xml version="1.0" encoding="utf-8"?

    >
    <manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package="cn.libgdx.drop.android"
    android:versionCode="1"
    android:versionName=&quot;1.0&quot; >

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />

    <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/GdxTheme" >
    <activity
    android:name=&quot;cn.libgdx.drop.android.AndroidLauncher&quot;
    android:label="@string/app_name"
    android:screenOrientation="landscape"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
    <intent-filter>
    <action android:name=&quot;android.intent.action.MAIN&quot; />
    <category android:name=&quot;android.intent.category.LAUNCHER&quot; />
    </intent-filter>
    </activity>
    </application>

    </manifest>

    事实上是用GDX-setup生成的项目android:screenOrientation默认值为landscape。所以无需修改。


    接下来须要禁用加速度计和罗盘。这须要修改Android项目AndroidLauncher.java文件,代码例如以下:
    package cn.libgdx.drop.android;

    import android.os.Bundle;

    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.backends.android.AndroidApplication;
    import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;

    import cn.libgdx.drop.Drop;

    public class AndroidLauncher extends AndroidApplication {
    @Override
    protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    config.useAccelerometer=false;
    config.useCompass=false;
    initialize(new Drop(), config);
    }
    }

    我们不能定义Activity的分辨率,这个是由Android操作系统来定。

    就像我们之前定义的,设置全部平台分辨率为800*480。

    開始编写代码

    如今将代码分成几个部分来分析。为了保持项目的可移植性,我们须要将代码写到core项目下。

    加载Assets
    我们第一个任务就是加载assets文件和保存參数。Assets通常在ApplicationListener.create()方法中加载,代码例如以下:

    package cn.libgdx.drop;

    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.audio.Music;
    import com.badlogic.gdx.audio.Sound;
    import com.badlogic.gdx.graphics.GL20http://com.badlogic.gdx.graphics.GL200;
    import com.badlogic.gdx.graphics.Texturehttp://com.badlogic.gdx.graphics.Texturee;
    import com.badlogic.gdx.graphics.g2d.SpriteBatchhttp://com.badlogic.gdx.graphics.g2d.SpriteBatchh;

    public class Drop extends ApplicationAdapter {
    private Texture dropImage;
    private Texture bucketImage;
    private Sound dropSound;
    private Music rainMusic;

    @Override
    public void create () {
    //将资源加载到GPU中。
    dropImage=new Texture(Gdx.files.internal("droplet.png"));
    bucketImage=new Texture(Gdx.files.internal("bucket.png"));
    //加载雨滴音效和下雨背景音乐
    dropSound=Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
    rainMusic=Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
    //開始播放背景音乐
    rainMusic.setLooping(true);
    rainMusic.play();
    }

    @Override
    public void render () {

    }
    }

    在create()方法中前两行加载雨滴和桶。Texture是指将图像加载并保存到缓存。Texture通过一个文件句柄(FileHandle)。FileHandle通过Gdx.files获取。这里有不同的文件。假设是调用Android下assets目录下的资源。使用internal。


    接下来是加载音效和背景音乐。libgdx分音效和音乐。音效是保存到内存中。音乐是从保存的地方直接加载的音乐。音乐文件一般比較大不能所有加载内存。

    假设声音低于10秒,最好使用音效;假设超过10秒。就使用音乐。


    加载音效通过Gdx.audio.newSound()方法。加载音乐使用Gdx.audio.newMusic()方法。两种方法都须要传递一个文件句柄(FileHandle),即可上面的Texture。
    接下来就是播放音乐而且设置循环。

    假设你这是执行程序,会听到下雨声。

    Camera和SpriteBatch
    接下来须要创建相机(camera)和SpriteBatch。我们使用相机的目的是在全部的平台都使用800*480分辨率。不管它的真实屏幕的大小。SpriteBatch是绘制2D图像的特殊类,跟texture几乎相同。


    我们加入两个变量到类中。例如以下:

    private OrthographicCamera camera;
    private SpriteBatch batch;
    在create()方法中加入例如以下语句,创建camera:

    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);

    这将确保camera总是显示800*480的范围。能够视作一个虚拟窗体。

    这样能够让应用可移植性增强。
    接下来,在create()方法中创建SpriteBatch:
    batch=new SpriteBatch();

    加入桶
    最后加入桶和雨滴,它们须要下面的条件:

    • 桶和雨滴在800*480中须要一个位置信息。

    • 桶和雨滴须要宽和高。

    • Texture

    为了展现桶和雨滴,我们须要保存它们的位置和大小。在Libgdx中能够通过Rectangle实现。代码例如以下:
    private Rectangle bucket;

    在create()方法中我们须要实例化而且设置他的仅仅。这里设置在屏幕底部。而且水平居中。代码例如以下:

    bucket = new Rectangle();
    bucket.x = 800 / 2 - 64 / 2;
    bucket.y = 20;
    bucket.width = 64;
    bucket.height = 64;

    须要注意的是。在libgdx中,坐标系原点在左下角。

    渲染桶

    接下来须要渲染我们的桶,首先须要设置屏幕的背景色,在render()方法中加入例如以下代码:

    @Override
    public void render () {
    Gdx.gl.glClearColor(0, 0, 0.2f, 1)http://Gdx.gl.glClearColor(0.2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)http://Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)

    }
    为了使用顶层的类,像Texture和SpriteBatch。首先须要调用清除屏幕并设置为蓝色。第一句的意思是设置清屏颜色,第二句才运行清屏操作。
    接下来我们须要告诉camera确保它更新。接下来我们设置camera在每一帧中都更新。

    接下来我们须要渲染桶。
    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(bucketImage, bucket.x, bucket.y);
    batch.end();

    第一句设置batch的坐标系统为相机,batch.end();会马上提交我们的绘制请求。

    让桶能够移动

    接下来我们控制桶。

    在设计游戏时。我们的设想是桶能够拖动。假设触摸屏幕或者鼠标button。

    我们想让桶进行水平移动。

    if(Gdx.input.isTouched()) {
    touchPos = new Vector3();
    touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
    camera.unproject(touchPos);
    bucket.x = touchPos.x - 64 / 2;
    }
    首先我们询问input模块通过Gdx.input.isTouched()来推断是否被触摸。接下来我们将触摸或者鼠标点击的卫士传递到camera的坐标系统。Gdx.input.getX()和Gdx.input.getY()方法用于返回当前触摸和鼠标的位置。

    为了转换当前坐标系统为camera的坐标系统我们须要使用camera.uproject()方法,调用这种方法须要一个Vector3,一个三维向量。

    我们创建这个向量。设置当前触摸或者鼠标的当前坐标,调用方法。


    须要注意的是touchPos须要在类中声明,假设在if语句中,每次运行这个语句就会创建一个变量,这就会导致Android的垃圾处理产生异常。


    touchPos是一个三维向量,你可能想知道为什么我们用2D界面须要一个三维向量。其实,OrthographicCamera是一个三维相机(camera)。

    让桶移动(键盘)

    在桌面和浏览器环境我们相同须要获取键盘输入。让我们通过设置能够通过键盘来操作桶。
    if(Gdx.input.isKeyPressed(Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime()http://Gdx.graphics.getDeltaTime()FT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
    if(Gdx.input.isKeyPressed(Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime()http://Gdx.graphics.getDeltaTime()GHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime();

    当键盘按下时,Gdx.input.isKeyPressed()方法用来推断是否为指定按键。Gdx.graphics.getDeltaTime()返回一帧的时间http://Gdx.graphics.getDeltaTime()用来推断是否为指定按键。

    Gdx.graphics.getDeltaTime()返回一帧的时间。
    我们相同须要设置桶不要越界:
    if(bucket.x < 0) bucket.x = 0;
    if(bucket.x > 800 - 64) bucket.x = 800 - 64;

    加入雨滴

    对于雨滴来说我们须要使用一个Rectangle数组。每一个保存雨滴的位置和大小。

    让我们加入一个变量:
    private Array<Rectangle> raindrops;
    这个Array类是一个libgdx的工具类。用来取代java的ArrayList。后者将在非常多情况下产生垃圾。Array尽量降低垃圾的产生。
    我们相同须要记录上一次掉落的雨滴的时间。所以我们加入:
    private long lastDropTime;
    我们将存储纳秒。这就是我们为什么使用long。

    以下方法用来随机产生雨点:

    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();
    }

    我们须要在create()方法中进行实例化:
    raindrops = new Array<Rectangle>();
    spawnRaindrop();
    接下来我们须要在render()方法中检測雨点的时间间隔,并生成新雨点:
    if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop();
    我们相同须要雨点移动,一下是代码:

    Iterator<Rectangle> iter = raindrops.iterator();
    while(iter.hasNext()) {
    Rectangle raindrop = iter.next();
    raindrop.y -= 200 * Gdx.graphics.getDeltaTime()http://Gdx.graphics.getDeltaTime()getDeltaTime();
    if(raindrop.y + 64 < 0) iter.remove();
    }
    雨点须要被渲染,所以须要SpriteBatch来进行渲染:
    batch.begin();
    batch.draw(bucketImage, bucket.x, bucket.y);
    for(Rectangle raindrop: raindrops) {
    batch.draw(dropImage, raindrop.x, raindrop.y);
    }
    batch.end();

    最后须要推断雨滴和桶是否重叠。假设重叠。就删除雨滴:

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

    退出清理
    最后须要清理。代码例如以下:
    @Override
    public void dispose() {
    dropImage.dispose();
    bucketImage.dispose();
    dropSound.dispose();
    rainMusic.dispose();
    batch.dispose();
    }

    点击下载源代码
    www.libgdx.cn版权全部,如需转载。注明出处)

  • 相关阅读:
    模拟退火求最小覆盖圆和最小覆盖球
    牛客SQL题解-请你对于表actor批量插入如下数据(不能有2条insert语句哦!)
    牛客SQL题解-创建一个actor表,包含如下列信息
    牛客SQL题解-将employees表的所有员工的last_name和first_name拼接起来作为Name,中间以一个空格区分
    牛客SQL题解-查找描述信息中包括robot的电影对应的分类名称以及电影数目
    牛客SQL题解-汇总各个部门当前员工的title类型的分配数目
    JavaScript
    JavaScript-给代码添加注释
    牛客SQL题解-获取员工其当前的薪水比其manager当前薪水还高的相关信息
    牛客SQL题解-获取所有非manager员工当前的薪水情况
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6803695.html
Copyright © 2020-2023  润新知