android游戏开发——简单的例子(笑脸)


程序运行效果图:

android游戏开发——简单的例子(笑脸)


代码实现:

1、MainActivity

package com.njupt.surface;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener{

	
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MySurfaceView(this));
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


	@Override
	public void onClick(View v) {
		
	}


	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		GameData.clickX = (int) ev.getX();
		GameData.clickY = (int) ev.getY();
		
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			GameData.clickType = GameData.DOWN;
			break;
		case MotionEvent.ACTION_MOVE:
			GameData.clickType = GameData.MOVE;
			break;
		case MotionEvent.ACTION_UP:
			GameData.clickType = GameData.UP;
			break;
			
		default:
			break;
		}
		return super.dispatchTouchEvent(ev);
	}


	/**
	 * 根据当前activity加载的view的大小有关
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		return super.onTouchEvent(event);
	}
    
	
    
}


2、MySurfaceView

package com.njupt.surface;

import java.util.ArrayList;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


/**
 * ①展现游戏界面
 * ②控制游戏界面
 */
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{

	private SurfaceHolder sh;//SurfaceView的管理器,不直接和SurfaceView打交道
	private boolean isDestroy = false;
	private Canvas canvas;//画纸
	private Paint paint;//画笔
	private int sW = 0;
	private int sH = 0;
	private ArrayList<Smile> list = new ArrayList<Smile>();
	private Resources res;
	
	/**
	 * ①绘制灰色背景
	 * ②绘制fps,帧率:每秒钟屏幕刷新的次数
	 * ③绘制按钮
	 * ④绘制小人,实现按钮的业务
	 * ⑤绘制笑脸
	 * 
	 */
	public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public MySurfaceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public MySurfaceView(Context context) {
		super(context);
		
		res = context.getResources();
		init();
		sh = this.getHolder();//获取当前view管理者
		sh.addCallback(this);
		
		paint = new Paint();
		paint.setTextSize(30);
		paint.setAntiAlias(true);//设置抗锯齿
	}

	private Bitmap[] bm = new Bitmap[10];
	private int w1 = 0;
	private int h1 = 0;
	private int w2 = 0;
	private int h2 = 0;
	
	
	/**
	 * 加载图片资源
	 */
	private void init() {
		//加载drable下的资源可以使用BitmapFactory
		bm[0] = BitmapFactory.decodeResource(res, R.drawable.left01);
		bm[1] = BitmapFactory.decodeResource(res, R.drawable.left02);
		bm[2] = BitmapFactory.decodeResource(res, R.drawable.top);
		bm[3] = BitmapFactory.decodeResource(res, R.drawable.top2);
		bm[4] = BitmapFactory.decodeResource(res, R.drawable.right01);
		bm[5] = BitmapFactory.decodeResource(res, R.drawable.right02);
		bm[6] = BitmapFactory.decodeResource(res, R.drawable.bottom);
		bm[7] = BitmapFactory.decodeResource(res, R.drawable.bottom2);
		bm[8] = BitmapFactory.decodeResource(res, R.drawable.avatar_boy);//人物
		bm[9] = BitmapFactory.decodeResource(res, R.drawable.rating_small);//笑脸
		
		w1 = bm[0].getWidth();
		h1 = bm[0].getHeight();
		w2 = bm[2].getWidth();
		h2 = bm[2].getHeight();
		
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		
		sW = this.getWidth();//不要在surfaceCreate()方法中那这两个值,因为那时view可能还没完全生成...
		sH = this.getHeight();
		
		GameData.screenX = sW;
		GameData.screenY = sH;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		new Thread(this).start();
		fpsThread();
	}

	private int fps = 0;
	private int count = 0;//计数,屏幕每刷新一次+1
	private void fpsThread() {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(!isDestroy){
					fps = count;
					count = 0;
					
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		isDestroy = true;
	}

	@Override
	public void run() {
		
		while(!isDestroy){
			canvas = sh.lockCanvas();//锁定画布,得到画布
			draw();
			count++;
			sh.unlockCanvasAndPost(canvas);//提交画好的画布,显示到屏幕
		}
	}

	
	/**
	 * 小人的初始位置...
	 */
	private int px = 10;
	private int py = 30;
	
	private int space = 5;//小人移动的距离
	
	/**
	 * 游戏界面的绘制
	 */
	private void draw() {
//		canvas.drawColor(Color.GRAY);
		paint.setColor(Color.GRAY);
		canvas.drawRect(0,0,sW,sH, paint);
		paint.setColor(Color.GREEN);
		canvas.drawText(String.valueOf(fps), 10, sH - 20, paint);
	
	    tickBtn();//应付事件,做相应处理
	    drawBtn();
	    
	    
	    canvas.drawBitmap(bm[8], px,py, null);//绘制小人
	    
	    drawSmile();//绘制笑脸...
	}

	/**
	 * 绘制笑脸...
	 */
	private void drawSmile() {
		
		for(int i = list.size() - 1 ; i >= 0 ; --i){
			Smile smile = list.get(i);
			
			if(smile.isDestroy()){
				list.remove(i);
			}
		}
		
		for(int i = 0 ; i < list.size() ; ++i){
			Smile smile = list.get(i);
			smile.draw(canvas);
		}
	}

	private void tickBtn() {
		switch (GameData.clickType) {
		case GameData.DOWN:
			if(!btn()){
				createSmile();
				GameData.clickType = 0;//防止笑脸一直创建...
			}
			
			break;

		case GameData.MOVE://用于处理手指一开始不在按钮上,但是滑到了按钮上的情况...
			btn();
			break;
			
		case GameData.UP:
			left = 0;
			top = 0;
			right = 0;
			bottom = 0;
			
			break;
		default:
			break;
		}
	}

	private void createSmile() {
		Smile smile = new Smile(bm[9],new Point(px+50,py+50),new Point(GameData.clickX,GameData.clickY),0.02f);
	    
		list.add(smile);
	}

	/**
	 * 用于点击按钮时,将按钮的图片换掉...
	 * 使用boolean作为返回值是为了解决点击按钮时也产生笑脸的bug。。。
	 */
	private boolean btn() {
		int x = GameData.clickX;
		int y = GameData.clickY;
		
		//判断是否点击了左边按钮
		if(10 < x && x < 10+w1 && sH-100 < y && y < sH-100+h1){
			left = 1;//用于将图片切换掉...
			px -= space;//用于改变小人的位置
			
			return true;
		}
		
		//判断是否点击了上边按钮
		if(60 < x && x < 60+w2 && sH-150 < y && y < sH-150+h2){
			top = 1;
			py -= space;
			
			return true;
		}
		
		if(110 < x && x < 100+w1 && sH-100 < y && y < sH-100+h1){
			right = 1;
			px += space;
			
			return true;
		}
		
		if(60 < x && x < 60+w2 && sH-60 < y && y < sH-60+h2){
			bottom = 1;
			py += space;
			
			return true;
		}
		
		return false;
	}

	private int left = 0;
	private int top = 0;
	private int right = 0;
	private int bottom = 0;
	private void drawBtn() {
		canvas.drawBitmap(bm[0 + left], 10,sH-100 ,null);//绘制左边按钮
		canvas.drawBitmap(bm[2 + top], 60,sH-150 ,null);
		canvas.drawBitmap(bm[4 + right], 110,sH-100 ,null);
		canvas.drawBitmap(bm[6 + bottom], 60,sH-60 ,null);
		
	}

	
	
	
}


3、GameData

package com.njupt.surface;

public class GameData {

	public static int clickX = 0;
	public static int clickY = 0;
	public static int clickType = 0;//记录当前和屏幕交换的状态
	
	public final static int DOWN = 1;
	public final static int MOVE = 2;
	public final static int UP = 3;
	
	public static int screenX = 0;
	public static int screenY = 0;
}


4、Smile

package com.njupt.surface;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;

public class Smile {
	private Bitmap bm;
	private Point sp;//笑脸的起点
	private Point ep;//笑脸的终点
	private float space;
	
	public Smile(Bitmap bm, Point sp, Point ep, float space) {
		super();
		this.bm = bm;
		this.sp = sp;
		this.ep = ep;
		this.space = space;
		
		px = sp.x;
		py = sp.y;
	}
	
	private int px = 0;
	private int py = 0;
	public void draw(Canvas canvas){
		canvas.drawBitmap(bm, px, py,null);
		tick();
		
		if(GameData.screenX < px || px < -bm.getWidth() || py < - bm.getHeight() || py > GameData.screenY){
			isDestroy = true;
		}
	}
	
	/**
	 * 用于改变笑脸的位置
	 */
	private void tick() {
		if(ep.x > sp.x){
			px += (ep.x - sp.x)*space;
		}else if(sp.x > ep.x){
			px -= (sp.x - ep.x)*space;
		}
		
		if(ep.y > sp.y){
			py += (ep.y - sp.y)*space;
		}else{
			py -= (sp.y - ep.y)*space;
		}
	}

	
	private boolean isDestroy = false;
	public boolean isDestroy(){
		return isDestroy;
	}
}


android游戏开发——简单的例子(笑脸)

上一篇:Android Touch事件分发机制


下一篇:Android查看应用的最大可用内存及其使用情况