Android手机游戏开发知识点总结

更新时间:2024-01-30 00:03:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Android手机游戏知识点总结

Android手机游戏开发学习笔记

第一部分 其实游戏就是让状态机不断的让Canvas在View上画你想要的东西。这个状态机包括内部的执行,还包括外部的输入。 Android开发的MVC模式

1,通过View和SurfaceView来显示界面的视图。(处理界面与用户的交互事件,如,触笔点击,用户按键等。可通过View类的onKeyDown,onKeyUp,onTouchEvent等)。 2,用Activity来控制游戏的整体结构。 3,设计一个逻辑类,用来处理逻辑运算。

Android中任何一个View类都只有重写onDraw方法来实现界面显示。 Android中提供了

onKeyUp,onKeyDown,onKeyMultiple,onKeyPreIme,onTouchEvent,onTrackballEvent等方法。可以用来处理游戏中的事件消息。所以继承View时,需要重载这些方法。

Android中提供了invalidate来刷新界面,但invalidate不能直接在线程中调用,违背单线程模型。

因此Android中最常用的方法是利用Handler来时更新UI界面。

第一部分 View 类

每个View类都有一个绘画的画布,在游戏中可以自定义视图View,任何一个View类都只需要重写onDraw方法来实现界面显示,可以是3D,也可以是文本。 游戏的核心就是不断的绘图和刷新,图我们可以通过onDraw方法绘制,刷新Android中可以用invalidate方法来刷新界面,注意:invalidate不能直接在线程中调用,因其违背了

违背单线程模型。因此Android中最常用的方法是利用Handler来时更新UI界面。下面这个例子中包含了两个刷新方法。

public class Game extends Activity{ public static final int REFRESH = 1; public GameView gameView;

public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);

this.gameView = new GameView(this);//实例化GameView

setContentView(gameView);

new Thread(new GameThread()).start(); }

// Handler handler = new Handler(){//注释掉的为实例化Handler对象并重写handleMessage方法实现一个消息接受器,然后在线程中通过sendMessage方法发送更新界面的消息,

当接收器收到更新界面的消息时,便执行invalidate方法更新屏幕显示。 // public void handleMessage(Message msg){//接受消息 // switch (msg.what){ // case Game.REFRESH:

// gameView.invalidate();//更新界面 // break; // }

// super.handleMessage(msg); // } // };

public boolean onTouchEvent (MotionEvent event){ return true; }

public boolean onKeyDown(int keyCode,KeyEvent event){ return true; }

public boolean onKeyUp(int keyCode,KeyEvent event){ switch (keyCode){

case KeyEvent.KEYCODE_DPAD_DOWN: gameView.y+=6; break;

case KeyEvent.KEYCODE_DPAD_UP: gameView.y-=6; break; }

return true; }

public boolean onKeyMultiple(int keyCode,int repeatCount,KeyEvent event){ return true;

}

// public class GameThread implements Runnable{//创建更新线程 // @Override // public void run() {

// while(!Thread.currentThread().isInterrupted()){ // Message message = new Message(); // message.what = Game.REFRESH;

// Game.this.handler.sendMessage(message);//发送消息 // try{

// Thread.sleep(100);

// }catch(InterruptedException e){ // Thread.currentThread().interrupt(); // } // } // } // }

public class GameThread implements Runnable{ public void run(){

while(!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(100);

}catch(InterruptedException e){ Thread.currentThread().interrupt(); }

gameView.postInvalidate();//使用PostInvalidate可以直接在线程中更新界面 不需要Handler来传递消息 } } } }

public class GameView extends View{ public int count = 0; public int y =0;

public GameView(Context context) { super(context); }

public void onDraw(Canvas canvas){ if(count<8){ count++; }else{ count=0; }

Paint paint= new Paint(); switch(count%4){ case 0:

paint.setColor(Color.BLACK); break; case 1:

paint.setColor(Color.RED); break; case 2:

paint.setColor(Color.YELLOW); break; case 3:

paint.setColor(Color.GREEN); break; }

canvas.drawRect(y,y,y+40,y+40, paint);//绘制矩形 } }

第二部分 SurfaceView类

1,开发复杂游戏,而且对程序的执行效率要求更高时用此类,因本身就是双缓冲机制的。

2,SurfaceView可以直接访问一个画布。

3,SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用而使用的。 4,View即其子类(如TextVie,Button)要画在Surface上。每个Surface创建一个Canvas对象(属性时常改变)用来管理View在Surface上绘制操作。 5,使用SurfaceView绘图时,一般都是出现在最顶层。在使用时要对其创建,

销毁,情况改变进行监视,这就需要实现SurfaceHolder.Callback接口, 如果要对被绘制的画布进行裁剪,控制其大小时都需要使用SurfaceHolder来完成处理。

6,在程序中,SurfaceHolder对象需要通过getHolder方法来获得,同时还需要addCallback方法来添加“回调函数”。

7,SurfaceView与View不同之处,在于SurfaceView不需要通过线程来更新视图,在绘制前必须使用lockCanvas方法锁定画布,并得到画布,然后在画布上绘制

绘制完成后,使用unlockCanvasAndPost方法来解锁画布。 8,addCallback:给SurfaceView添加一个回调函数; removeCallback:从SurfaceView移除回调函数;

public class GameView2 extends SurfaceView implements SurfaceHolder.Callback, Runnable{

SurfaceHolder surfaceHolder = null;//定义对象 public boolean loop = false; public int count = 1;

public GameView2(Context context) { super(context);

surfaceHolder = this.getHolder();//实例化SurfaceHolder对象 surfaceHolder.addCallback(this);//添加回调函数 loop = true;

this.setFocusable(true);//不知道这句什么意思? }

private void Draw() {

Canvas canvas = surfaceHolder.lockCanvas();//锁定画布 if(surfaceHolder ==null||canvas ==null){ return ; }

if(count<100){ count++; }else{ count= 0; }

Paint paint = new Paint();//创建画笔 paint.setAntiAlias(true);//设置抗锯齿

paint.setColor(Color.GREEN);//设置画笔颜色 canvas.drawRect(0,0,320,480, paint);//绘制矩形 switch(count%4){ case 0:

paint.setColor(Color.BLUE); break; case 1:

paint.setColor(Color.YELLOW); break; case 2:

paint.setColor(Color.RED); break; case 3:

paint.setColor(Color.CYAN); break; default:

paint.setColor(Color.WHITE); break; }

canvas.drawCircle(130, 240, 500, paint);

surfaceHolder.unlockCanvasAndPost(canvas);//绘制后解锁,绘制后必须解锁才能显示 }

@Override//在Surface大小发生改变时激发

public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

// TODO Auto-generated method stub }

@Override//在Surface创建时激发

public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub new Thread(this).start(); }

@Override//在Surface销毁时调用

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub loop=false; }

public void run(){ while(loop){ try{

Thread.sleep(200);

synchronized (surfaceHolder) { Draw(); }

}catch(Exception e){ } } } }

第三部分 Paint类和Color类

在Android中通过graphic类来显示2D图形。graphic包括Canvas类(画布),Paint(画笔),Color(颜色),Bitmap(图像),2D几何图形等常用类。 package graphics; Paint类常用的一些方法: setAntiAlias 设置画笔的锯齿效果 setColor 设置画笔颜色

setARGB 设置画笔的a,r,g,b值。 setAlpha 设置透明度 setTextSize 设置字体大小 setStyle 设置画笔风格 空心或实心 setStrokeWidth设置空心的边框宽度 getColor 得到画笔的颜色 getAlpha 得到画笔的透明度 Color类中定义了一些颜色常量

Color.rgb方法将整型的颜色转换成Color类型。如Color.red方法可提取出红色的值。 /**

* 注意:在绘制时按从上到下的顺序绘制的 ,后面的如果和前面的重合的话会

将前面的覆盖掉 */

public class Graphics_Paint_Color extends View implements Runnable { public Paint paint; private String TAG=\你好\

public Graphics_Paint_Color(Context context) { super(context);

paint = new Paint();//创建画笔 new Thread(this).start();//开启线程 }

public void onDraw(Canvas canvas){ super.onDraw(canvas);

paint.setAntiAlias(true);//设置抗锯齿 paint.setColor(Color.RED);//设置画笔颜色

paint.setColor(Color.rgb(12, 234, 34));//设置画笔颜色 其中参数分别为red,green,blue三种颜色的值

Color.red(23);//提取颜色? Color.blue(234);

paint.setARGB(255, 23,234,49);//设置Paint的颜色和Alpha值

paint.setAlpha(200);//设置透明度

//paint.set(new PAINT());//设置另外一个Paint对象 paint.setTextSize(14);//设置字体的尺寸

//得到Paint的一些属性

Log.i(TAG, \的颜色\Log.i(TAG,\的Alpha\

paint.setStyle(Paint.Style.STROKE);//设置Paint为空心 paint.setStrokeWidth(5);//设置空心的外框宽度 canvas.drawRect(0,0,50,60, paint);//绘制空心矩形

paint.setStyle(Paint.Style.FILL);//设置Paint为实心 canvas.drawRect(60,70,120,140, paint);//绘制实心的矩形 }

public void run() {

while(!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(200); }catch(Exception e){ e.printStackTrace();

Thread.currentThread().interrupt(); }

postInvalidate();//使用postInvalidate可以直接在线程中更新界面 } }

}在View或SurfaceView中绘制图形后,需要在Activtiy中通过setContentView()来让其显示出来

第四部分 Canvas类和ShadeDrawable类 Canvas方法:

Canvas() 创建画布,可以用setBitmap()方法设置绘制具体画布 Canvas(Bitmap bitmap) 以bitmap对象创建一个画布,则将内容都绘制在bitmap上,所以bitmap不得为null

Canvas(GL gl) 绘制3D效果时使用,与OpenGL drawColor 设置画布背景色 setBitmap 设置具体画布

clipRect 设置显示区域,即设置裁剪区 isOpaque 检测是否支持透明

rotate 旋转画布 在游戏中我们需要对精灵旋转,缩放或其它操作就可以通过旋转画布来实现,但在旋转画布时会旋转画布上所以对象,而我们只需要旋转其中一个。这个时候

我们就需要用save方法来锁定需要操作的对象,在操作后通过restore方法来解锁。(例子有此方法的运用) setViewport 设置画布中显示窗口 skew 设置便宜量

绘制几何图形的方法

drawRect 绘制矩形 drawCircle 绘制圆形 drawOval 绘制椭圆 drawLine 绘制直线 drawPoint 绘制点

public class CanvasView extends View implements Runnable{ private Paint paint ;

public ShapeDrawableView shapeDrawableView; public CanvasView(Context context) { super(context); paint = new Paint();

shapeDrawableView= new ShapeDrawableView(context);//得到对象 new Thread(this).start(); }

public void onDraw(Canvas canvas){ super.onDraw(canvas);

canvas.drawColor(Color.BLACK);//设置画布颜色 paint.setAntiAlias(true);//取消抗锯齿效果 //canvas.clipRect(20,20,80,80);//设置裁剪区域

canvas.save();//锁定画布 //canvas.rotate(45.0f);//旋转画布

paint.setColor(Color.RED);//设置颜色及绘制矩形 canvas.drawRect(new Rect(10,10,80,80), paint); canvas.restore();//解锁画布

paint.setStyle(Paint.Style.STROKE);{//设置为空心画笔 Rect rect = new Rect(); rect.left =85; rect.bottom=80; rect.right=150; rect.top = 10;

paint.setColor(Color.BLUE);

canvas.drawRect(rect, paint);//绘制矩形

canvas.drawCircle(60,60,50,paint);//绘制圆形

RectF rectF = new RectF();//绘制椭圆 rectF.bottom=80; rectF.left=160; rectF.right= 300; rectF.top = 10;

canvas.drawOval(rectF, paint);

Path path = new Path();//绘制多边形 path.moveTo(10, 90); path.lineTo(80, 100); path.lineTo(70,150); path.lineTo(10, 200); path.close();//封闭多边形 canvas.drawPath(path, paint);

paint.setStrokeWidth(5);

canvas.drawLine(50,50,300,200, paint); }

paint.setStyle(Paint.Style.FILL);{//设置画笔为实心 paint.setColor(Color.YELLOW);

canvas.drawRect(20,250,300,300, paint); }

shapeDrawableView.DrawShape(canvas);//绘制另一View里的图形到本View中来 }

public void run() {

while(!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(200); }catch(Exception e){

Thread.currentThread().interrupt(); }

postInvalidate();//直接在线程中更新

} } } /**

*Android中可以通过ShapeDrawable来绘制图像。可以通过getPaint方法得到Paint对象,

setBounds 此方法可设置图形显示的区域

通过ShapeDrawable的Draw方法将图形画到屏幕上 */

public class ShapeDrawableView extends View{ ShapeDrawable shapeDrawable; Paint paint;

public ShapeDrawableView(Context context) { super(context); }

public void DrawShape(Canvas canvas){

shapeDrawable = new ShapeDrawable();//------用ShapeDrawable绘图必须要实例化对象

paint=shapeDrawable.getPaint();//得到画笔 paint.setColor(Color.GREEN);//设置画笔颜色 Rect bounds =new Rect(10,310,80,390);//绘制矩形

shapeDrawable.setBounds(bounds);//------用ShapeDrawable绘图必须要使用SetBounds显示区域

shapeDrawable.draw(canvas);//--------用ShapeDrawable绘图必须要使用draw()使图像显示到屏幕上 //另一种写法

/* 实例化ShapeDrawable对象并说明是绘制一个椭圆 */ shapeDrawable = new ShapeDrawable(new OvalShape()); //得到画笔paint对象并设置其颜色

shapeDrawable.getPaint().setColor(Color.GREEN); /* 设置图像显示的区域 */

shapeDrawable.setBounds(70, 250, 150, 280); /* 绘制图像 */

shapeDrawable.draw(canvas);

//以下为绘制多边形 Path path1 = new Path(); /*设置多边形的点*/

path1.moveTo(150+5, 80+80-50); path1.lineTo(150+45, 80+80-50); path1.lineTo(150+30, 80+120-50); path1.lineTo(150+20, 80+120-50); /* 使这些点构成封闭的多边形 */ path1.close();

//PathShape后面两个参数分别是宽度和高度

shapeDrawable = new ShapeDrawable(new PathShape(path1,150,150)); //得到画笔paint对象并设置其颜色

shapeDrawable.getPaint().setColor(Color.BLUE); /* 设置图像显示的区域 */

shapeDrawable.setBounds(100, 170, 200, 280); /* 绘制图像 */

shapeDrawable.draw(canvas); } }

第五部分 字符串绘制

Android中提供了drawText方法来绘制字符串,在绘制执法串之前需要设置画笔对象,包括字符串的尺寸,颜色等属性。使用FontMetrics来规划字体属性 可以用getFontMetrics方法来获得系统字体的相关内容。 setTextSize 设置字符串的尺寸 setARGB 设置颜色

getTextWidths 取得字符串宽度

setFlags(Paint.ANTI_ALIAS_FLAG) 消除锯齿 measureText 得到字符串宽度 得到字符串高度可用:

FontMetrics fontMetrics = paint.getFontMetrics();

textselfHeight = (int)Math.ceil(fontMetrics.descent - fontMetrics.top)+2;//得到文字的高度

textPageLineNum = textHeight/textselfHeight;//每一页的行数 = 绘制区域的高度/文字本身的高度

下例实现了文本翻页,换行。

* 实现文字自动换行 * 自动翻页

public class TextUtil{

int m_iTextPosX; //绘制的x点 int m_iTextPosY; //绘制的y点 int m_iTextWidth; //绘制宽度 int m_iTextHeight; //绘制高度 int m_iFontHeight; //字体高度

int m_ipageLineNum; //每一页显示的行数 int m_iTextBGColor; // 背景颜色 int m_iTextColor; // 字体颜色 int m_iAlpha; //Alpha值

int m_iRealLine; // 字符串真实的行数 int m_iCurLine; //当前行

String m_strText; Vector m_String; Paint m_paint; int m_iTextSize; public TextUtil(){ m_paint = new Paint(); m_String = new Vector(); }

public TextUtil(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize){ m_paint = new Paint(); m_String = new Vector();

m_strText = strText; m_iTextPosX = x; m_iTextPosY = y; m_iTextWidth = w; m_iTextHeight = h;

m_iTextBGColor = bgcolor; m_iTextColor = txetcolor; m_iTextSize = iTextSize; m_iAlpha = a; } /** * 初始化

* @param strText 要显示的字符串 * @param x x * @param y y * @param w w * @param h h

* @param bgcolor 背景颜色 * @param txetcolor 文字的颜色 * @param a Alpha

* @param iTextSize 字体大小 */

public void InitText(String strText, int x, int y, int w, int h, int bgcolor, int txetcolor, int a, int iTextSize){ m_iCurLine = 0; m_ipageLineNum = 0; m_iRealLine = 0; m_strText = \m_iTextPosX = 0; m_iTextPosY = 0; m_iTextWidth = 0; m_iTextHeight = 0; m_iTextBGColor = 0; m_iTextColor = 0; m_iTextSize = 0; m_iAlpha = 0; m_String.clear();

SetText(strText); SetRect(x, y, w, h); SetBGColor(bgcolor); SetTextColor(txetcolor); SetFontSize(iTextSize); SetAlpha(a); SetPaint(); GetTextIfon(); } /**

* 设置Alpha * @param a Alpha值 */

public void SetAlpha(int a){ m_iAlpha = a; } /**

* 对Paint属性的设置 */

public void SetPaint(){

m_paint.setARGB(m_iAlpha, Color.red(m_iTextColor), Color.green(m_iTextColor), Color.blue(m_iTextColor)); m_paint.setTextSize(m_iTextSize); } /**

* 设置字体尺寸 * @param iTextSize */

public void SetFontSize(int iTextSize){ m_iTextSize = iTextSize; } /**

* 设置显示文本的区域 * @param x * @param y

* @param w * @param h */

public void SetRect(int x, int y, int w, int h){ m_iTextPosX = x; m_iTextPosY = y; m_iTextWidth = w; m_iTextHeight = h; } /**

* 设置背景颜色 * @param bgcolor */

public void SetBGColor(int bgcolor){ m_iTextBGColor = bgcolor; } /**

* 设置字体颜色 * @param txetcolor */

public void SetTextColor(int txetcolor){ m_iTextColor = txetcolor; } /**

* 色绘制要显示的字符串 * @param strText */

public void SetText(String strText){ m_strText = strText; } /**

* 得到字符串的信息 * 包括:行数、页数等信息 * 内部调用 */

public void GetTextIfon(){ char ch; int w = 0; int istart = 0;

FontMetrics fm = m_paint.getFontMetrics();

m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + 2; m_ipageLineNum = m_iTextHeight / m_iFontHeight; for (int i = 0; i < m_strText.length(); i++){ ch = m_strText.charAt(i); float[] widths = new float[1]; String srt = String.valueOf(ch); m_paint.getTextWidths(srt, widths); if (ch == '\\n'){ m_iRealLine++;

m_String.addElement(m_strText.substring(istart, i)); istart = i + 1; w = 0; }else{

w += (int) (Math.ceil(widths[0])); if (w > m_iTextWidth){ m_iRealLine++;

m_String.addElement(m_strText.substring(istart, i)); istart = i; i--; w = 0; }else{

if (i == (m_strText.length() - 1)){ m_iRealLine++;

m_String.addElement(m_strText.substring(istart, m_strText.length())); } } } } } /**

* 绘制字符串 * @param canvas */

public void DrawText(Canvas canvas){

for (int i = m_iCurLine, j = 0; i < m_iRealLine; i++, j++){ if (j > m_ipageLineNum){ break; }

canvas.drawText((String) (m_String.elementAt(i)), m_iTextPosX, m_iTextPosY + m_iFontHeight * j, m_paint); } } /**

* 翻页等按键处理 * @param keyCode * @param event * @return */

public boolean KeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_DPAD_UP){ if (m_iCurLine > 0){ m_iCurLine--; }

}else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN){ if ((m_iCurLine + m_ipageLineNum) < (m_iRealLine - 1)){ m_iCurLine++; } }

return false; } }

public class GameView extends View implements Runnable{ /* 声明Paint对象 */ private Paint mPaint = null; private int mICount = 0;

/* 声明TextUtil对象 */ private TextUtil mTextUtil = null; public GameView(Context context){ super(context); /* 构建对象 */ mPaint = new Paint();

String string = \测试自动换行\\n\\n设置文字自动换行abcdefgh\\niklmnopqrst换行123347465\\n43756245Android\\n设置文字自动换行abcdefgh\\n iklmnopqrst换行123347465\\n43756245Android\ /* 实例化TextUtil */

mTextUtil = new TextUtil(string,5,50,300,80,0x0,0xffffff,255,16); /* 初始化TextUtil */

mTextUtil.InitText(string,5,150,300,80,0x0,0xffffff,255,16); /* 开启线程 */

new Thread(this).start(); }

public void onDraw(Canvas canvas){ super.onDraw(canvas); /* 设置背景颜色 */

canvas.drawColor(Color.BLACK); mPaint.setAntiAlias(true); if ( mICount < 100 ){ mICount++; }

mPaint.setColor(Color.RED);

canvas.drawText(\装在进度:\/* 绘制TextUtil:实现自动换行 */ mTextUtil.DrawText(canvas); }

// 触笔事件

public boolean onTouchEvent(MotionEvent event){ return true; }

// 按键按下事件

public boolean onKeyDown(int keyCode, KeyEvent event){

return mTextUtil.KeyDown(keyCode, event); }

// 按键弹起事件

public boolean onKeyUp(int keyCode, KeyEvent event){ return false; }

public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event){ return true; } /** * 线程处理 */

public void run(){

while (!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(100);

}catch (InterruptedException e){ Thread.currentThread().interrupt(); }

//使用postInvalidate可以直接在线程中更新界面 postInvalidate(); } } }

public class Activity01 extends Activity{ private GameView mGameView = null;

public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); mGameView = new GameView(this); setContentView(mGameView); }

// 按键弹起事件

public boolean onKeyUp(int keyCode, KeyEvent event){ return super.onKeyUp(keyCode, event);

}

// 按键按下事件

public boolean onKeyDown(int keyCode, KeyEvent event){ mGameView.onKeyDown(keyCode, event); return true; } }

第六部分 图像的绘制 旋转 缩放

1.((BitmapDrawable) getResource().getDrawable(资源索引)).getBitmap() 加载资源

2.canvas.drawBitmap(bitmap,x,y,null);将bitmap绘制在屏幕的(x,y)位置 3.getHeight() ,getWidth() 获得图片的高度好宽度

4.Android中通过Matrix旋转图片。Matrix没有结果体,它必须被实例化,可通过reset方法或set方法来实现。 setRotate方法来设置旋转角度

createBitmap 创建一个经过旋转等处理的Bitmap对象

5.Matrix的postScale(x,y)方法来设置缩放的倍数 分别在x,y方法缩放的倍数。 public class Draw_Bitmap extends Activity{ public DrawBitmap drawBitmap;

public void onCreate(Bundle savedInstanceState){ drawBitmap = new DrawBitmap(this); super.onCreate(savedInstanceState); setContentView(drawBitmap); }

public boolean onKeyDown(int keyCode,KeyEvent event){ if(drawBitmap == null){ return false;

}else if(keyCode ==KeyEvent.KEYCODE_BACK){ this.finish(); return true; }

return drawBitmap.onKeyDown(keyCode, event); } }

public class DrawBitmap extends View implements Runnable{ private static Paint paint1=null; public static Bitmap dog1=null; public Bitmap tb1=null; public int dog1width = 0; public int dog1height = 0; public float rotate=0.0f; public float scale = 1.0f;

Matrix matrix = new Matrix();//构建Matrix对象 Matrix用于旋转图片 public DrawBitmap(Context context) { super(context); paint1 = new Paint(); //从资源中装载图片 dog1 =

((BitmapDrawable)getResources().getDrawable(R.drawable.dog)).getBitmap(); tb1 =

((BitmapDrawable)getResources().getDrawable(R.drawable.tb)).getBitmap();

dog1width = dog1.getWidth();//得到图像的宽度 dog1height =dog1.getHeight();//得到图像的高度

new Thread(this).start();//创建,开启线程 }

public void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawColor(Color.BLUE);

canvas.drawBitmap(dog1,10,240,paint1);

matrix.reset();//重置matrix得到Matrix的方法体 matrix.setRotate(rotate);//设置旋转

matrix.postScale(scale, scale);//设置缩放分别为(x,y)方法的缩放 Bitmap dog1rotate =

Bitmap.createBitmap(dog1,0,0,dog1width,dog1height,matrix,true);//按Matrix

的旋转构建新的Bitmap

DrawBitmap.drawImage(canvas,dog1rotate,130,240);//绘制旋转后的图片

dog1rotate= null;//这里难道是释放资源

DrawBitmap.drawImage(canvas,dog1,0,0);//在屏幕的(0,0)处绘制图片 DrawBitmap.drawImage2(canvas,tb1,10,dog1.getHeight(),142,100,150,178);//在指定位置按指定的裁决区域进行绘制 } /**

* i---屏幕上的x坐标 * height---屏幕上的y坐标 * j---要绘制图片的宽度 *k---要绘制图片的高度 *l---图片上的x坐标 *m---图片上的Y坐标 */

private static void drawImage2(Canvas canvas, Bitmap tb12, int i, int height, int j, int k, int l, int m) {

Rect rect1 = new Rect();//图片上裁剪区域 rect1.left = l; rect1.top =m; rect1.right=l+j; rect1.bottom = m+k;

Rect rect2 = new Rect();//屏幕上的裁剪区域 rect2.left = i; rect2.top = height; rect2.right =i+j;

rect2.bottom = height+k;

canvas.drawBitmap(tb12, rect1,rect2, null); }

private static void drawImage(Canvas canvas, Bitmap dog12, int i, int j){ canvas.drawBitmap(dog12,i,j,null); }

public boolean onKeyDown(int keyCode,KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){ rotate+=10;

}else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){ rotate--;

}else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){ if(scale>0.3){//注意:scale必须大于0,否则会报错 scale-=0.1; }

}else if(keyCode == KeyEvent.KEYCODE_DPAD_UP){ if(scale<2.0){ scale+=0.1; } }

return true; }

public boolean onKeyUp(int keyCode,KeyEvent event){ return false; }

public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event){ return true; }

@Override public void run() {

while(!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(100); }catch(Exception e){

Thread.currentThread().interrupt(); }

postInvalidate(); } } }

第七部分 图像像素的操作

Android中Bitmap提供了操作像素的方法,可通过getPixels方法获得图像像素并放到一个数组中去。我们处理这个数组就可以了,最后通过setPixels设置这个像素数组到Bitmap中去。

Android中,每一个图像像素通过4字节整数来展现:最高位字节用作Alpha通道。即用来实现透明与不透明控制,255代表完全透明,0为完全不透明;接下来的一个字节是Red红色通道。

255代表完全是红色。依次类推,接下来的两个字节相应地实现绿色和蓝色通道。 下例为通过图像像素的操作来模拟水纹效果。

public class GameView extends View implements Runnable{ int BACKWIDTH; int BACKHEIGHT; short[] buf2; short[] buf1; int[] Bitmap2; int[] Bitmap1;

public GameView(Context context){ super(context); Bitmap image =

BitmapFactory.decodeResource(this.getResources(),R.drawable.qq);//装载图片

BACKWIDTH = image.getWidth(); BACKHEIGHT = image.getHeight();

buf2 = new short[BACKWIDTH * BACKHEIGHT]; buf1 = new short[BACKWIDTH * BACKHEIGHT]; Bitmap2 = new int[BACKWIDTH * BACKHEIGHT]; Bitmap1 = new int[BACKWIDTH * BACKHEIGHT];

image.getPixels(Bitmap1, 0, BACKWIDTH, 0, 0, BACKWIDTH, BACKHEIGHT);//加载图片的像素到数组中 new Thread(this).start(); }

public void DropStone(

int x, // x坐标 int y, // y坐标

int stonesize, // 波源半径 int stoneweight){ // 波源能量

for (int posx = x - stonesize; posx < x + stonesize; posx++) for (int posy = y - stonesize; posy < y + stonesize; posy++)

if ((posx - x) * (posx - x) + (posy - y) * (posy - y) < stonesize * stonesize) buf1[BACKWIDTH * posy + posx] = (short) -stoneweight; }

public void RippleSpread(){

for (int i = BACKWIDTH; i < BACKWIDTH * BACKHEIGHT - BACKWIDTH; i++){

buf2[i] = (short) (((buf1[i - 1] + buf1[i + 1] + buf1[i - BACKWIDTH] + buf1[i + BACKWIDTH]) >> 1) - buf2[i]);// 波能扩散 buf2[i] -= buf2[i] >> 5;// 波能衰减 }

// 交换波能数据缓冲区 short[] ptmp = buf1; buf1 = buf2; buf2 = ptmp; }

public void render(){//渲染你水纹效果 int xoff, yoff; int k = BACKWIDTH;

for (int i = 1; i < BACKHEIGHT - 1; i++){ for (int j = 0; j < BACKWIDTH; j++){ // 计算偏移量

xoff = buf1[k - 1] - buf1[k + 1];

yoff = buf1[k - BACKWIDTH] - buf1[k + BACKWIDTH]; // 判断坐标是否在窗口范围内 if ((i + yoff) < 0){ k++; continue; }

if ((i + yoff) > BACKHEIGHT){

k++; continue; }

if ((j + xoff) < 0){ k++; continue; }

if ((j + xoff) > BACKWIDTH){ k++; continue; }

// 计算出偏移象素和原始象素的内存地址偏移量 int pos1, pos2;

pos1 = BACKWIDTH * (i + yoff) + (j + xoff); pos2 = BACKWIDTH * i + j;

Bitmap2[pos2++] = Bitmap1[pos1++]; k++; } } }

public void onDraw(Canvas canvas){ super.onDraw(canvas);

canvas.drawBitmap(Bitmap2, 0, BACKWIDTH, 0, 0, BACKWIDTH, BACKHEIGHT, false, null);//绘制经过处理的图片效果 }

public boolean onTouchEvent(MotionEvent event){// 触笔事件 return true; }

public boolean onKeyDown(int keyCode, KeyEvent event){// 按键按下事件 return true; }

public boolean onKeyUp(int keyCode, KeyEvent event){// 按键弹起事件 DropStone(BACKWIDTH/2, BACKHEIGHT/2, 10, 30); return false; }

public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event){ return true; }

public void run(){//线程处理

while (!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(50);

}catch (InterruptedException e){ Thread.currentThread().interrupt(); }

RippleSpread(); render();

//使用postInvalidate可以直接在线程中更新界面 postInvalidate(); } } }

第八部分 Shader类 图片的渲染 /**

* 所谓的渲染就是对画笔的设置 本人是这样理解的。Shader类的使用,都需要先构建Shader对象,然后通过Paint的setShader方法来设置渲染对象,然后在绘制时使用Paint

对象。当然用不同的渲染需要构建不同的对象(即相当于创建不同的画笔)。 */

public class Shader01 extends View{ Bitmap qq2 = null; int qq2width = 0; int qq2height = 0; Paint paint = null;

Shader bitmapShaper = null;//Bitmap渲染 Shader linearGradient = null;//线性渲染 Shader radialGradient = null;//环形渲染 Shader sweepGradient = null;//梯度渲染

Shader composeShaper = null;//混合渲染

ShapeDrawable shapeDrawable = null;

public Shader01(Context context) { super(context);

qq2 = ((BitmapDrawable)

getResources().getDrawable(R.drawable.qq)).getBitmap();//装载资源

qq2width = qq2.getWidth();//得到图片的宽度 qq2height = qq2.getHeight();//得到图片的高度

//创建BitmapShader对象 bitmapShaper = new

BitmapShader(qq2,Shader.TileMode.REPEAT,Shader.TileMode.MIRROR);//要想裁剪需要使用BitmapShader类来裁剪,得到图片的宽度和高度

//创建linearGradient对象并设置变化的颜色数组 linearGradient = new LinearGradient(10, 0, 50, 100, new int []{Color.RED,Color.YELLOW,Color.BLACK}, null, Shader.TileMode.MIRROR);

//混合渲染

composeShaper =new ComposeShader(linearGradient, bitmapShaper, PorterDuff.Mode.DARKEN);//也可选用其他的混合

//环形渲染

radialGradient = new RadialGradient(50, 200, 50, new int[]{Color.GREEN,Color.RED,Color.BLUE}, null, Shader.TileMode.REPEAT);

//梯度渲染

sweepGradient = new SweepGradient(30, 30, new int[]{Color.GREEN,Color.RED,Color.BLUE}, null); paint = new Paint();//创建画笔

}

public void onDraw(Canvas canvas){ super.onDraw(canvas);

shapeDrawable = new ShapeDrawable(new OvalShape());//设置绘制椭圆 shapeDrawable.getPaint().setShader(bitmapShaper);//设置要绘制的椭圆形的图片

shapeDrawable.setBounds(0,0,qq2width,qq2height);//设置要显示的区域 shapeDrawable.draw(canvas);//绘制图片

paint.setShader(linearGradient);//绘制线性渲染 canvas.drawRect(200,0,320,50, paint);

paint.setShader(composeShaper);//绘制混合渲染 canvas.drawRect(200,55,320,105, paint);

paint.setShader(radialGradient);//绘制环形渲染 canvas.drawRect(200,200,320,250, paint);

paint.setShader(sweepGradient);//绘制梯度渲染 canvas.drawRect(200,110,320,160, paint); } }

================================================================================================================================================= 第九部分 双缓冲技术

原理:当一个动画争先显示时,程序又在改变它,前面的还没画完,程序又请求重新绘制,这时就会出现闪屏。为避免这种情况,可以使用双缓冲技术,将要处理好的的图片

在内存中处理好之后,再将其显示到屏幕上。Android中SurfaceView类本身就是一个双缓冲机制,所以游戏开发中用SurfaceView用得更多,效率也更高。下例是针对View类实现 双缓冲技术的例子。

public class BufferView extends View implements Runnable{-----------???

Bitmap bitmap1= null;

Bitmap bufferBitmap = null;//创建缓冲区

Canvas canvas1 = null; Paint paint = null;

public BufferView(Context context) { super(context); bitmap1 =

((BitmapDrawable)getResources().getDrawable(R.drawable.qq)).getBitmap();//装载资源

bufferBitmap = Bitmap.createBitmap(320,480,Config.ARGB_8888);//创建屏幕大小的缓冲区

canvas1 = new Canvas();//创建画布(程序中出现了两块画布) paint = new Paint();

canvas1.setBitmap(bufferBitmap);//将内容绘制在bufferBitmap缓冲区上,可理解为将缓冲区作为画布。

canvas1.drawBitmap(bitmap1, 0,0, paint);//将图片绘制到缓冲区上

new Thread(this).start(); }

public void onDraw(Canvas canvas){ super.onDraw(canvas);

canvas.drawBitmap(bufferBitmap, 0,0, paint);//将bufferBitmap缓冲区上画布绘制到屏幕上去 }

@Override public void run() {

while(!Thread.currentThread().isInterrupted()){ try{

Thread.sleep(200); }catch(Exception e){

Thread.currentThread().interrupt(); }

postInvalidate(); } } }

================================================================================================================================================= 第十部分 全屏显示及获取屏幕属性

如果想像G1游戏那样,当我们把手机屏幕横放时,应用程序会自动变为横屏模式。其实可以通过下面两个方法实现这个功能。

法一:双击AndroidManifest.xml文件,选择Application选项卡,选中Activity类,再找到Screen orientation选项 ,选择 senor 最后保存即可。在真机上就能看到效果

法二:在AndroidManifest.xml文件中设计如下中加入android:screenOrientation=\即可。如下:

public class FullScreen extends Activity{

public TextView textView_FullScreen;//定义一个TextView来显示屏幕属性 public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);//通过requestWindowFeature方法来设置为无标题栏

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//通过setFlags方法设置为全屏模式

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//通过setRequestedOrientation方法来设置为横屏 setContentView(R.layout.fullscreen);

textView_FullScreen =

(TextView)this.findViewById(R.id.textView_FullScreen);//得到TextView对象

DisplayMetrics displayMetrics = new DisplayMetrics();//定义DisplayMetrics对象,DisplayMetrics定义了屏幕的一些属性

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);//通过getMetrics方法来取得窗口属性

int screenWidth = displayMetrics.widthPixels;//得到窗口宽度 int screenHeight = displayMetrics.heightPixels;//得到窗口高度

textView_FullScreen.setText(\屏幕宽度:\屏幕高度:\} }

第十一部分 Tween动画 第一种方法 在代码中设计

public class AnimationView extends View{ public Animation animationAlpha = null; public Animation animationScale = null; public Animation animationTranslate = null; public Animation animationRotate = null;

Bitmap bitmap1 = null;

public AnimationView(Context context) { super(context); bitmap1 =

((BitmapDrawable)getResources().getDrawable(R.drawable.dog)).getBitmap();//加载资源 }

public void onDraw(Canvas canvas){ canvas.drawBitmap(bitmap1, 50,100, null); }

public boolean onKeyUp(int keyCode,KeyEvent event){ switch(keyCode){ /*

* Alpha透明度动画效果。其属性设置格式为: * AlphaAnimation(float fromAlpha,float toAlpha) * fromAlpha---为动画起始时透明度

* toAlpha---动画结束时透明度(0.0表示完全透明,1.0表示完全不透明) *

* setDuration(long durationMillis);设置动画显示的时间 单位为毫秒 * startAnimation(Animation animation);开始播放动画 */

case KeyEvent.KEYCODE_DPAD_UP:

animationAlpha = new AlphaAnimation(0.0f, 1.0f);//创建Alpha动画 animationAlpha.setDuration(3000);//动画持续时间 this.startAnimation(animationAlpha);//开始播放动画 break; /*

* Scale伸缩动画效果.。其属性设置如下:

* ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue)

* fromX,toX 为起始和结束时x坐标上的伸缩尺寸 * fromY,toY 为起始和结束时y坐标上的伸缩尺寸 * pivotXType,pivotYType 分别为x,y的伸缩模式

* pivotXVale,pivotYVale 分别为伸缩动画相对于x,y的坐标开始位置 */

case KeyEvent.KEYCODE_DPAD_DOWN:

animationScale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,

0.5f, Animation.RELATIVE_TO_SELF, 0.5f);//创建Scale动画 animationScale.setDuration(500);//动画持续的时间 this.startAnimation(animationScale);//开始播放动画 /*

* Translate移动动画效果。其属性设置如下:

* TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta) * fromXDelta ,fromYDelta 分别为起始x,y坐标

* toXDelta,toYDelta 分别为终点时x,y坐标 */

case KeyEvent.KEYCODE_DPAD_LEFT:

animationTranslate = new TranslateAnimation(10, 100, 10, 100);//创建Translate动画

animationTranslate.setDuration(1000);//动画持续时间 this.startAnimation(animationTranslate);//开始播放动画 break; /*

* Rotate旋转动画效果

* RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue) * fromDegrees 开始角度 * toDegrees 结束角度

* pivotXValue , pivotYValue 伸缩动画相对于x,y的坐标坐标开始位置 * pivotXType,pivotYType 分别为x,y的伸缩模式 */

case KeyEvent.KEYCODE_DPAD_RIGHT: animationRotate = new RotateAnimation(0.0f, 360f, Animation.RELATIVE_TO_SELF,

0.5f, Animation.RELATIVE_TO_SELF, 0.5f);//创建Rotate动画 animationRotate.setDuration(1000);//动画持续时间 this.startAnimation(animationRotate);//动画播放 }

return true; }

} 需在Activity种实例化

------------------------------------------------------------------------------------------------------- 第二种方法 xml设计 aipha.xml

android:fromAlpha=\

android:toAlpha=\android:duration=\/>

rotate.xml

android:interpolator=\ android:fromDegrees=\ android:toDegrees=\ android:pivotX=\ android:pivotY=\ android:duration=\ scale.xml

android:interpolator=\ android:fromXScale=\android:toXScale=\ android:fromYScale=\android:toYScale=\ android:pivotX=\android:pivotY=\ android:fillAfter=\android:duration=\ translate.xml

android:fromXDelta=\android:toXDelta=\android:fromYDelta=\android:toYDelta=\android:duration=\/>

public class GameView extends View{

private Animation mAnimationAlpha = null;//定义Alpha动画 private Animation mAnimationScale = null;//定义Scale动画 private Animation mAnimationTranslate = null;//定义Translate动画 private Animation mAnimationRotate = null;//定义Rotate动画

Bitmap mBitQQ = null;//定义Bitmap对象 Context mContext = null;

public GameView(Context context){ super(context); mContext = context;

mBitQQ = ((BitmapDrawable)

getResources().getDrawable(R.drawable.qq)).getBitmap();//装载资源 }

public void onDraw(Canvas canvas){ super.onDraw(canvas);

canvas.drawBitmap(mBitQQ, 0, 0, null);//绘制图片 }

public boolean onKeyUp(int keyCode, KeyEvent event){ switch ( keyCode ){

case KeyEvent.KEYCODE_DPAD_UP:

mAnimationAlpha = AnimationUtils.loadAnimation(mContext,R.layout.alpha);//装载动画布局

this.startAnimation(mAnimationAlpha);//开始播放动画 break;

case KeyEvent.KEYCODE_DPAD_DOWN:

mAnimationScale = AnimationUtils.loadAnimation(mContext,R.layout.scale);//装载动画布局

this.startAnimation(mAnimationScale);//开始播放动画 break;

case KeyEvent.KEYCODE_DPAD_LEFT: mAnimationTranslate =

AnimationUtils.loadAnimation(mContext,R.layout.translate);//装载动画布局 this.startAnimation(mAnimationTranslate);//开始播放动画 break;

case KeyEvent.KEYCODE_DPAD_RIGHT: mAnimationRotate =

AnimationUtils.loadAnimation(mContext,R.layout.rotate);//装载动画布局 this.startAnimation(mAnimationRotate);//开始播放动画 break; }

return true; } }

=================================================================================================================================== Framed动画

第一种方法 在代码中设计

public class GameView extends View{

private AnimationDrawable animationDrawable = null;//定义AnimationDrawable装载动画 Context mContext = null;

Drawable mBitAnimation = null;//定义一个Drawable对象 public GameView(Context context){ super(context); mContext = context;

animationDrawable = new AnimationDrawable();//实例化AnimationDrawable对象

for (int i = 1; i <= 15; i++){//利用循环装载所有名字类似的资源(图片命名时是有规律的 所以才能用此循环)

int id = getResources().getIdentifier(\mContext.getPackageName());------------------------需要深入 mBitAnimation = getResources().getDrawable(id);

animationDrawable.addFrame(mBitAnimation, 500);//通过addFrame方法把每一帧添加进去,每一帧显示的时间为500毫秒 }

animationDrawable.setOneShot( false );//利用setOneShot方法设置播放模式是否循环false表示循环而true表示不循环

this.setBackgroundDrawable(animationDrawable);// 加载本类将要显示这个动画 }

public void onDraw(Canvas canvas){ super.onDraw(canvas); }

public boolean onKeyUp(int keyCode, KeyEvent event){ switch ( keyCode ){

case KeyEvent.KEYCODE_DPAD_UP:

animationDrawable.start();//最后通过start方法播放动画 break; }

return true; }

} 要想显示Frame动画,还要在Activity中添加GameView对象 ------------------------------------------------------------------------------ 第二种方法:在XML文件中的设计 frameanimation.xml

public class GameView extends View{

private AnimationDrawable frameAnimation = null; Context mContext = null;

public GameView(Context context){ super(context); mContext = context;

ImageView img = new ImageView(mContext);//定义一个ImageView用来显示动画

img.setBackgroundResource(R.anim.frameanimation);//装载动画布局文件

frameAnimation = (AnimationDrawable) img.getBackground();//构建动画

frameAnimation.setOneShot( false ); //设置是否循环

this.setBackgroundDrawable(frameAnimation);//设置该类显示的动画 }

public void onDraw(Canvas canvas){ super.onDraw(canvas); }

public boolean onKeyUp(int keyCode, KeyEvent event){ switch ( keyCode ){

case KeyEvent.KEYCODE_DPAD_UP:

frameAnimation.start();//开始播放动画 break; }

return true; }

} 还许要在Acitivity类中实例化GameView对象才能显示。

=================================================================================================================================================== GIF动画播放

其原理:首先需要对GIF动画图像进行解码,然后将GIF中的每一帧分别提取出来保存到一个容器中,然后根据需要绘制每一帧,这样就可以轻松地实现GIF动画的播放了。

下面有个例子,可以在工作中直接使用。

public class GifDecoder{ private int E0; private int E1[]; private int E2; private int E6; private boolean E7; private int E8[]; private int width; private int height; private int ED; private boolean EE; private boolean EF; private int F0[]; private int F1; private boolean F2; private int F3; private long F4; private int F5;

private static final int F6[] = { 8, 8, 4, 2 };

private static final int F8[] = { 0, 4, 2, 1 }; int curFrame; int poolsize; int FA; byte C2[]; int FB; int FC; int FD;

public GifDecoder(byte abyte0[]){ E0 = -1;

E1 = new int[280]; E2 = -1; E6 = 0; E7 = false; E8 = null; width = 0; height = 0; ED = 0; EE = false; EF = false; F0 = null; F1 = 0; F5 = 0; curFrame = 0; C2 = abyte0; poolsize = C2.length; FA = 0; }

public boolean moreFrames(){ return poolsize - FA >= 16; }

public void nextFrame(){ curFrame++; }

public Bitmap decodeImage(){

return decodeImage(curFrame); }

public Bitmap decodeImage(int i){ if (i <= E0){ return null; }

if (E0 < 0){ if (!E3()){ return null; } if (!E4()){ return null; } } do{ if (!E9(1)){ return null; }

int j = E1[0]; if (j == 59){ return null; }

if (j == 33){ if (!E7()){ return null; } }

else if (j == 44){ if (!E5()){ return null; }

Bitmap image = createImage(); E0++; if (E0 < i){ image = null;

}else{ return image; } } }

while (true); }

public void clear(){ C2 = null; E1 = null; E8 = null; F0 = null; }

private Bitmap createImage(){ int i = width; int j = height; int j1 = 0; int k1 = 0;

int ai[] = new int[4096]; int ai1[] = new int[4096]; int ai2[] = new int[8192]; if (!E9(1)){ return null; }

int k = E1[0];

int[] image = new int[width * height]; int ai3[] = E8; if (EE){ ai3 = F0; }

if (E2 >= 0){ ai3[E2] = 0xffffff; }

int l2 = 1 << k; int j3 = l2 + 1;

int k2 = k + 1; int l3 = l2 + 2; int k3 = -1; int j4 = -1;

for (int l1 = 0; l1 < l2; l1++){ ai1[l1] = l1; } int j2 = 0; E2(); j1 = 0;

label0: for (int i2 = 0; i2 < j; i2++){ int i1 = 0; do{ if (i1 >= i){ break; }

if (j2 == 0){ int i4 = E1(k2); if (i4 < 0){

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

if (i4 > l3 || i4 == j3){

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

if (i4 == l2){ k2 = k + 1; l3 = l2 + 2; k3 = -1; continue; }

if (k3 == -1){ ai2[j2++] = ai1[i4]; k3 = i4; j4 = i4; continue;

} int i3 = i4; if (i4 == l3){ ai2[j2++] = j4; i4 = k3; }

for (; i4 > l2; i4 = ai[i4]){ ai2[j2++] = ai1[i4]; }

j4 = ai1[i4]; if (l3 >= 4096){

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

ai2[j2++] = j4; ai[l3] = k3; ai1[l3] = j4;

if (++l3 >= 1 << k2 && l3 < 4096){ k2++; } k3 = i3; }

int l = ai2[--j2]; if (l < 0){

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

if (i1 == 0){ FC = 0; FB = ai3[l]; FD = 0;

}else if (FB != ai3[l]){

for (int mm = FD; mm <= FD + FC; mm++){ image[j1 * width + mm] = FB; } FC = 0; FB = ai3[l];

FD = i1; if (i1 == i - 1){

image[j1 * width + i1] = ai3[l]; } }else{ FC++; if (i1 == i - 1){

for (int mm = FD; mm <= FD + FC; mm++){ image[j1 * width + mm] = FB; } } } i1++; }

while (true); if (EF){ j1 += F6[k1]; do{ if (j1 < j){ continue label0; }

if (++k1 > 3){

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

j1 = F8[k1]; }

while (true); } j1++; }

return Bitmap.createBitmap(image, width, height, Config.RGB_565); }

private int E1(int i){ while (F5 < i){ if (F2){

return -1; }

if (F1 == 0){ F1 = E8(); F3 = 0; if (F1 <= 0){ F2 = true; break; } }

F4 += E1[F3] << F5; F3++; F5 += 8; F1--; }

int j = (int) F4 & (1 << i) - 1; F4 >>= i; F5 -= i; return j; }

private void E2(){ F5 = 0; F1 = 0; F4 = 0L; F2 = false; F3 = -1; }

private boolean E3(){ if (!E9(6)){ return false; }

return E1[0] == 71 && E1[1] == 73 && E1[2] == 70 && E1[3] == 56 && (E1[4] == 55 || E1[4] == 57) && E1[5] == 97; }

private boolean E4(){

if (!E9(7)){ return false; }

int i = E1[4]; E6 = 2 << (i & 7); E7 = EB(i, 128); E8 = null;

return !E7 || E6(E6, true); }

private boolean E5(){ if (!E9(9)){ return false; }

width = EA(E1[4], E1[5]); height = EA(E1[6], E1[7]); int i = E1[8]; EE = EB(i, 128); ED = 2 << (i & 7); EF = EB(i, 64); F0 = null;

return !EE || E6(ED, false); }

private boolean E6(int i, boolean flag){ int ai[] = new int[i]; for (int j = 0; j < i; j++){ if (!E9(3)){ return false; }

ai[j] = E1[0] << 16 | E1[1] << 8 | E1[2] | 0xff000000; } if (flag){ E8 = ai; }else{ F0 = ai; }

本文来源:https://www.bwwdw.com/article/w74w.html

Top