• View框架下实现角色的上下左右移动


      玩过游戏的朋友都知道,不管是RPG游戏或者是飞行射击又或者其他类型的游戏,都会有这中功能——控件角色的移动。现在就来实现这个功能。

                                                                                  

    这是一张用来展示角色行走的图片,大小 188*380,名字是hero.png。

    首先新建一个class(RoleAnimation.java),该类主要是绘制hero.png中的单个角色和连贯的动画,方便其他地方调用

    public class RoleAnimation {
        /** 上一帧播放时间 **/
        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 framBitmaps
         * @param isloop
         */
        public RoleAnimation(Context context,Bitmap[]frameBitmaps,boolean isloop){
            mFrameCount=frameBitmaps.length;
            mframeBitmap=frameBitmaps;
            mIsLoop=isloop;
        }
        /**
         * 绘出某一帧
         * @param canvas
         * @param mPaint
         * @param x
         * @param y
         * @param frameID
         */
        public  void DrawFram(Canvas canvas,Paint mPaint,int x,int y,int frameID) {
            canvas.drawBitmap(mframeBitmap[frameID], x, y, mPaint);
        }
        /**
         * 绘出该对象的动画
         * @param canvas
         * @param mPaint
         * @param x
         * @param y
         */
        public void DrawAnimtion(Canvas canvas,Paint mPaint,int x,int y) {
            if(!mIsend){
                DrawFram(canvas,mPaint,x,y,mPlayID);
                long time=java.lang.System.currentTimeMillis();
                if(time-mLastPlayTime>=ANIM_TIME){
                    mPlayID++;
                    mLastPlayTime=time;
                    if(mPlayID>=mFrameCount){ //将所有帧播放完毕
                        mIsend=true;
                        if(mIsLoop){
                            mIsend=false;
                            mPlayID=0;
                        }
                    }
                }
            }
        }
    }

    再建一个class(RoleView)继承 View

    public class RoleView extends View {
        private int FloatX=0;
        private int FloatY=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;
        RoleAnimation mHeroAnim[] = new RoleAnimation[ANIM_COUNT];
        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;
        
        public RoleView(Context context, int SrceemWidth, int SrceenHeight) {
            super(context);
            mPaint = new Paint();
            // 利用程序来切割hero.png图片
            Bitmap testmap = ReadBitMap(context, R.drawable.hero);
            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++) {
                y = 0;
                bitmap[ANIM_DOWN][i] = BitmapClipBitmap(testmap,
                        x, y, tileWidth, tileHeight);
                y += 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;
            }
            mHeroAnim[ANIM_DOWN] = new RoleAnimation(context, bitmap[ANIM_DOWN],
                    true);
            mHeroAnim[ANIM_LEFT] = new RoleAnimation(context, bitmap[ANIM_LEFT],
                    true);
            mHeroAnim[ANIM_RIGHT] = new RoleAnimation(context, bitmap[ANIM_RIGHT],
                    true);
            mHeroAnim[ANIM_UP] = new RoleAnimation(context, bitmap[ANIM_UP], true);
        }
        
        /**
         * 该方法在实例化view的时候会被调用
         */
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            canvas.save();
            canvas.clipRect(0, 0, 320, 30);
            mPaint.setColor(Color.WHITE);
            canvas.drawRect(0, 0, 480, 30, mPaint);
            mPaint.setColor(Color.RED);
            canvas.restore();
            /** 根据按键更新显示动画 **/
            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);
                }
            } else {
                /** 按键抬起后人物停止动画 **/
                mHeroAnim[mAnimationState].DrawFram(canvas, mPaint, 20+FloatX, 100+FloatY, 0);
                canvas.drawText("按键已经抬起动画停止", 0, 20, mPaint);
            }
            super.onDraw(canvas);
            invalidate();  //重新调用onDraw方法,相当于刷屏重绘
        }
        
        /**
         * 设置按键状态true为按下 false为抬起
         * 
         * @param keyCode
         * @param state
         */
        public void setKeyState(int keyCode, boolean state) {
            switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_DOWN:
                mIskeyDown = state;
                FloatY++;
                break;
            case KeyEvent.KEYCODE_DPAD_UP:
                mIskeyUp = state;
                FloatY--;
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                mIskeyLeft = state;
                FloatX--;
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                mIskeyRight = state;
                FloatX++;
                break;
            }
            mAllkeyDown = state;
        }
    
        
        /**
         * 获取本地的图片资源
         * @param context
         * @param resources
         * @return
         */
        public static Bitmap ReadBitMap(Context context, int resources) {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            opt.inInputShareable = true;
            // 获取资源图片
            InputStream is = context.getResources().openRawResource(resources);
            return BitmapFactory.decodeStream(is, null, opt);
        }
        /**
         * 程序切割图片
         * 
         * @param bitmap
         * @param x
         * @param y
         * @param w
         * @param h
         * @return
         */
        public static Bitmap BitmapClipBitmap(Bitmap bitmap, int x, int y, int w, int h) {
            return Bitmap.createBitmap(bitmap, x, y, w, h);
        }
    }

    最后在Activity里面调用

    public class RoleMoveActivity extends Activity {
        RoleView mAnimView;
        @Override
        protected 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();
            mAnimView = new RoleView(this, display.getWidth(), display.getHeight());
            setContentView(mAnimView);
        }
    
        @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);
        }
    }
  • 相关阅读:
    form 元素横向排列
    mysql5.6 主从同步
    centos iptables
    angular 数据绑定
    angular路由 模块 依赖注入
    angular $scope对象
    angular前端开发环境
    使用STM32CubeMX生成RTC工程[闹钟中断2]
    利用STM32CubeMX生成HID双向通讯工程
    使用STM32CubeMX生成RTC工程[秒中断]
  • 原文地址:https://www.cnblogs.com/cindyOne/p/2991650.html
Copyright © 2020-2023  润新知