5.1、雨滴遊戲的擴充,5.1雨滴擴充
在本教程中我們將對雨滴遊戲進行擴充。我們將嘗試添加一個菜單和其他的一些功能。
(前一篇文章:點擊進入)
** Screen介面**
Screen對於任何遊戲都是基本的,Screen包含很多來自ApplicationListener對象的方法,但包含兩個新的方法:show和hide。用來獲得或失去焦點。
** Game類**
Game類提供來繼承自ApplicationListener的介面供使用,同時提供了一些方法用來設定和控制Screen渲染。
通過使用Screen和Game對象,可以建立一個簡單而結構健壯的遊戲。
接下來建立一個Game對象,作為遊戲的入口。
代碼如下:
package cn.libgdx.drop;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Drop extends Game {
public SpriteBatch batch;
public BitmapFont font;
public void create() {
batch = new SpriteBatch();
//使用Libgdx預設的字型
font = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
}
public void render() {
super.render(); //這個非常重要!
}
public void dispose() {
batch.dispose();
font.dispose();
}
}
我們啟動應用時執行個體化一個SpriteBatch和BitmapFont。SpriteBatch對象用來渲染螢幕的對象,像texture;BitmapFont對象與SpriteBatch一起使用,用來設定渲染字型。
接下來,我們設定MainMenuScreen對象,用來在首次運行時設定參數。
通常的錯誤是忘記在render()方法中調用super.render()方法,否則Screen類中的create()方法將不會被渲染。
最後,不要忘記消除所有對象!
主菜單
代碼如下:
package cn.libgdx.drop;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
public class MainMenuScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public MainMenuScreen(final Drop gam) {
game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
}
在代碼中,我們添加繼承自Screen介面的構造方法,Screen介面不提供任何create()方法,所以我們使用構造方法。構造方法唯一必須的參數是一個執行個體化的Drop。接下來是render()方法:
public class MainMenuScreen implements Screen {
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Drop!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen(new GameScreen(game));
dispose();
}
}
}
我們調用之前建立的SpriteBatch和BitmapFont。接下來檢測螢幕是否被觸摸,如果為true則將遊戲設定為一個GameScreen執行個體並且銷毀當前執行個體。
遊戲螢幕
接下來我們製作我們的遊戲,代碼如下:
package cn.libgdx.drop;
import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
public class GameScreen implements Screen {
final Drop game;
Texture dropImage;
Texture bucketImage;
Sound dropSound;
Music rainMusic;
OrthographicCamera camera;
Rectangle bucket;
Array raindrops;
long lastDropTime;
int dropsGathered;
public GameScreen(final Drop gam) {
this.game = gam;
// 載入圖片
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);
//建立相機和SpriteBatch
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
// 建立Rectangle
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2;
bucket.y = 20;
bucket.width = 64;
bucket.height = 64;
raindrops = new Array();
spawnRaindrop();
}
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();
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Drops Collected: " + dropsGathered, 0, 480);
game.batch.draw(bucketImage, bucket.x, bucket.y);
for (Rectangle raindrop : raindrops) {
game.batch.draw(dropImage, raindrop.x, raindrop.y);
}
game.batch.end();
if (Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
}
if (Gdx.input.isKeyPressed(Keys.LEFT))
bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if (Gdx.input.isKeyPressed(Keys.RIGHT))
bucket.x += 200 * Gdx.graphics.getDeltaTime();
if (bucket.x < 0)
bucket.x = 0;
if (bucket.x > 800 - 64)
bucket.x = 800 - 64;
if (TimeUtils.nanoTime() - lastDropTime > 1000000000)
spawnRaindrop();
Iterator iter = raindrops.iterator();
while (iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if (raindrop.y + 64 < 0)
iter.remove();
if (raindrop.overlaps(bucket)) {
dropsGathered++;
dropSound.play();
iter.remove();
}
}
}
@Override
public void resize(int width, int height) {
}
@Override
public void show() {
rainMusic.play();
}
@Override
public void hide() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
}
}
這裡我們使用了構造方法來代替繼承自ApplicationListener的create()方法,傳遞一個Drop對象。
我們添加了一個Sring用來顯示收集的雨滴。
(www.libgdx.cn著作權,如需轉載,註明出處)