本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2013/03/17/libgdx-game-3/
这一篇主要是添加一些让游戏更人性化的东西,比如音效和加载画面,菜单等等。
这其中用到了很多资源,主要出自以下几个网站,大家有需要也可以去上面寻找。
添加音效
首先是飞镖发出时候的音效,我希望是类似”bing”的一声,要短小精炼。
我使用的是http://www.freesound.org/people/BMacZero/sounds/96132/
libgdx支持的音频主要是WAV, MP3和OGG,其他的支持需要扩展支持。
libgdx中的音频有两种,一种是sound,一种是music。
一般所谓的音效使用sound,而音乐就使用music。
在DartController中添加属性
Sound bing;
在实例化方法中添加
this.bing = Gdx.audio.newSound(Gdx.files.internal("audio/bing.wav"));
在AddDart方法中添加
bing.play();
在怪兽被消灭的时候的音效我选用http://www.freesound.org/people/yottasounds/sounds/174465/
在TargetController中添加
great = Gdx.audio.newSound(Gdx.files.internal("audio/great.wav"));
最后添加一个背景音乐。我使用的是http://www.freesound.org/people/Setuniman/sounds/167453/
大小为5.7M,个人感觉有点大。
而且我需要循环播放,这就意味着末尾的这个部分的我不需要。
使用在线转换器截取并转化成ogg。
转化以后大小变成465kb了。仔细听一下,感觉很多部分是重复,所以再一次截取,只要前4秒的。
转化好以后在主类添加
backgroundMusic = Gdx.audio.newMusic(Gdx.files
.internal("audio/background.ogg"));
backgroundMusic.setLooping(true);//循环播放
backgroundMusic.setVolume(0.4f);//设置音量
backgroundMusic.play();//播放
因为music可以在resume和pause时自动播放和暂停,所以不需要其他的处理。在游戏关闭时需要将其释放掉。
backgroundMusic.dispose();
Game-Screen模式和资源预加载
到目前为止我们的所有操作都在一个界面上,但是一个游戏中可能有很多不同的界面和场景,比如菜单,帮助,关卡1,关卡2等等。
libgdx提供了Game-Screen模式,即只有一个Game,但是Game中有很多Screen。通过setScreen来切换。
这里注意一下Game所提供的切换功能没有任何过渡效果,后面会有添加过多效果的例子。
新建DartsGame类,继承Game类。在darts-shasha-android项目和darts-shasha-desktop项目中分别修改入口代码
package com.cnblogs.htynkn;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
publicclass MainActivity extends AndroidApplication {
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg =new AndroidApplicationConfiguration();
cfg.useGL20 =false;
initialize(new DartsGame(), cfg);
}
}
和
package com.cnblogs.htynkn;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
publicclass Main {
publicstaticvoidmain(String[] args) {
LwjglApplicationConfiguration cfg =new LwjglApplicationConfiguration();
cfg.title ="darts-shasha";
cfg.useGL20 =false;
cfg.width =480;
cfg.height =320;
new LwjglApplication(new DartsGame(), cfg);
}
}
新建一个类ShaScreen,实现Screen接口,其中的代码基本和原来的主类一样。唯一的区别就是create中的代码需要移动到show中。
在DartsGame中添加代码
package com.cnblogs.htynkn;
import com.badlogic.gdx.Game;
import com.cnblogs.htynkn.screen.ShaScreen;
publicclass DartsGame extends Game {
@Override
publicvoidcreate() {
ShaScreen screen =new ShaScreen();
this.setScreen(screen);
}
}
这样我们就转化到Game-Screen模式。
当我们在游戏中使用了很多资源的时候直接new的话经常会卡顿,比如我们这个demo再加入音效后进入时间明显变长了。
所以我们这里需要一个预加载过程,而libgdx提供的AssetManager可以实现这个功能。
加载中使用一个小图标加文字形式。由于要使用中文,同时文字量很小,所以使用hiero作图。
新建一个LoadingScreen类作为加载页面。
因为AssetManager的作用很特殊,很多类都可以要调用它,所以我一般使用单例模式。
在DartsGame添加
publicstatic AssetManager manager;
publicstatic AssetManagergetManager() {
if (manager ==null) {
manager =new AssetManager();
}
return manager;
}
在LoadingScreen中通过
AssetManager manager = DartsGame.getManager();
获取manager。然后通过load方法添加要加载的资源
manager.load("audio/background.ogg", Music.class);
manager.load("audio/bing.wav", Sound.class);
manager.load("audio/great.wav", Sound.class);
manager.load("pack/sha/default.pack", TextureAtlas.class);
这里只是告诉manager要加载什么资源,并没有实际加载。
在render方法中调用
DartsGame.getManager().update()
来启动加载并获取是否加载完成,如果返回值为true那么就表明加载完成。
其他类通过
DartsGame.getManager().get()
来获取资源。
LoadingScreen代码如下:
package com.cnblogs.htynkn.screen;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.cnblogs.htynkn.DartsGame;
publicclass LoadingScreen implements Screen {
Game game;
Stage stage;
@Override
publicvoidrender(float delta) {
Gdx.gl.glClearColor(0,0,0,1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
if (DartsGame.getManager().update()) {
game.setScreen(new ShaScreen());
}
stage.act();
stage.draw();
}
@Override
publicvoidresize(int width,int height) {
// TODO Auto-generated method stub
}
@Override
publicvoidshow() {
AssetManager manager = DartsGame.getManager();
manager.load("audio/background.ogg", Music.class);
manager.load("audio/bing.wav", Sound.class);
manager.load("audio/great.wav", Sound.class);
manager.load("pack/sha/default.pack", TextureAtlas.class);
stage =new Stage(480,320,true);
BitmapFont font =new BitmapFont(
Gdx.files.internal("pack/loading/font.fnt"),false);
LabelStyle labelStyle =new LabelStyle(font, Color.WHITE);
Label label =new Label("游戏加载中...", labelStyle);
label.setPosition(160,150);
stage.addActor(label);
Image image =new Image(
new TextureAtlas(Gdx.files
.internal("pack/loading/default.pack"))
.findRegion("ninja_attack"));
image.setOrigin(image.getWidth() /2, image.getHeight() /2);
image.addAction(Actions.repeat(1000, Actions.rotateBy(360,3f)));
image.setPosition(100,140);
stage.addActor(image);
}
@Override
publicvoidhide() {
// TODO Auto-generated method stub
}
@Override
publicvoidpause() {
// TODO Auto-generated method stub
}
@Override
publicvoidresume() {
// TODO Auto-generated method stub
}
@Override
publicvoiddispose() {
// TODO Auto-generated method stub
}
publicLoadingScreen(Game game) {
this.game = game;
}
}
效果如下:
当我们不需要某个资源时通过
manager.unload
来销毁。或者使用
manager.clear();
来清空所有资源。
添加友盟统计
统计功能对于一个应用是必须的。你可以获取到用户的信息,比如分辨率,系统版本,还可以快速获取到错误等等。
libgdx是一个游戏框架,没有自带的统计功能,这里我选用友盟统计。
首先申请key
申请完成以后获取Appkey并下载SDK,拷贝到android项目的libs文件夹中。
在AndroidManifest.xml中添加相关信息。
详细的情况参考友盟的文档。
现在来看一下友盟文档,最常用的是
MobclickAgent.onResume(this);
MobclickAgent.onPause(this);
为了方便开发,我们新建一个接口IStatisticsService。
package com.cnblogs.htynkn.extension;
publicinterface IStatisticsService {
void onResume();
void onPause();
}
然后在DartsGame类添加
publicstatic IStatisticsService statisticsService;
然后在Android项目中添加AndroidStatisticsService
package com.cnblogs.htynkn.extension;
import android.content.Context;
import com.umeng.analytics.MobclickAgent;
publicclass AndroidStatisticsService implements IStatisticsService {
Context context;
publicAndroidStatisticsService(Context context) {
this.context = context;
}
@Override
publicvoidonResume() {
MobclickAgent.onResume(context);
}
@Override
publicvoidonPause() {
MobclickAgent.onPause(context);
}
}
修改入口文件为
package com.cnblogs.htynkn;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.cnblogs.htynkn.extension.AndroidStatisticsService;
publicclass MainActivity extends AndroidApplication {
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg =new AndroidApplicationConfiguration();
cfg.useGL20 =false;
DartsGame dartsGame =new DartsGame();
DartsGame.setStatisticsService(new AndroidStatisticsService(this));
initialize(dartsGame, cfg);
}
}
同样的,在桌面项目中添加DesktopStatisticsService
package com.cnblogs.htynkn.extension;
import com.badlogic.gdx.Gdx;
publicclass DesktopStatisticsService implements IStatisticsService{
@Override
publicvoidonResume() {
Gdx.app.log("StatisticsService","onResume");
}
@Override
publicvoidonPause() {
Gdx.app.log("StatisticsService","onPause");
}
}
修改入口文件
package com.cnblogs.htynkn;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.cnblogs.htynkn.extension.DesktopStatisticsService;
publicclass Main {
publicstaticvoidmain(String[] args) {
LwjglApplicationConfiguration cfg =new LwjglApplicationConfiguration();
cfg.title ="飞镖杀杀";
cfg.useGL20 =false;
cfg.width =480;
cfg.height =320;
DartsGame.setStatisticsService(new DesktopStatisticsService());
new LwjglApplication(new DartsGame(), cfg);
}
}
因为桌面项目并没有统计功能,所以以输出log替代。
然后在游戏相应位置调用即可。
其他需要的功能办法基本相同,就是实现相应接口,然后不同的平台传入不同实现。没有实现的就用mock输出。
依照这种方法还可以添加其他第三方功能。
不过很遗憾友盟SDK升级以后我死活用不上了…现在换成百度APP统计了。原理是一样的,具体参考源码。
比如在Android的启动文件中重写onPause和onResume
package com.cnblogs.htynkn;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.cnblogs.htynkn.extension.AndroidStatisticsService;
publicclass MainActivity extends AndroidApplication {
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg =new AndroidApplicationConfiguration();
cfg.useGL20 =false;
DartsGame dartsGame =new DartsGame();
DartsGame.setStatisticsService(new AndroidStatisticsService(this));
initialize(dartsGame, cfg);
}
@Override
protectedvoidonResume() {
super.onResume();
DartsGame.getStatisticsService().onResume();
}
@Override
protectedvoidonPause() {
super.onPause();
DartsGame.getStatisticsService().onPause();
}
}
统计结果
我还实现了其他方法,比如事件记录等等。
说实话,友盟的统计比百度的好很多,但是不知为嘛我用不起了。
写在最后
本来这一篇写好很久了,但是我一直想加入一个菜单和游戏结束的界面,不过最近实在没有时间,先发出来这个部分吧。
如果有时间以后会补上的。
Github仓库地址:https://github.com/htynkn/DartsShaSha 对应的tag是page3。
apk下载地址:http://pan.baidu.com/share/link?shareid=385272&uk=4127624209
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2013/03/17/libgdx-game-3/