游戏帧动画处理---注释很详细!@hxx

来源:互联网 发布:哈萨克bayge软件下载 编辑:程序博客网 时间:2024/06/18 10:09
package cn.hxx.demo;import java.io.InputStream;import android.R;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.os.Bundle;import android.view.Display;import android.view.KeyEvent;import android.view.View;import android.view.Window;import android.view.WindowManager;public class AnimationActivity extends Activity {AnimView mAnimView=null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);// 全屏显示窗口requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);// 获取屏幕宽高Display display = getWindowManager().getDefaultDisplay();//显示自定义的游戏viewmAnimView = new AnimView(this,display.getWidth(), display.getHeight());setContentView(mAnimView);//在屏幕上显示当前的view } public class AnimView extends View { /**向下移动动画,对应Animation[]的0号元素**/        public final static int ANIM_DOWN = 0;        /**向左移动动画**/        public final static int ANIM_LEFT = 1;        /**向右移动动画**/        public final static int ANIM_RIGHT = 2;        /**向上移动动画**/        public final static int ANIM_UP = 3;        /**动画的总数量**/        public final static int ANIM_COUNT = 4;        //这个搞了两个人的动态效果针        Animation[] mHeroAnim=new Animation[ANIM_COUNT];        Animation[] mTestAnim=new Animation[ANIM_COUNT];//放enemy的                Paint mPaint = null;//画笔来啦        /**任意键被按下**/    private boolean mAllkeyDown = false;    /**按键下**/    private boolean mIskeyDown = false;    /**按键左**/    private boolean mIskeyLeft = false;    /**按键右**/    private boolean mIskeyRight = false;    /**按键上**/    private boolean mIskeyUp = false;    //当前绘制动画状态ID    int mAnimationState = 0;        ////这里没有绘制图片了,直接用了一副完整的场景map.png    Bitmap mMapImage = null;     /**     * 构造方法     *      * @param context     */    public AnimView(Context context,int screenWidth, int screenHeight) {        super(context);        mPaint = new Paint();        //这里和enemy.png所有动作一张图上不一样,这里每一张图示一个动作        //这里可以用循环来处理,总之我们需要把动画的ID传进去        mHeroAnim[ANIM_DOWN] = new Animation(context,new int []{R.drawable.hero_down_a,R.drawable.hero_down_b,R.drawable.hero_down_c,R.drawable.hero_down_d},true);        mHeroAnim[ANIM_UP]=new Animation(context,new int[]{R.drawable.hero_up_a,R.drawable.hero_up_b,R.drawable.hero_up_c,R.drawable.hero_up_d},true);        mHeroAnim[ANIM_LEFT] = new Animation(context,new int []{R.drawable.hero_left_a,R.drawable.hero_left_b,R.drawable.hero_left_c,R.drawable.hero_left_d},true);        mHeroAnim[ANIM_RIGHT]= new Animation(context,new int []{R.drawable.hero_right_a,R.drawable.hero_right_b,R.drawable.hero_right_c,R.drawable.hero_right_d},true);               //利用程序来切割图片,仅仅切割enemy。png即可,因为hero图片不需要切割        /**enemy.png。一排四个图,从左到右画吧==》 x=0开始         * 第一排:向下走。2右走,3左走,4上走         */        Bitmap testmap=readBitMap(context,R.drawable.enemy);        Bitmap[][] bitmap=new Bitmap[ANIM_COUNT][ANIM_COUNT];        int tileWidth=testmap.getWidth()/ANIM_COUNT;        int tileHeight = testmap.getHeight() / ANIM_COUNT;        int i=0,x=0,y=0;        for(i=0;i<ANIM_COUNT;i++){ //x=0开始,表示从左向右                y=0; //一行一行的画        //0,0 第一排        bitmap[ANIM_DOWN][i]=BitmapClipBitmap(testmap,x,y,tileWidth,tileHeight);        y+=tileHeight;//        0,tileHeight 第二排        bitmap[ANIM_LEFT][i] = BitmapClipBitmap(testmap,x,y,tileWidth,tileHeight);    y+=tileHeight;    bitmap[ANIM_RIGHT][i] = BitmapClipBitmap(testmap,x,y,tileWidth,tileHeight);    y+=tileHeight;    bitmap[ANIM_UP][i] = BitmapClipBitmap(testmap,x,y,tileWidth,tileHeight);    x+= tileWidth;        }        mTestAnim[ANIM_DOWN] = new Animation(context,bitmap[ANIM_DOWN],true);        mTestAnim[ANIM_LEFT] = new Animation(context,bitmap[ANIM_LEFT],true);        mTestAnim[ANIM_RIGHT]= new Animation(context,bitmap[ANIM_RIGHT],true);        mTestAnim[ANIM_UP]   = new Animation(context,bitmap[ANIM_UP],true);        mMapImage = ReadBitMap(context,R.drawable.map);//直接把地图给读出来            }    @Override    protected void onDraw(Canvas canvas) {    //1:先画地图    canvas.drawBitmap(mMapImage, 0, 0, mPaint);     if (mAllkeyDown) {     if (mIskeyDown) {        mAnimationState = ANIM_DOWN;//        canvas.drawText("按下下键,开始播放向下动画开始", 0, 20, mPaint);    } else if (mIskeyLeft) {        mAnimationState = ANIM_LEFT;//        canvas.drawText("按下左键,开始播放向左动画开始", 0, 20, mPaint);    } else if (mIskeyRight) {        mAnimationState = ANIM_RIGHT;//        canvas.drawText("按下右键,开始播放向右动画开始", 0, 20, mPaint);    } else if (mIskeyUp) {        mAnimationState = ANIM_UP;//        canvas.drawText("按下上键,开始播放向上动画开始", 0, 20, mPaint);    }     //2: 绘制主角和enemy动画     //根据mAnimationState得到animation数组中对于的姿势,然后画出来     mHeroAnim[mAnimationState].DrawAnimation(canvas, mPaint, 20, 100);     mTestAnim[mAnimationState].DrawAnimation(canvas, mPaint, 100, 100);     }else{//     按键抬起后人物停止动画     mHeroAnim[mAnimationState].DrawFrame(canvas, mPaint, 20, 100, 0);     mTestAnim[mAnimationState].DrawFrame(canvas, mPaint, 100, 100, 0);     }     super.onDraw(canvas);        invalidate();         }    /**     * 设置按键状态true为按下 false为抬起     * @param keyCode     * @param state     */            public void setKeyState(int keyCode, boolean state) {                switch(keyCode) {                case KeyEvent.KEYCODE_DPAD_DOWN:            mIskeyDown = state;            break;                case KeyEvent.KEYCODE_DPAD_UP:            mIskeyUp = state;            break;                case KeyEvent.KEYCODE_DPAD_LEFT:            mIskeyLeft = state;            break;                case KeyEvent.KEYCODE_DPAD_RIGHT:            mIskeyRight = state;            break;                }                mAllkeyDown = state;            }            @Override            public boolean onKeyDown(int keyCode, KeyEvent event) {        mAnimView.setKeyState(keyCode,true);                return super.onKeyDown(keyCode, event);            }            @Override            public boolean onKeyUp(int keyCode, KeyEvent event) {        mAnimView.setKeyState(keyCode,false);                return super.onKeyUp(keyCode, event);            }                        /**             * 程序切割图片             * @param bitmap             * @param x             * @param y             * @param w             * @param h             * @return             */            public Bitmap BitmapClipBitmap(Bitmap bitmap,int x, int y, int w, int h) {                return  Bitmap.createBitmap(bitmap, x, y, w, h);            }                            /**     * 读取本地资源的图片     *      * @param context     * @param resId     * @return     */    public Bitmap ReadBitMap(Context context, int resId) {        BitmapFactory.Options opt = new BitmapFactory.Options();        opt.inPreferredConfig = Bitmap.Config.RGB_565;        opt.inPurgeable = true;        opt.inInputShareable = true;        // 获取资源图片        InputStream is = context.getResources().openRawResource(resId);        return BitmapFactory.decodeStream(is, null, opt);    }            }         }}
package cn.hxx.demo;import java.io.InputStream;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;public class Animation {  /** 上一帧播放时间 **/    private long mLastPlayTime = 0;    /** 播放当前帧的ID **/    private int mPlayID = 0;    /** 动画frame数量 **/    private int mFrameCount = 0;    /** 用于储存动画资源图片 **/    private Bitmap[] mframeBitmap = null;    /** 是否循环播放 **/    private boolean mIsLoop = false;    /** 播放结束 **/    private boolean mIsend = false;    /** 动画播放间隙时间 **/    private static final int ANIM_TIME = 100;        /**     * 构造函数     * @param context     * @param frameBitmapID 动画帧id数组(标示一种资源int,而不是资源bitmap,一次要播放的一组“动画id”,比如说向右走的四个姿势图片id数组     * @param mIsLoop 是否循环播放动画     */    public Animation(Context context,int[] frameBitmapID, boolean mIsLoop){    mFrameCount = frameBitmapID.length;    //这个和frameBitmapID区别?mframeBitmap是资源的流形式,而frameBitmapID是资源标识,用于找到资源    mframeBitmap = new Bitmap[mFrameCount];    for(int i =0; i < mFrameCount; i++) {        mframeBitmap[i] = ReadBitMap(context,frameBitmapID[i]);            }    mIsLoop=mIsLoop;    }        /**     * 构造函数     * @param context     * @param frameBitmap  动画帧数组,一次要连续完成一套动作资源     * @param isloop  是否循环播放动画     */    public Animation(Context context, Bitmap [] frameBitmap, boolean isloop) {mFrameCount = frameBitmap.length;mframeBitmap = frameBitmap;mIsLoop = isloop;    }    /**     * 绘制动画,只画一帧啊,即一套动作中的一个姿势     * 这个函数的用处在于,最后停止的时候我就只这个动画组中的第一帧(不然停止的时候一个脚抬起)     * @param canvas     * @param paint     * @param x     * @param y     * @param frameID     */    public void DrawFrame(Canvas canvas, Paint paint, int x,int y,int frameID){    canvas.drawBitmap(mframeBitmap[frameID], x, y, paint);    }    /**画动画,按照一组的动画从左到右画,注意不一定一组连贯动作全画完,看按键时间     *      * @param canvas     * @param paint     * @param x     * @param y     */    public void DrawAnimation(Canvas canvas, Paint paint , int x, int y){    if(!mIsend){//没有结束    canvas.drawBitmap(mframeBitmap[mPlayID], x, y, paint);     long time = System.currentTimeMillis();     //控制播放帧的速度     if(time-mLastPlayTime>ANIM_TIME){ //如果两帧之间时间超过间隔时间     mPlayID++;//就播放下一帧     mLastPlayTime = time;     if(mPlayID >= mFrameCount){     //标志动画播放结束        mIsend = true;        if (mIsLoop) {    //设置循环播放    mIsend = false;    mPlayID = 0;        }     }     }    }    }    /**     * 读取图片资源     * @param context     * @param resId     * @return     */    public Bitmap ReadBitMap(Context context, int resId) {BitmapFactory.Options opt = new BitmapFactory.Options();opt.inPreferredConfig = Bitmap.Config.RGB_565;opt.inPurgeable = true;opt.inInputShareable = true;// 获取资源图片InputStream is = context.getResources().openRawResource(resId);return BitmapFactory.decodeStream(is, null, opt);    }}


0 0
原创粉丝点击