-
Notifications
You must be signed in to change notification settings - Fork 115
Quick Start
由于框架全部使用SurfaceView进行绘制,不使用诸如Button、Layout等原生控件,所以应该首先新建类继承引擎核心类Engine,负责游戏的流程,注释中已有明确的标明功能。
public class Game extends Engine {
// 一般在构造函数完成变量的初始化
public Game() {
// 控制debug模式是否开始,debug模式打印日志、帧数、pause次数等信息
super(true);
}
// 载入一些UI参数和设置屏幕放向,默认背景色,设定屏幕的扫描方式等
@Override
public void init() {
// 初始化UI默认参数,必须调用该方法,其中有一些用于多机型适配的参数需要初始化
UIdefaultData.init(this);
}
// 通常用于精灵,背景,图片等物体的设置和载入
@Override
public void load() {
}
// draw 和 update 在线程中进行不断的循环刷新
// draw 负责绘制 update 负责更新数据和对象信息
@Override
public void draw() {
}
@Override
public void update() {
}
// 将touch 事件传回 功能和所设定的屏幕扫描方式有关
@Override
public void touch(MotionEvent event) {
}
// 将碰撞事件传回 传回精灵和物品的基类
// 用于处理碰撞事件 默认使用矩形碰撞
@Override
public void collision(BaseSub baseSub) {
}
}
使用GamePrinter进行文字绘制,除此以外还有多种方法绘制:
@Override
public void draw() {
Canvas canvas = getCanvas();
GameTextPrinter printer = new GameTextPrinter(canvas);
printer.drawText("哈哈哈", 100, 100);
}
效果图:
建议图片存放在Asset中:
GameTexture texture = new GameTexture(this);
texture.loadFromAsset("pic/logo.jpg")
texture.draw(canvas, 100, 100);
效果图:
另外也可使用loadFromAssetStripFrame
从一个大的图片中取出对应位置的图片。
/**
* get bitmap from a big bitmap
*
* @param filename
* @param x
* @param y
* @param width
* @param height
* @return
*/
public boolean loadFromAssetStripFrame(String filename,
int x, int y,
int width, int height)
比如可以通过这四个参数把这个小飞机取出来:
PicUtils中提供了在Bitmap处理中很有用的各种特效和压缩方法,大家可以一试。
使用精灵可以使用BaseSprite也可以继承该类使用,BaseSprite封装了很多方法供各种动画使用,这些功能很多都是需要结合动画系统来使用的,动画系统会在后面介绍。
1.简单初始化:
sprite = new BaseSprite(this);
2.初始化连续帧动画:
连续帧的初始化需要这样的连续帧图片:
GameTexture texture = new GameTexture(this);
texture.loadFromAsset("pic/zombie.png");
// 长宽以及列数
sprite = new BaseSprite(this, 96, 96, 8);
sprite.setTexture(texture);
sprite.setPosition(100, 100);
sprite.setDipScale(100, 100);
// 帧切换动画是关键
sprite.addAnimation(new FrameAnimation(0, 63, 1));
addToSpriteGroup(sprite);
效果图:
3.使用从大图取出的多帧图片:
// 新建图片资源(此图为上图的大图)
GameTexture texture = new GameTexture(this);
texture.loadFromAsset("pic/shoot.png");
// 初始化设定模式和长宽
ship = new BaseSprite(this, 100, 124, FrameType.COMMON);
// 设定资源
ship.setTexture(texture);
// 从大图中取出两帧
ship.addRectFrame(0, 100, 100, 124);
ship.addRectFrame(167, 361, 100, 124);
ship.addAnimation(new FrameAnimation(0, 1, 1));
效果图(两帧图片不断切换):
4.一些重要的其他设定:
// 图片资源
ship.setTexture(texture);
// 大图取帧模式
ship.addRectFrame(0, 100, 100, 124);
// 设定位置
ship.setPosition(x, y);
// 设置dp大小
ship.setDipScale(96, 96);
// 设定dp位置
ship.setDipPosition(x, y);
// 设定透明度
ship.setAlpha(...);
// 只有将精灵添加到SpriteGroup中框架才会自行绘制,否则需要手动调用
addToSpriteGroup(ship);
...
使用的按钮可以继承BaseButton进行拓展,也可以直接使用TextureButton和TextButton进行使用。
Button设定功能的方式和原生一样,通过设定接口回调的方式进行:
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick() {
Log.e("button", "onClick");
}
});
1.TextureButton:
TextureButton button;
// 初始化并设定名字
button = new TextureButton(this, "logo");
texture = new GameTexture(this);
texture.loadFromAsset("pic/logo.jpg");
// 添加图片资源
button.setTexture(texture);
// button的接口回调,不是View的那个接口
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick() {
Log.e("button", "onClick");
}
});
button.setPosition(200, 300);
button.setDipScale(100, 150);
// 添加到ButtonGroup进行绘制和处理
addToButtonGroup(button);
效果图:
结合PicUtil中的各种Bitmap处理方法可以很容易的做出各种样式的Button:
2.TextButton:
TextButton button;
button = new TextButton(this, "logo");
button.setText("刘丰恺");
addToButtonGroup(button);
// 余略见源码
...
效果图:
目前的动画系统可以使用已经封装好的继承了BaseAnimation的动画,也可以继承BaseAnim进行自我定义动画类进行使用。
AnimType中保存了Animation的应用类型。
Animation | method | function |
---|---|---|
AliveAnimation | adjustAlive(boolean ori) | 碰撞检测的时候进行判断存活状态 |
AlphaAnimation | adjustAlpha(int ori) | 修改物体透明度 |
CircleMoveAnimation | adjustPosition(Float2 ori) | 沿某一圆心进行圆周运动 |
FenceAnimation | adjustPosition(Float2 ori) | 使用围栏动画防止出界 |
FrameAnimation | adjustFrame(int ori) | 逐帧动画 |
MoveAnimation | adjustPosition(Float2 ori) | 位移动画 |
SpinAnimation | adjustRotation(float ori) | 旋转动画 |
ThrobAnimation | adjustScale(Float2 ori) | 跳跃动画 |
VelocityAnimation | adjustPosition/adjustAlive | 线性加速度计 |
WrapMoveAnimation | adjustPosition(Float2 ori) | 围栏动画防止出界 |
ZoomAnimation | adjustScale(Float2 ori) | 放大缩小动画 |
待续 | ... | ... |
绑定动画分为两类,ListAnimation和FixedAnimation,ListAnimation将动画存储到固定的一个List中,用于重复更新的动画, 而FixedAnimation存储在Map中,使用名字进行调用,用于点击或者非自动更新的动画。 比如前面精灵类动画的就是添加到ListAnimation。 下面的这种写法就是FixedAnimation,这个动画是小飞机入场,因为只使用了一次,所以使用了FixedAnimation。
ship.addfixedAnimation("start",
new MoveAnimation(UIdefaultData.centerInHorizontalX - ship.getWidthWithScale() / 2,
UIdefaultData.screenHeight - 2 * ship.getHeightWidthScale(), new Float2(10, 10)));
效果图:
BaseButtonAnimation是BaseButton的动画类继承了BaseAnim的动画基类,通过提供Button的状态,设定Button的动画。
Animation | method | function |
---|---|---|
ZoomCenterButtonAnim | adjustButtonRect(Rect ori,boolean touchType) | 按钮放缩动画 |
ColorAnimation | adjustButtonBackGround(int ori,boolean type) | TextButton点击变色 |
待续 | ... | ... |
为Button设定放缩动画:
// 设定中心放缩
button.setZoomCenter(true);
// 三个参数 初始值/放大值/帧数
button.setAnimation(new ZoomCenterButtonAnim(10, 30, 3));
效果图:
为Button设定颜色动画:
// 初始颜色 / 按下颜色
button.setAnimation(
new ColorAnimation(UIdefaultData.colorAccent,
UIdefaultData.colorPressed));
效果图:
使用设置ID和Name进行物体分组,通过物体分组,框架核心类会对对象进行分类处理。
final int SHIP = 0;
ship.setName("SHIP");
ship.setIdentifier(SHIP);
只要使用了addToSpriteGroup(sprite)
的精灵对象就会自动进行碰撞检测,而对碰撞检测的结果会从
collision
中进行发回。
@Override
public void collision(BaseSub baseSub) {
// 获取与之碰撞的对象
BaseSprite other = (BaseSprite) baseSub.getOffender();
// 获取ID分组处理
if (baseSub.getIdentifier() == BULLET &&
other.getIdentifier() == ENEMY) {
// 设定死亡
other.setAlive(false);
// 回收
removeFromSpriteGroup(other);
addToRecycleGroup(other);
}
}
其中getOffender()
获得与之碰撞的对象,通过getIdentifier()
获取设定的对象分组,实行逻辑判断。
开启Debug模式会看见碰撞线。
效果图:
屏幕扫描模式是用来优先响应屏幕点击、Button点击、和多点触控而设的,放置在不同情况下都能优化屏幕的刷新。
// 检测单一移动
SINGLE,
// 检测Button
BUTTON,
// 多点检测
FULL,
// 单击+Button
SINGLE_BUTTON
并且通过如下方式进行设置:
super.setTouchMode(TouchMode.BUTTON);
-
NetUtils
网络状态工具类 -
PicUtils
图片处理工具类 -
ServiceUtils
服务工具类 -
ImageHelper
图型处理类 -
DisplayUtils
数据转换类 -
SpUtils
Sp简化工具类(可存储list和map
) -
ValidatorsUtils
正则表达式处理类
播放短音效,首先初始化SoundManager
用以加载音效。
// 接收实例和Manager的尺寸
SoundManager manager = new SoundManager(this, 5);
// 从assets加载音频 同时加载路径也会作为音效名进行存储
manager.addSound("mic/open.mid");
// 通过加载名进行播放
manager.play("mic/open.mid");
完成以上步骤就可以播放了,当然尽量只向其中放置较短的音效,如背景音乐的长音频,请见播放音频。
public void removeSound(String musicName) // 移除
public void play(String musicName, float volume) // 播放 + 音量
public boolean containSoundID(int soundID) // 判断音频是否存在
public int getSoundID(String soundName) // 获取ID
...
播放音频适合例如背景音乐一样的音乐。
// 传入两个参数 上下文和文件名
MusicPlayer player = new MusicPlayer(this, "mic/open.mp3");
player.play();
以上的就能实现播放了,下面还有一些其他的方法。
public void dispose() // 清理
public void setLooping(boolean isLooping) // 是否循环
public void setVolume(float volume) // 设定音量
...
从SoundManager
中导入多段音频,快速播放达成音效的效果。
SoundManager manager = new SoundManager(this, 5);
manager.addSound("mic/1.mid");
manager.addSound("mic/2.mid");
SoundPlayer player = new SoundPlayer(manager, 500, 16);
player.addSound("mic/1.mid");
player.addSound("mic/2.mid");
...
使用player.play();
进行播放。