Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果
来源:互联网 发布:手机淘宝怎么快速秒杀 编辑:程序博客网 时间:2024/06/05 21:52
SurfaceView是View的子类,常用于实现游戏中的动画效果。SurfaceView最大的特点就是:从主线程中,把具体的绘图线程独立出来。这样做的好处在于:当绘图任务比较繁重时,避免主线程的阻塞,从而提高主线程的反应速度。
废话少说,言归正传,下面用几个例子说明surfaceview的使用。
(一) 基本功能:用SurfaceView显示一副背景图片。 运行后的效果很简单,就是在屏幕上显示一副图片。
package com.pushBox;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;public class PushBoxActivity extends Activity {//欢迎界面WelcomeView welcomeView = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //显示欢迎界面 welcomeView = new WelcomeView( this ); setContentView( welcomeView ); } //内部类,欢迎界面 class WelcomeView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private WelcomeViewDrawThread welcomeViewDrawThread; //背景图片,大小640 * 480 Bitmap background; //图片显示的位置 int backgroundX = 0; int backgroundY = 0; public WelcomeView( Context context ) { super( context ); holder = this.getHolder(); holder.addCallback( this ); background = BitmapFactory.decodeResource( getResources(), R.drawable.background ); //创建一个绘图线程 welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder ); } //自定义的绘图函数,具体的绘图在这里完成 public void onDraw( Canvas c ) { c.drawBitmap( background, backgroundX, backgroundY, null ); } @Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stub//启动绘图线程welcomeViewDrawThread.setFlag( true );welcomeViewDrawThread.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubwelcomeViewDrawThread.setFlag( false );} } //内部类,欢迎界面的绘图线程 class WelcomeViewDrawThread extends Thread { private WelcomeView welcomeView; private SurfaceHolder holder; private boolean isRun; private int sleepSpan = 200; public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder ) { this.welcomeView = welcomeView; this.holder = holder; isRun = true; } public void setFlag( boolean flag ) { isRun = flag; }@Overridepublic void run() {// TODO Auto-generated method stubwhile( isRun ){Canvas c = null;try{c = holder.lockCanvas();synchronized( holder ){//调用绘图函数welcomeView.onDraw( c );}}finally{if( c != null ){holder.unlockCanvasAndPost( c );}}try{//睡眠200毫秒Thread.sleep( sleepSpan );}catch(Exception e){e.printStackTrace();}}} }}
(二) 初露锋芒:用SurfaceView显示一个动态打开的门。运行后的效果,左右两扇门缓缓打开。
如果只用SurfaceView显示一副背景图片,那绝对是“大炮打蚊子”------大材小用。从主线程中拉出一个单独的线程,就是为了处理动态效果。这里具体实现的时候有两个线程:welcomeViewGoThread和welcomeViewDrawThread。welcomeViewGoThread只负责修改图片显示的坐标,welcomeViewDrawThread负责在具体的位置显示图片。这种进一步分离,使得各模块的功能更加独立和明确。
package com.pushBox;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.os.Bundle;import android.view.SurfaceHolder;import android.view.SurfaceView;public class PushBoxActivity extends Activity {//欢迎界面WelcomeView welcomeView = null;//欢迎界面的动画线程WelcomeViewGoThread welcomeViewGoThread = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //显示欢迎界面 welcomeView = new WelcomeView( this ); setContentView( welcomeView ); welcomeViewGoThread = new WelcomeViewGoThread( welcomeView ); //启动动画线程 welcomeViewGoThread.start(); } //内部类,欢迎界面 class WelcomeView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private WelcomeViewDrawThread welcomeViewDrawThread; //背景图片,大小640 * 480 Bitmap background; //左边的木门,大小180 * 450 Bitmap leftWood; Bitmap rightWood; //图片显示的位置 int backgroundX = 0; int backgroundY = 0; int leftWoodX = 10; int leftWoodY = 15; int rightWoodX = 150; int rightWoodY = 15; public WelcomeView( Context context ) { super( context ); holder = this.getHolder(); holder.addCallback( this ); background = BitmapFactory.decodeResource( getResources(), R.drawable.background ); leftWood = BitmapFactory.decodeResource( getResources(), R.drawable.image33 ); rightWood = BitmapFactory.decodeResource( getResources(), R.drawable.image3 ); //创建一个绘图线程 welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder ); } //自定义的绘图函数,具体的绘图在这里完成 public void onDraw( Canvas c ) { c.drawBitmap( background, backgroundX, backgroundY, null ); c.drawBitmap( leftWood, leftWoodX, leftWoodY, null ); c.drawBitmap( rightWood, rightWoodX, rightWoodY, null ); } @Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stub//启动绘图线程welcomeViewDrawThread.setFlag( true );welcomeViewDrawThread.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubwelcomeViewDrawThread.setFlag( false );} } //内部类,欢迎界面的动画线程,只修改坐标,不负责具体显示 class WelcomeViewGoThread extends Thread { private WelcomeView welcomeView; private int sleepSpan = 200; private boolean isRun; public WelcomeViewGoThread( WelcomeView welcomeView ) { this.welcomeView = welcomeView; isRun = true; } public void setFlag( boolean flag ) { isRun = flag; } @Override public void run() { // TODO Auto-generated method stub while( isRun ) { // 修改木门坐标 welcomeView.leftWoodX -= 2; welcomeView.rightWoodX += 2; if( welcomeView.leftWoodX < -90 ) { welcomeView.leftWoodX = 10; welcomeView.rightWoodX = 150; } try{ //睡眠200毫秒 Thread.sleep( sleepSpan ); } catch(Exception e){ e.printStackTrace(); } } } } //内部类,欢迎界面的绘图线程 class WelcomeViewDrawThread extends Thread { private WelcomeView welcomeView; private SurfaceHolder holder; private boolean isRun; private int sleepSpan = 200; public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder ) { this.welcomeView = welcomeView; this.holder = holder; isRun = true; } public void setFlag( boolean flag ) { isRun = flag; }@Overridepublic void run() {// TODO Auto-generated method stubwhile( isRun ){Canvas c = null;try{c = holder.lockCanvas();synchronized( holder ){//调用绘图函数welcomeView.onDraw( c );}}finally{if( c != null ){holder.unlockCanvasAndPost( c );}}try{//睡眠200毫秒Thread.sleep( sleepSpan );}catch(Exception e){e.printStackTrace();}}} }}
(三) 脱胎换骨:修改程序框架。
上述的程序框架有问题,所有代码都放在一个文件里。下面要做的就是把相关的class都独立出来。代码改起来也很简单,只要把几个内部类单独写到一个文件即可。
(四) 重出江湖:用SurfaceView实现一个完整的欢迎界面
- Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果
- 推箱子游戏开发(一) surfaceView 实现动画效果
- Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动
- Android开发入门——推箱子游戏开发实战(二)
- Android开发入门——推箱子游戏开发实战(三)
- Android开发入门——推箱子游戏开发实战(四)
- Android开发入门——推箱子游戏开发实战(五)
- Android开发入门——推箱子游戏开发实战(六)
- Android开发入门——推箱子游戏开发实战(七)
- Android开发入门——推箱子游戏开发实战(八)
- Android开发入门——推箱子游戏开发实战(九)
- Android开发入门——推箱子游戏开发实战(十)
- Android开发入门——推箱子游戏开发实战(十一)
- Android开发入门——推箱子游戏开发实战(十二)
- Android开发入门——推箱子游戏开发实战(十三)
- Android开发入门——推箱子游戏开发实战(十四)
- Android开发入门——推箱子游戏开发实战(十五,终结)
- C#入门学习-----推箱子游戏(WPF技术实现)
- getRequestDispatcher()与sendRedirect()的区别
- sql 2008远程链接
- linux下安装Qt/E
- 用java遍历所有当前运行环境
- 配置Vim编辑器设置Tab键的格数(长度)
- Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果
- 一笺梦
- bbs
- php 获取随机数
- Python语言中的按位运算
- JAVA [ HTTP ]
- hdu 3887 Counting Offspring
- 指针例子
- 网络编程初步认识(一)