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);
    }
}

 

 

转载于:https://www.cnblogs.com/cindyOne/archive/2013/03/31/2991650.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现这个功能,你需要使用Android Studio中的ImageView和Button控件。首先,在xml布局文件中添加ImageView和四个Button控件,分别表示上下左右移动。例如: ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/plane" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/plane" android:layout_centerInParent="true"/> <Button android:id="@+id/up_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Up" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/> <Button android:id="@+id/down_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Down" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> <Button android:id="@+id/left_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Left" android:layout_alignParentLeft="true" android:layout_centerVertical="true"/> <Button android:id="@+id/right_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Right" android:layout_alignParentRight="true" android:layout_centerVertical="true"/> </RelativeLayout> ``` 然后,在Java代码中获取ImageView和四个Button控件,并为每个Button控件添加点击事件。在点击事件中,修改ImageView的LayoutParams,从而改变ImageView的位置。例如,向上移动时,修改ImageView的topMargin: ```java ImageView plane = findViewById(R.id.plane); Button up_btn = findViewById(R.id.up_btn); Button down_btn = findViewById(R.id.down_btn); Button left_btn = findViewById(R.id.left_btn); Button right_btn = findViewById(R.id.right_btn); up_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plane.getLayoutParams(); params.topMargin -= 10; plane.setLayoutParams(params); } }); down_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plane.getLayoutParams(); params.topMargin += 10; plane.setLayoutParams(params); } }); left_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plane.getLayoutParams(); params.leftMargin -= 10; plane.setLayoutParams(params); } }); right_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) plane.getLayoutParams(); params.leftMargin += 10; plane.setLayoutParams(params); } }); ``` 这样,当用户点击不同的Button控件时,就可以实现飞机的上下左右移动了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值