手把手教你写蛇蛇大作战(四)
这篇我们主要 添加 摇杆 、加速按钮 还有音效
首先我们看看这章完成的效果图
在移动设备上只能通过触控板来控制蛇的移动 所以我们要添加一个
TouchPad
和加速按钮
在LibGdx
中已经有了这个控件 但是默认的皮肤太丑了。所以我自己用Sketch
画了一个。
摇杆
背景图片
摇杆图片
图片准备好了开始打包图片
修改DesktopLauncher.java
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class DesktopLauncher { private static boolean rebuildAtlas = true; private static boolean drawDebugOutline = false; public static void main(String[] arg) { if (rebuildAtlas) { TexturePacker.Settings settings = new TexturePacker.Settings(); settings.maxHeight = 1024; settings.maxWidth = 1024; settings.duplicatePadding = false; settings.debug = drawDebugOutline; TexturePacker.process(settings, "../../desktop/images", "../../android/assets/images", "snake"); //添加打包 摇杆皮肤 TexturePacker.process(settings, "../../desktop/images-ui", "../../android/assets/images", "touchpad-ui"); } LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); config.width = 800; config.height = 480; config.samples = 3; new LwjglApplication(new SnakeIo(), config); } } |
运行下DesktopLauncher
,就会在android/assets/images 目录下生成皮肤文件
然后我们新建文件 touchpad-ui.json
内容如下
1 2 3 4 5 6 7 8 9 10 |
{ com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: { default: { background: background, knob: knob } } } |
添加TouchPad
在WorldRenderer.java
添加以下属性
1 2 3 4 5 6 |
private Skin touchPadSkin;//摇杆皮肤 public Stage stage;//舞台 private Touchpad touchpad;//摇杆 private ImageButton btnSpeed;//加速按钮 |
在init()
方法下面添加初始化代码
1 2 3 4 5 6 7 8 |
stage = new Stage(new ExtendViewport(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT)); touchPadSkin = new Skin(Gdx.files.internal(Constants.SKIN_TOUCHPAD_UI),new TextureAtlas(Constants.TEXTURE_ATLAS_TOUCHPAD_UI)); stage.addActor(buildSpeed()); stage.addActor(buildTouchPad()); worldController.touchProcessor = stage;//touchpad 监听 |
buildSpeed()
和buildTouchPad()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private ImageButton buildSpeed() { Drawable drawable = new TextureRegionDrawable(Assets.instance.ui.lightning); btnSpeed = new ImageButton(drawable); btnSpeed.setBounds(stage.getWidth() - 150, 50, 100, 100); btnSpeed.addListener(new ClickListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { worldController.snake.speedUp(); return super.touchDown(event, x, y, pointer, button); } @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { super.touchUp(event, x, y, pointer, button); worldController.snake.speedDown(); } }); return btnSpeed; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
private Touchpad buildTouchPad() { Skin skin = touchPadSkin; touchpad = new Touchpad(20, skin); touchpad.setBounds(50, 50, 100, 100); touchpad.addListener(new InputListener() { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { return true; } @Override public void touchDragged(InputEvent event, float x, float y, int pointer) { super.touchDragged(event, x, y, pointer); // knob相对touchpad左下角的位置 float knobX = touchpad.getKnobX(); float knobY = touchpad.getKnobY(); // knob依touchpad的中心点向右水平线, float knobPercentX = touchpad.getKnobPercentX(); // 手指离开中心向左趋于-1,向右趋于1 float knobPercentY = touchpad.getKnobPercentY(); // 手指离开中心向下趋于1,向上趋于-1 if (knobPercentX == 0 && knobPercentY == 0) return; double angle = Math.atan2(knobPercentY, knobPercentX); if (angle < 0) { angle += Math.PI * 2; } worldController.snake.setDirection(angle); } @Override public void touchUp(InputEvent event, float x, float y, int pointer, int button) { super.touchUp(event, x, y, pointer, button); } }); return touchpad; } |
修改render()
方法
1 2 3 4 5 6 7 8 |
public void render() { renderBackground(shapeRenderer); renderWorld(spriteBatch); stage.act(Gdx.graphics.getDeltaTime()); stage.draw(); } |
修改resize()
方法
1 2 3 4 5 6 7 8 |
public void resize(int width, int height) { camera.viewportWidth = Constants.VIEWPORT_WIDTH; // Viewport of 30 units! camera.viewportHeight = Constants.VIEWPORT_HEIGHT * height / width; // Lets keep things in proportion. camera.update(); stage.getViewport().update(width, height); } |
可以运行看看效果了。
添加声音
这个声音上传不上去,请到我的github去下载吧
把声音拷贝到assets下的sounds目录下
然后编写代码
修改Assets.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
... public AssetSounds sounds; ... public void init(AssetManager assetManager) { this.assetManager = assetManager; assetManager.setErrorListener(this); assetManager.load(Constants.TEXTURE_ATLAS_OBJECTS, TextureAtlas.class); //load sounds assetManager.load("sounds/bm.mp3", Music.class); assetManager.load("sounds/live_lost.wav", Sound.class); assetManager.finishLoading(); ... sounds = new AssetSounds(assetManager); } public class AssetSounds { public final Music bm; public final Sound liveLost; public AssetSounds(AssetManager manager) { this.bm = manager.get("sounds/bm.mp3", Music.class); this.liveLost = manager.get("sounds/live_lost.wav", Sound.class); } } |
LigbGdx 提供了Sound.java
和Music.java
来播放声音
我们这边的背景音乐是mp3格式的所以用Musice.java
在这个之前我们先添加我们的声音播放类AudioManager.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
public class AudioManager { public static final AudioManager instance = new AudioManager(); private Music playingMusic; // singleton: prevent instantiation from other classes private AudioManager() { } public void play(Sound sound) { play(sound, 1); } public void play(Sound sound, float volume) { play(sound, volume, 1); } public void play(Sound sound, float volume, float pitch) { play(sound, volume, pitch, 0); } public void play(Sound sound, float volume, float pitch, float pan) { if (!GamePreferences.instance.sound) return; sound.play(GamePreferences.instance.volSound * volume, pitch, pan); } public void play(Music music) { stopMusic(); playingMusic = music; if (GamePreferences.instance.music) { music.setLooping(true); music.setVolume(GamePreferences.instance.volMusic); music.play(); } } public void stopMusic() { if (playingMusic != null) playingMusic.stop(); } public void onSettingsUpdated() { if (playingMusic == null) return; playingMusic.setVolume(GamePreferences.instance.volMusic); if (GamePreferences.instance.music) { if (!playingMusic.isPlaying()) playingMusic.play(); } else { playingMusic.pause(); } } } |
这边为了方便我们直接把设置方法也写进去了,GamePreferences 提供游戏菜单设置声音大小 的方法 在这里我们省略可以去github 看代码
播放声音
修改SnakeIo.java
1 2 3 4 5 6 7 8 9 10 11 |
@Override public void create() { GamePreferences.instance.load(); Assets.instance.init(new AssetManager()); worldController = new WorldController(); worldRenderer = new WorldRenderer(worldController); Gdx.input.setInputProcessor(worldController); AudioManager.instance.play(Assets.instance.sounds.bm); } |
在dispose()
中添加暂停方法
1 2 3 4 5 6 7 8 9 |
@Override public void dispose() { AudioManager.instance.stopMusic(); worldRenderer.dispose(); worldController.dispose(); Assets.instance.dispose(); } |
这篇文章就ok了,基本功能实现了。还有未实现的功能
- 判断游戏的结束
- 添加机器蛇
- 添加游戏菜单
代码已经放在GITHUB
可以切换到tag3
来查看本篇文章代码
使用
git checkout tag3
转载请注明:zhangman523 » 手把手教你写蛇蛇大作战(四)