在本教程中我们将对雨滴游戏进行扩展。我们将尝试加入一个菜单和其它的一些功能。
(前一篇文章:) ** 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用来显示收集的雨滴。
(版权全部,如需转载,注明出处)