`

(12)、andengine之PathModifier一个j精灵在屏幕四周循环跑动

阅读更多

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.modifier.PathModifier;
import org.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.andengine.entity.modifier.PathModifier.Path;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.RepeatingSpriteBackground;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.source.AssetBitmapTextureAtlasSource;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.modifier.ease.EaseSineInOut;

import android.util.DisplayMetrics;
/**
 * 这是一个路径修改器配合动画精灵的例子,我准备分两块来说明,一个是路径修改器的构成;一个是动画精灵的构成。最后达到的效果是一个小人在屏幕四周循环跑动。
 * 路径修改器中定义内部类Path,用于记录路径上的各个点坐标,PathModifier根据坐标生成MoveModifier,完成每两点的移动,
 * 一系列的MoveModifier放入一个顺序容器就完成了物体的移动。
 * 这种移动是没有与动画集成的,但是每完成两个点(Path中设置的点)的移动就回调IPathModifierListener监听中的onPathWaypointStarted方法,
 * 于是可以在其中判断动画经理播放的动画。 
 * 动画精灵AnimatedSprite是一种特殊的TiledSprite。
 * TiledSprite将同一个纹理切分为多个方形的显示区域,通过设置索引确定应该显示哪个区域。
 * AnimatedSprite中按照指定时间、指定顺序变换TiledSprite的索引,完成动画的功能。
 * 好了两个重要的部件已经介绍清楚了,程序中合并了两个部件完成人物的行走
 */
public class PathModifierActivity extends SimpleBaseGameActivity
{
 private static int winWidth = 854;
 private static int winHeight = 480;
 
 private BitmapTextureAtlas mBitmapTextureAtlas;
 private TiledTextureRegion mTiledTextureRegion;
 
 //拼接的资源背景
 private RepeatingSpriteBackground mRepeatingSpriteBackground;

 @Override
 public EngineOptions onCreateEngineOptions()
 {
  setScreenDisplay();
  Camera camera = new Camera(0, 0, winWidth, winHeight);
  return new EngineOptions
  (
   true,
   ScreenOrientation.LANDSCAPE_FIXED,
   new RatioResolutionPolicy(winWidth, winHeight),
   camera
  );
 }

 @Override
 protected void onCreateResources()
 {
  BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("images/");
  /*
   * 拼接的资源路径背景
   * RepeatingSpriteBackground用来生成一个重复块的背景;
   * AssetBitmapTextureAtlasSource的构造参数pAssetPath应指明根目录gfx/background_grass.png才行
   */
  mRepeatingSpriteBackground = new RepeatingSpriteBackground
    (
     winWidth,
     winHeight,
     this.getTextureManager(),
     AssetBitmapTextureAtlasSource.create(this.getAssets(), "images/background_grass.png"),
     this.getVertexBufferObjectManager()
    );
  
  mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 128, 128, TextureOptions.DEFAULT);
  mTiledTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, this, "player.png", 0, 0, 3, 4);
  mBitmapTextureAtlas.load();
  
 }

 @Override
 protected Scene onCreateScene()
 {
  this.mEngine.registerUpdateHandler(new FPSLogger());
  Scene scene = new Scene();
  
  scene.setBackground(mRepeatingSpriteBackground);
  
  //精灵默认大小为24x32
 // AnimatedSprite player = new AnimatedSprite(10, 10, mTiledTextureRegion, this.getVertexBufferObjectManager());
  //将精灵的大小设置为48x64
  AnimatedSprite player = new AnimatedSprite(10, 10, 48,64,mTiledTextureRegion, this.getVertexBufferObjectManager());
  /*
   * 创建1条封闭路径共为5个坐标,后面为路径具体路线
   * 其中没两个相连的点连成一条线
   */
  Path path = new Path(5);
  path.to(10, 10)
   .to(10, winHeight-10-player.getHeight())
   .to(winWidth-10-player.getWidth(), winHeight-10-player.getHeight())
   .to(winWidth-10-player.getWidth(), 10)
   .to(10, 10);

  LoopEntityModifier loopEntityModifier = new LoopEntityModifier
  (
   //30秒钟刚好走完path指定的路径
   new PathModifier
   (
    30,
    path,
    null,
    new PathModifierListener(player),
    /*
     * PathModifier的最后一个参数我还不是很理解,IEaseModifier在构建Pathmodifier的时候被当作参数传递给控制每段Path运动的MoveModifier。
     * 每次更新调用onManagedUpdate时都会调用重载的onSetValues函数,设置实体的位置,具体调用在BaseSingleValueSpanModifier里。
     * (1)、EaseSineInOut方法:
     * public float getPercentage(final float pSecondsElapsed, final float pDuration)
     * {
     *   //已经过的时间占总时间的百分比,取值[0,1],线性趋势。
     *   final float percentage = pSecondsElapsed / pDuration;
     *   //简化为(1-cos(PI* percentage))/2,取值[0,1],但变化趋势是余弦曲线。
     *   return -0.5f * (FloatMath.cos(percentage * PI) - 1);
     * }
     * 可见这个函数用在这里是为了控制英雄在每段Path上的移动速度,并非匀速而是按余弦曲线递增的;
     * 出现每一段路径都会先加速后减速的效果
     *
     * (2)、EaseLinear:匀速移动
     */
    EaseSineInOut.getInstance()
   )
  );
  
  //注册实体修改器
  player.registerEntityModifier(loopEntityModifier);
  
  scene.attachChild(player);
  
  return scene;
 }
 /**
  * 路径修改的监听器
  * 每完成两个点(Path中设置的点)的移动就回调IPathModifierListener监听中的onPathWaypointStarted方法
  */
 private class PathModifierListener implements IPathModifierListener
 {
  private AnimatedSprite animatedSprite;
  
  public PathModifierListener(AnimatedSprite animatedSprite)
  {
   this.animatedSprite = animatedSprite;
  }

  /**
   * 路径(总路径)的开始
   */
  @Override
  public void onPathStarted(final PathModifier pPathModifier, final IEntity pEntity)
  {
   System.out.println("PathModifierListener::onPathStarted()");
  }

  /**
   *  每一段(两点的连线)路径的开始
   *  当Path中两点移动开始时调用,其中pWaypointIndex表示Path中的第几段  
   *  每相连的两个点决定一段
   */
  @Override
  public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex)
  {
   System.out.println("第"+pWaypointIndex+"段");
   System.out.println("PathModifierListener::onPathWaypointStarted()");
   // pWaypointIndex  第几段路径
   switch (pWaypointIndex)
   {
    case 0:
     /*
      *long[] pFrameDurations :每帧动画的播放时间长度
      *int pFirstTileIndex  :从第几帧开始播放
      *int pLastTileIndex  :第几帧结束
      *boolean pLoop    :是否循环播放
      */
     animatedSprite.animate(new long[]{200,200,200}, 6, 8, true);
     break;
    case 1:
     animatedSprite.animate(new long[]{200,200,200}, 3, 5, true);
     break;
    case 2:
     animatedSprite.animate(new long[]{200,200,200}, 0, 2, true);
     break;
    case 3:
     animatedSprite.animate(new long[]{200,200,200}, 9, 11, true);
     break;
   }
  }
  /**
   * 每一段(两点的连线)路径的结束
   */
  @Override
  public void onPathWaypointFinished(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex)
  {
   System.out.println("PathModifierListener::onPathWaypointFinished()");
  }

  /**
   * 路径(总路径)的结束
   */
  @Override
  public void onPathFinished(final PathModifier pPathModifier, final IEntity pEntity)
  {
   System.out.println("PathModifierListener::onPathFinished()");
  }
  
 }
 

 /**
  * 设置屏幕大小
  */
 private void setScreenDisplay()
 {
  DisplayMetrics displayMetrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
  winWidth = displayMetrics.widthPixels;
  winHeight = displayMetrics.heightPixels;
 }

}

分享到:
评论

相关推荐

    AndEngine PathModifier

    基于AndEngine 游戏引擎的例子PathModifier,走动的游戏人物

    AndEngine进阶之自定义Tiled精灵

    AndEngine游戏引擎进阶之自定义Tiled精灵,AndEngine游戏引擎是一个开源的Android 2D游戏引擎。

    andengine封装动画精灵类

    封装了个andengine的动画精灵类,可以直接传入多张小图片的名称,直接生成动画精灵

    andengine背景滚动循环

    andengine背景滚动循环。背景循环AutoParallaxBackground

    一个关于andengine中精灵 动作的简单例子

    我根据andengine文档和网上的例子,自己加工在androidstadio上运行代码中有我照着文档写的例子,根据自己理解做了一点注释,希望对新人有帮助

    AndEngine 精灵场景坐标转换

    在制作动画精灵的时候,为了方便计算,常常需要把场景中的坐标转换为精灵的内部坐标,或者需要把精灵的内部坐标转换为场景坐标.如果精灵没有进行过旋转操作,他们之间只差 一个offse而已

    Andengine笔记

    在Rokon(另一个Android 2D游戏引擎)宣布停止更新以后,AndEngine成为Android最为流行的2D游戏引擎。  相较Libgdx引擎:AndEngine拥有更多的游戏组件与扩展功能;并且它在默认情况下已经可以支持中文;采用屏幕坐标...

    AndEngine下载

    AndEngine下载 AndEngine

    andengine 类代码组织图

     AndEngine是一个开源项目。这使得开发者在遇到问题时可以直接从源码上找到答案,也能按照自己的需要对AndEngine进行修改和扩展。AndEngine的源码在github上托管[2]。 高效  AndEngine主要使用Java语言开发,但在...

    AndEngine 类 组织图

     AndEngine是一个开源项目。这使得开发者在遇到问题时可以直接从源码上找到答案,也能按照自己的需要对AndEngine进行修改和扩展。AndEngine的源码在github上托管[2]。 高效  AndEngine主要使用Java语言开发,但在...

    andengine2.0开发的小游戏

    利用andengine2.0开发的一款小游戏,有兴趣的朋友可以研究下。

    使用AndEngine的一个DEMO

    使用AndEngine的一个DEMO,可以完美运行

    andengine 中文

    andengine 中文文档

    andEngine实例源码

    andEngine实例源码

    AndEngine最新jar包

    AndEngine最新jar包 AndEngine最新jar包 AndEngine最新jar包

    andengine源码及demo

    andengine源码,源码扩展及demo,供14个project

    android andengine 代码 AnimatedSprite 实例

    android andengine 代码 AnimatedSprite 实例 大家一起学习android andengine 游戏开发吧

    AndEngine游戏开发示例

    AndEngine游戏开发示例 详情请链接至:http://blog.csdn.net/lan410812571/article/details/9716743

    Packt.AndEngine.for.Android.Game.Development

    在Rokon(另一个Android 2D游戏引擎)宣布停止更新以后,AndEngine成为Android最为流行的2D游戏引擎。 相较Libgdx引擎:AndEngine拥有更多的游戏组件与扩展功能;并且它在默认情况下已经可以支持中文;采用屏幕坐标系...

    andengine example

    这是andengine引擎官方提供的一个示例app,里面包含了引擎的许多方面的例子,例如物理系统、粒子系统、声音系统、碰撞检测等,效果特别绚。

Global site tag (gtag.js) - Google Analytics