注意事项: 1、如需将自定义视图添加到XML,必须实现
public Game(Context context, AttributeSet attrs)构造方法
2、图片缩放
Matrix matrix = new Matrix();
// 设置新图片宽高的系数
matrix.setScale(sx, sy);//SX SY 新的宽高
// 缩放图片 //创建图片(原始图片,被缩放图片左上角的X坐标,被缩放图片左上角的y坐标,被缩放图片宽度,被缩放图片高度,图片转化对象)
Bitmap newBitmap = Bitmap.createBitmap(origin, 0, 0, origin.getWidth(), origin.getHeight(), matrix, true);
3.截取图片的一部分
Bitmap bitmapx = Bitmap.createBitmap(bitmap, 50, 50, 100, 100);// 截取图片的一部分
4.获取assets里的图片
// 获取assets路径所对应的文件的输入流
InputStream ins = className.getClass().getResourceAsStream(resName);
// inputStream=getResources().openRawResource(id);//在view类里可以由drawable获得inputstream
// 将输入流转为Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(ins);
5.获取drawable里额图片
InputStream inputStream=getResources().openRawResource(id);
// 将输入流转为Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(ins);
6.只绘制图片的一部分
// 1.在屏幕上裁剪一个可见区域
canvas.clipRect(x, y, x + w, y + h, Op.REPLACE);
// 2.将你需要绘制的图片的某一部分,移动到可见区域
canvas.drawBitmap(bitmap, x - w * line, y - row * h, paint);
// 3.再将整个屏幕职位可见
canvas.clipRect(0, 0, Game.SCREEN_W, Game.SCREEN_H, Op.REPLACE);
7. onDraw(Canvas canvas) 优先于 draw(Canvas canvas)方法;有onDraw方法的前提下不会调用draw方法
package com.example.gaoxinzhilu.view;
import java.io.InputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
public class Game extends View implements Runnable {
// public Game(Context context) {
// super(context);
// init();
// }
public Game(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private Context c;// 上下文
private DisplayMetrics displayMetrics;// 屏幕尺寸
public static int SCREEN_W;
public static int SCREEN_H;
Thread thread;
InputStream is;
Bitmap[] bitmap;
int images;
String[] imagePath;
private Paint paint;// 画笔
private boolean isRun;
private enum GAMESTATUE {
INIT, PLAY, EXIT
};
private GAMESTATUE currentStatues;
public void init() {
paint = new Paint();
currentStatues = GAMESTATUE.INIT;
bitmap = new Bitmap[72];
for (int i = 0; i < 72; i++) {
bitmap[i] = Utils.createBitmapFromAssets("/assets/image/i0011_" + (1 + i) + ".JPG");
// bitmap[i] = Utils.createBitmapFromAssetsScale("/assets/image/i0011_" + (1 + i) + ".JPG", 0.5);//设置缩放比例
}
isRun = true;
// 启动线程
thread = new Thread(this);
thread.start();
}
public Game(Context context, DisplayMetrics attrs) {
super(context);
c = context;
displayMetrics = attrs;
SCREEN_W = displayMetrics.widthPixels;
SCREEN_H = displayMetrics.heightPixels;
init();
}
@Override
public void run() {
// TODO Auto-generated method stub
while (isRun) {
// 逻辑
gameDeal();
// 调用绘画方法
postInvalidate();
// 休眠一段时间
// 1S 24张
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
switch (currentStatues) {
case INIT:
drawInit(canvas);
// init---->play
currentStatues = GAMESTATUE.PLAY;
break;
case PLAY:
drawPlay(canvas);
break;
case EXIT:
drawExit(canvas);
break;
}
}
private void drawExit(Canvas canvas) {
}
private void drawPlay(Canvas canvas) {
// 绘画正在进行
try {
Bitmap bitmapx=bitmap[images];
// Bitmap bitmapx = Bitmap.createBitmap(bitmap[images], 50, 50, 100, 100);// 截取图片的一部分
canvas.drawBitmap(bitmapx, 0, 0, paint);
} catch (Exception e) {
Log.e("Game", " " + e.getMessage());
}
}
private void drawInit(Canvas canvas) {
// 绘画 开始
}
/**
* 游戏的总逻辑
*/
private void gameDeal() {
switch (currentStatues) {
case INIT:// 初始化的逻辑
dealInit();
break;
case PLAY:// 运行时的逻辑
dealPlay();
break;
case EXIT:// 退出时的逻辑
dealExit();
break;
}
}
private void dealExit() {
}
private void dealPlay() {
// 绘画数据在变化 如位置 颜色
images++;
images = images % bitmap.length;
Log.e("Game", "==" + images);
}
private void dealInit() {
// 初始化数据,如颜色
images = -1;
}
/**
* 销毁这个自定义视图
*/
public void Destroy() {
isRun = false;
for (Bitmap bt : bitmap) {
if (!bt.isRecycled()) {
bt.recycle();// 回收图片所占的内存
System.gc();// 提醒系统及时回收
}
}
bitmap = null;
}
}
package com.example.gaoxinzhilu.view;
import java.io.InputStream;
import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Region.Op;
public class Utils {
public static Utils className;
// 图片的缩放类型
private enum SCALETYLE {
BITMAPWH, BITMAPW, BITMAPH
}
public Utils() {
// TODO Auto-generated constructor stub
className = this;
}
// 在app创建的时候就执行
static {
if (className == null) {
className = new Utils();
}
}
/**
* 休眠一段时间
*
* @param time
*/
public static void sleepTime(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 随机某一区间的一个值
*
* @param min
* 最小值
* @param max
* 最大值
* @return
*/
public static int getRandomBetweenBound(int min, int max) {
return Math.abs(new Random().nextInt() % (max - min) + 1) + min;
}
/**
* 创建bitmap对象(只适合来自于assets)
*
* @param path
* @return
*/
public static Bitmap createBitmapFromAssets(String resName) {
// 获取assets路径所对应的文件的输入流
InputStream ins = className.getClass().getResourceAsStream(resName);
// inputStream=getResources().openRawResource(id);//在view类里可以由drawable获得inputstream
// 将输入流转为Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(ins);
// 获取Drawabel
// BitmapFactory.decodeResource(, R.drawable.ic_launcher);
// 获取SDCARD
// InputStream inputStream = new FileInputStream("/sdcard/asdsa.png");
return bitmap;
}
/**
* 等比缩放后bitmap
*/
public static Bitmap createBitmapFromAssetsScale(String resName, double d) {
Bitmap origin = createBitmapFromAssets(resName);
return bitmapScale(origin, (int) ( origin.getWidth() * d), 0, SCALETYLE.BITMAPW);
}
/**
* 图片的缩放
*
* @param origin
* 需要被缩放的图片
* @param newW
* 图片缩放之后的宽
* @param newH
* 图片缩放之后的高
* @return
*/
private static Bitmap bitmapScale(Bitmap origin, int newW, int newH, SCALETYLE type) {
Bitmap newBitmap = null;
// 图片处理类
Matrix matrix = new Matrix();
// 求图片缩放的系数
// 400 500 500/400
// 200 100 100/200
float sx = 1;
float sy = 1;
switch (type) {
case BITMAPWH:// 通过宽高来缩放
sx = newW * 1.0f / origin.getWidth();
sy = newH * 1.0f / origin.getHeight();
break;
case BITMAPW:// 通过宽来缩放
sx = newW * 1.0f / origin.getWidth();
sy = sx;
break;
case BITMAPH:// 通过高来缩放
sy = newH * 1.0f / origin.getHeight();
sx = sy;
break;
}
// 设置新图片宽高的系数
matrix.setScale(sx, sy);
// 缩放图片 //创建图片(原始图片,被缩放图片左上角的X坐标,被缩放图片左上角的y坐标,被缩放图片宽度,被缩放图片高度,图片转化对象)
newBitmap = Bitmap.createBitmap(origin, 0, 0, origin.getWidth(), origin.getHeight(), matrix, true);
return newBitmap;
}
/**
* 图片根据新的宽等比例缩放图片
*
* @param origin
* 需要被缩放的图片
* @param newW
* 图片缩放之后的宽
* @return
*/
public static Bitmap bitmapScaleByW(Bitmap origin, int newW) {
return bitmapScale(origin, newW, 0, SCALETYLE.BITMAPW);
}
/**
* 图片根据新的高等比例缩放图片
*
* @param origin
* 需要被缩放的图片
* @param newW
* 图片缩放之后的宽
* @param newH
* 图片缩放之后的高
*/
public static Bitmap bitmapScaleByH(Bitmap origin, int newH) {
return bitmapScale(origin, 0, newH, SCALETYLE.BITMAPH);
}
/**
* 图片的缩放
*
* @param origin
* 需要被缩放的图片
* @param newW
* 图片缩放之后的宽
* @param newH
* 图片缩放之后的高
* @return
*/
public static Bitmap bitmapScaleByWH(Bitmap origin, int newW, int newH) {
return bitmapScale(origin, newW, newH, SCALETYLE.BITMAPWH);
}
/**
* 只绘制图片的某一部分
*/
public static void bush(Canvas canvas, Bitmap bitmap, Paint paint, int x, int y, int w, int h, int row, int line) {
// 1.在屏幕上裁剪一个可见区域
canvas.clipRect(x, y, x + w, y + h, Op.REPLACE);
// 2.将你需要绘制的图片的某一部分,移动到可见区域
canvas.drawBitmap(bitmap, x - w * line, y - row * h, paint);
// 3.再将整个屏幕职位可见
canvas.clipRect(0, 0, Game.SCREEN_W, Game.SCREEN_H, Op.REPLACE);
// test
// canvas.drawBitmap(bitmap, x-w*line+10, y-row*h+10, paint);
}
/**
* 帧更新,当更新到最大帧的时候,再回归到最小帧
*
* @param currentFrame
* 当前的帧
* @param minFrame
* 最小帧
* @param maxFrame
* 最大帧
*/
public static int frameUpdate(int currentFrame, int minFrame, int maxFrame) {
// 1 2
// 1 2 3 4 5 6
// 如果当前帧已经是最大帧,就回归到最低
if (currentFrame >= maxFrame) {
currentFrame = minFrame;
} else {
currentFrame++;
}
return currentFrame;
}
}