[AndEngine学习教程] 第4节 制作人物动画
2013-03-08 10:47
393 查看
转自:/article/8024907.html
1.回顾
在上一节我们制作一个可以变幻的图形,这节将基于上一节的内容,制作一个行走的人物动画.在这里就称它为战士吧!呵呵!!!!
2.新使用到的资源
1.RepeatingSpriteBackground 游戏场景中使用到的背景绘制策略,本节中使用到草坪背景,由于背景大小是可以自动调节的,
不可能绘制一张固定大小的图片来作为背景.一方面占用空间大不说,另一方面背景图片经过缩放后效果也不好
2.PathModifier 为战士设定行走路径.需要说明的是:这里的路径是两点间的直线路径.比如只需要设定起点和终点.战士就会
沿着这两点间的直线进行移动
3.源代码陈述
1.关于RepeatingSpriteBackground ,这是一种重复绘制背景图片的策略,此类继承于SpriteBackground ,有两个构造函数:
[java]
view plaincopyprint?
/**
* @param pCameraWidth
* @param pCameraHeight
* @param pTextureManager
* @param pBitmapTextureAtlasSource needs to be a power of two as otherwise the <code>repeating</code> feature doesn't work.
*/
public RepeatingSpriteBackground(finalfloat pCameraWidth,
finalfloat pCameraHeight,
final TextureManager pTextureManager,final IBitmapTextureAt lasSource pBitmapTextureAtlasSource,final VertexBufferObjectManager pVertexBufferObjectManager)throws
IllegalArgumentException {
this(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource,1, pVertexBufferObjectManager);
}
public RepeatingSpriteBackground(finalfloat pCameraWidth,
finalfloat pCameraHeight,
final TextureManager pTextureManager,final IBitmapTextureAt lasSource pBitmapTextureAtlasSource,final
float pScale,final VertexBufferObjectManager pVertexBufferObjectManager)throws IllegalArgumentException {
super(null);
this.mScale = pScale;
this.mEntity =
this.loadSprite(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource, pVertexBufferObjectManager);
}
本例子中使用到的是第一种构造函数,实现形式如下:
[java]
view plaincopyprint?
private
static finalint CAMERA_WIDTH=800;
private staticfinal
int CAMERA_HEIGHT=480;
private Camera mCamera;
private RepeatingSpriteBackground mGrassBackground;
private TiledTextureRegion mPlayerTextureRegion;
private BitmapTextureAtlas mTexture;
@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
mCamera = new Camera(0,0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true,ScreenOrientation.LANDSCAPE_SENSOR,new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),
mCamera);
return engineOptions;
}
@Override
public void onCreateResources(
OnCreateResourcesCallback pOnCreateResourcesCallback)
throws Exception {
// TODO Auto-generated method stub
this.mTexture =
new BitmapTextureAtlas(getTextureManager(),
128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture,this,"player.png",0,0,3,4);
this.mGrassBackground =new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, getTextureManager(), AssetBitmapTextureAtlasSource.create(getAssets(),"background_grass.png"),
getVertexBufferObjectManager());
mTexture.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
然后在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)函数中实现
[java]
view plaincopyprint?
Scene mScene = new Scene();
mScene.setBackground(mGrassBackground);
pOnCreateSceneCallback.onCreateSceneFinished(mScene);
这样就把重复是的背景放置完成.
3.重点介绍
本例中用到一个72x128大小,3列4行的精灵战士
因此动画的创建方式为:
[java]
view plaincopyprint?
final AnimatedSprite player =new AnimatedSprite(10,10,
48,64, mPlayerTextureRegion, getVertexBufferObjectManager());
mScene.attachChild(player);
这样就把战士般到了屏幕上,但是此时,战士还不会动,为了让它动起来可要花费点力气的.呵呵!.有什么办法呢?就是给战士注册监听实体,
由于本例子要求的是战士按照设定路径移动,自然想到AndEngine中的Path类,定义一个可以围绕整个屏幕的path路线:
[java]
view plaincopyprint?
final Path path =
new Path(5).to(10,10).to(10, CAMERA_HEIGHT -74).to(CAMERA_WIDTH-58,
CAMERA_HEIGHT -74).to(CAMERA_WIDTH-58,10).to(10,10);
每个to函数为Path添加一个路径,最终形成一个从屏幕左上角->左下角->右下角->右上角->左上角的封闭路径.
有了以上基础,当然是添加基于Path类修改器啦.
[java]
view plaincopyprint?
PathModifier pathModifier = new PathModifier(30.0f, path,new IPathModifierListener(){
@Override
public void onPathStarted(PathModifier pPathModifier,
IEntity pEntity) {
// TODO Auto-generated method stub
}
@Override
public void onPathWaypointStarted(PathModifier pPathModifier,
IEntity pEntity, int pWaypointIndex) {
// TODO Auto-generated method stub
switch(pWaypointIndex) {
case 0:
player.animate(new long[]{200,200,
200},6,
8,true);
break;
case 1:
player.animate(newlong[]{200,200,
200},3,
5,true);
break;
case 2:
player.animate(new long[]{200,200,
200},0,
2,true);
break;
case 3:
player.animate(newlong[]{200,200,
200},9,
11,true);
break;
}
}
@Override
public void onPathWaypointFinished(PathModifier pPathModifier,
IEntity pEntity, int pWaypointIndex) {
// TODO Auto-generated method stub
}
@Override
public void onPathFinished(PathModifier pPathModifier,
IEntity pEntity) {
// TODO Auto-generated method stub
}
},EaseSineInOut.getInstance());
战士行走动作的变化是一个基础动画,所以需要Animate方法.但是战士在每个位置脸朝向不一样的,所以到了每个拐点的开始处都
需要修改动画的脸部朝向,这样就更加逼真点.从图片可以看出他们的对应关系.需要说明的是player.animate()函数:
[java]
view plaincopyprint?
public void animate(finallong[] pFrameDurations,
finalint pFirstTileIndex,
finalint pLastTileIndex,
finalboolean pLoop) {
this.animate(pFrameDurations, pFirstTileIndex, pLastTileIndex, pLoop,null);
}
各个参数的含义为:(战士图片中可以看出:有4组动作,每组动作为3个画面)
pFrameDurations:连续播放3个画面,三个long数据为每个动画的播放时间间隔,单位为毫秒;
pFirstTileIndex:动画的其起始列,按照"Z"字形排列计数.
pLastTileIndex:动画的结束序列,按照"Z"字形排列计数.
pLoop:是否循环播放
为了让战士行走路径也能循环,在PathModifier的基础上增加LoopEntityModifier
[java]
view plaincopyprint?
LoopEntityModifier loopModifier = new LoopEntityModifier(pathModifier, -1);
有了loopModifier,当然是把它绑定到player上啦
[java]
view plaincopyprint?
player.registerEntityModifier(loopModifier);
至此,整个设计任务完成了,下面看看运行的结果图片:
本例子源代码:http://download.csdn.net/detail/cen616899547/4705911
1.回顾
在上一节我们制作一个可以变幻的图形,这节将基于上一节的内容,制作一个行走的人物动画.在这里就称它为战士吧!呵呵!!!!
2.新使用到的资源
1.RepeatingSpriteBackground 游戏场景中使用到的背景绘制策略,本节中使用到草坪背景,由于背景大小是可以自动调节的,
不可能绘制一张固定大小的图片来作为背景.一方面占用空间大不说,另一方面背景图片经过缩放后效果也不好
2.PathModifier 为战士设定行走路径.需要说明的是:这里的路径是两点间的直线路径.比如只需要设定起点和终点.战士就会
沿着这两点间的直线进行移动
3.源代码陈述
1.关于RepeatingSpriteBackground ,这是一种重复绘制背景图片的策略,此类继承于SpriteBackground ,有两个构造函数:
[java]
view plaincopyprint?
/**
* @param pCameraWidth
* @param pCameraHeight
* @param pTextureManager
* @param pBitmapTextureAtlasSource needs to be a power of two as otherwise the <code>repeating</code> feature doesn't work.
*/
public RepeatingSpriteBackground(finalfloat pCameraWidth,
finalfloat pCameraHeight,
final TextureManager pTextureManager,final IBitmapTextureAt lasSource pBitmapTextureAtlasSource,final VertexBufferObjectManager pVertexBufferObjectManager)throws
IllegalArgumentException {
this(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource,1, pVertexBufferObjectManager);
}
public RepeatingSpriteBackground(finalfloat pCameraWidth,
finalfloat pCameraHeight,
final TextureManager pTextureManager,final IBitmapTextureAt lasSource pBitmapTextureAtlasSource,final
float pScale,final VertexBufferObjectManager pVertexBufferObjectManager)throws IllegalArgumentException {
super(null);
this.mScale = pScale;
this.mEntity =
this.loadSprite(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource, pVertexBufferObjectManager);
}
/** * @param pCameraWidth * @param pCameraHeight * @param pTextureManager * @param pBitmapTextureAtlasSource needs to be a power of two as otherwise the <code>repeating</code> feature doesn't work. */ public RepeatingSpriteBackground(final float pCameraWidth, final float pCameraHeight, final TextureManager pTextureManager, final IBitmapTextureAt lasSource pBitmapTextureAtlasSource, final VertexBufferObjectManager pVertexBufferObjectManager) throws IllegalArgumentException { this(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource, 1, pVertexBufferObjectManager); } public RepeatingSpriteBackground(final float pCameraWidth, final float pCameraHeight, final TextureManager pTextureManager, final IBitmapTextureAt lasSource pBitmapTextureAtlasSource, final float pScale, final VertexBufferObjectManager pVertexBufferObjectManager) throws IllegalArgumentException { super(null); this.mScale = pScale; this.mEntity = this.loadSprite(pCameraWidth, pCameraHeight, pTextureManager, pBitmapTextureAtlasSource, pVertexBufferObjectManager); }
本例子中使用到的是第一种构造函数,实现形式如下:
[java]
view plaincopyprint?
private
static finalint CAMERA_WIDTH=800;
private staticfinal
int CAMERA_HEIGHT=480;
private Camera mCamera;
private RepeatingSpriteBackground mGrassBackground;
private TiledTextureRegion mPlayerTextureRegion;
private BitmapTextureAtlas mTexture;
@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
mCamera = new Camera(0,0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true,ScreenOrientation.LANDSCAPE_SENSOR,new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),
mCamera);
return engineOptions;
}
@Override
public void onCreateResources(
OnCreateResourcesCallback pOnCreateResourcesCallback)
throws Exception {
// TODO Auto-generated method stub
this.mTexture =
new BitmapTextureAtlas(getTextureManager(),
128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture,this,"player.png",0,0,3,4);
this.mGrassBackground =new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, getTextureManager(), AssetBitmapTextureAtlasSource.create(getAssets(),"background_grass.png"),
getVertexBufferObjectManager());
mTexture.load();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
private static final int CAMERA_WIDTH=800; private static final int CAMERA_HEIGHT=480; private Camera mCamera; private RepeatingSpriteBackground mGrassBackground; private TiledTextureRegion mPlayerTextureRegion; private BitmapTextureAtlas mTexture; @Override public EngineOptions onCreateEngineOptions() { // TODO Auto-generated method stub mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); EngineOptions engineOptions = new EngineOptions(true,ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT), mCamera); return engineOptions; } @Override public void onCreateResources( OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception { // TODO Auto-generated method stub this.mTexture = new BitmapTextureAtlas(getTextureManager(), 128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA); this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this,"player.png", 0,0,3, 4); this.mGrassBackground = new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, getTextureManager(), AssetBitmapTextureAtlasSource.create(getAssets(), "background_grass.png"), getVertexBufferObjectManager()); mTexture.load(); pOnCreateResourcesCallback.onCreateResourcesFinished(); }
然后在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)函数中实现
[java]
view plaincopyprint?
Scene mScene = new Scene();
mScene.setBackground(mGrassBackground);
pOnCreateSceneCallback.onCreateSceneFinished(mScene);
Scene mScene = new Scene(); mScene.setBackground(mGrassBackground); pOnCreateSceneCallback.onCreateSceneFinished(mScene);
这样就把重复是的背景放置完成.
3.重点介绍
本例中用到一个72x128大小,3列4行的精灵战士
因此动画的创建方式为:
[java]
view plaincopyprint?
final AnimatedSprite player =new AnimatedSprite(10,10,
48,64, mPlayerTextureRegion, getVertexBufferObjectManager());
mScene.attachChild(player);
final AnimatedSprite player = new AnimatedSprite(10, 10, 48, 64, mPlayerTextureRegion, getVertexBufferObjectManager()); mScene.attachChild(player);
这样就把战士般到了屏幕上,但是此时,战士还不会动,为了让它动起来可要花费点力气的.呵呵!.有什么办法呢?就是给战士注册监听实体,
由于本例子要求的是战士按照设定路径移动,自然想到AndEngine中的Path类,定义一个可以围绕整个屏幕的path路线:
[java]
view plaincopyprint?
final Path path =
new Path(5).to(10,10).to(10, CAMERA_HEIGHT -74).to(CAMERA_WIDTH-58,
CAMERA_HEIGHT -74).to(CAMERA_WIDTH-58,10).to(10,10);
final Path path = new Path(5).to(10, 10).to(10, CAMERA_HEIGHT - 74).to(CAMERA_WIDTH-58, CAMERA_HEIGHT - 74).to(CAMERA_WIDTH-58, 10).to(10, 10);
每个to函数为Path添加一个路径,最终形成一个从屏幕左上角->左下角->右下角->右上角->左上角的封闭路径.
有了以上基础,当然是添加基于Path类修改器啦.
[java]
view plaincopyprint?
PathModifier pathModifier = new PathModifier(30.0f, path,new IPathModifierListener(){
@Override
public void onPathStarted(PathModifier pPathModifier,
IEntity pEntity) {
// TODO Auto-generated method stub
}
@Override
public void onPathWaypointStarted(PathModifier pPathModifier,
IEntity pEntity, int pWaypointIndex) {
// TODO Auto-generated method stub
switch(pWaypointIndex) {
case 0:
player.animate(new long[]{200,200,
200},6,
8,true);
break;
case 1:
player.animate(newlong[]{200,200,
200},3,
5,true);
break;
case 2:
player.animate(new long[]{200,200,
200},0,
2,true);
break;
case 3:
player.animate(newlong[]{200,200,
200},9,
11,true);
break;
}
}
@Override
public void onPathWaypointFinished(PathModifier pPathModifier,
IEntity pEntity, int pWaypointIndex) {
// TODO Auto-generated method stub
}
@Override
public void onPathFinished(PathModifier pPathModifier,
IEntity pEntity) {
// TODO Auto-generated method stub
}
},EaseSineInOut.getInstance());
PathModifier pathModifier = new PathModifier(30.0f, path, new IPathModifierListener(){ @Override public void onPathStarted(PathModifier pPathModifier, IEntity pEntity) { // TODO Auto-generated method stub } @Override public void onPathWaypointStarted(PathModifier pPathModifier, IEntity pEntity, int pWaypointIndex) { // TODO Auto-generated method stub switch(pWaypointIndex) { case 0: player.animate(new long[]{200, 200, 200}, 6, 8, true); break; case 1: player.animate(new long[]{200, 200, 200}, 3, 5, true); break; case 2: player.animate(new long[]{200, 200, 200}, 0, 2, true); break; case 3: player.animate(new long[]{200, 200, 200}, 9, 11, true); break; } } @Override public void onPathWaypointFinished(PathModifier pPathModifier, IEntity pEntity, int pWaypointIndex) { // TODO Auto-generated method stub } @Override public void onPathFinished(PathModifier pPathModifier, IEntity pEntity) { // TODO Auto-generated method stub } },EaseSineInOut.getInstance());
战士行走动作的变化是一个基础动画,所以需要Animate方法.但是战士在每个位置脸朝向不一样的,所以到了每个拐点的开始处都
需要修改动画的脸部朝向,这样就更加逼真点.从图片可以看出他们的对应关系.需要说明的是player.animate()函数:
[java]
view plaincopyprint?
public void animate(finallong[] pFrameDurations,
finalint pFirstTileIndex,
finalint pLastTileIndex,
finalboolean pLoop) {
this.animate(pFrameDurations, pFirstTileIndex, pLastTileIndex, pLoop,null);
}
public void animate(final long[] pFrameDurations, final int pFirstTileIndex, final int pLastTileIndex, final boolean pLoop) { this.animate(pFrameDurations, pFirstTileIndex, pLastTileIndex, pLoop, null); }
各个参数的含义为:(战士图片中可以看出:有4组动作,每组动作为3个画面)
pFrameDurations:连续播放3个画面,三个long数据为每个动画的播放时间间隔,单位为毫秒;
pFirstTileIndex:动画的其起始列,按照"Z"字形排列计数.
pLastTileIndex:动画的结束序列,按照"Z"字形排列计数.
pLoop:是否循环播放
为了让战士行走路径也能循环,在PathModifier的基础上增加LoopEntityModifier
[java]
view plaincopyprint?
LoopEntityModifier loopModifier = new LoopEntityModifier(pathModifier, -1);
LoopEntityModifier loopModifier = new LoopEntityModifier(pathModifier, -1);
有了loopModifier,当然是把它绑定到player上啦
[java]
view plaincopyprint?
player.registerEntityModifier(loopModifier);
player.registerEntityModifier(loopModifier);
至此,整个设计任务完成了,下面看看运行的结果图片:
本例子源代码:http://download.csdn.net/detail/cen616899547/4705911
相关文章推荐
- (转)[AndEngine学习教程] 第4节 制作人物动画
- [AndEngine学习教程] 第4节 制作人物动画
- IOS UI学习教程之使用UIImageView控件制作动画
- MFC学习笔记之二(制作人物动画+人物移动+地图拖曳)
- 学习用CSS3制作50个超棒动画效果教程
- [AndEngine学习教程] 第3节 使用Modifier修改动画
- [AndEngine学习教程] 第3节 使用Modifier修改动画
- (转)[AndEngine学习教程] 第3节 使用Modifier修改动画
- DAZ Studio for Mac(3D三维人物动画制作软件)附DAZStudio注册码和破解教程 V4.10.0.123已注册版
- 视频专辑:轻松学习flash动画制作视频教程
- Maya 变形金刚 制作 中文视频教程教程 大黄蜂 动画
- [3dmax教程] 人物+骨骼+蒙皮+动画教程
- Flash动画制作视频教程
- [转]Ultra Fractal教程系列44——动画功能的使用02——制作一个缩放动画
- 【Unity&DragonBones】像素角色人物骨骼动画教程(四)蒙皮骨骼动画使得角色动作更流畅
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十三)制作游戏主菜单面板及鼠标左右键快捷技能栏
- ☆☆☆☆☆全面武装你的MS,开机动画制作教程☆☆☆☆☆☆
- Flash动画教程学习(一)--动画基础
- [AndEngine学习教程] 第6节 模拟手柄控制器
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(五)实现2D人物动画②