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();
//显示自定义的游戏view
mAnimView = 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);
}
}