之前写过的技术类博客很少,如果写的不好还请大家见谅!

在这个系列中,我会以实例的形式来讲解android游戏的所有开发的步骤,估计会有8-10个游戏会陆续的跟大家见面的,由于自己本身现在在上班,所以时间不是很充裕,一般会在每周日定时更新博客,而每一周至少更新一个游戏的所有相关内容。




首先要编写android中的游戏,要了解android在游戏开发的过程中要用到的两个类view、SurfaceView,另外还有一个GLSurfaceview主要是编写3D游戏的好像,现在自己涉及的比较少,所以在这里也不会讲。

View与SurfaceView有什么区别呢,我想大家在网上也能找到很多相关的答案,自己也在这里再重复一下别人的总结,当然也是自己在开发中的体会。

SurfaceView和View最本质的区别在于,surfaceView可以在一个新起的单独线程中重新绘制画面而View必须在UI的主线程中更新画面,所以这就有问题发生了,当我们重新绘制画面所要耗费的时间比较的长时,那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。

   当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中 thread处理,一般就需要有一个事件队列的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。

  所以基于以上,根据游戏特点,一般分成两类。

  1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是触摸屏幕来更新,可以直接使用 invalidate或postInvalidate(在后面会详细讲解一下这两个函数的区别) ,因为这种情况下,这一次触摸屏幕和下一次的触摸屏幕需要的时间比较长些,不会产生影响。

所以五子棋也就要用View来写了。

下面开始上代码:

主要是绘制棋盘与棋子的部分

public class GameView extends View {

	//屏幕的宽和高
	private int screenWidth = 0;
	private int screenHeight = 0;
	//画棋盘的起始位置
	private int startX = 0;
	private int startY = 0;
	//棋盘中每个格子的高和宽
	private int GRID_WIDTH = 40;
	private int GRID_NUM = 12;//要画的棋盘中的线数
	private Paint paint = null;
	
	//表示棋子的二维数组,其中数组中的每一个元素代表棋盘上的一个点
	private int[][] chess = new int[GRID_NUM][GRID_NUM];
	private int CHESS_BLACK = 1;//表示棋子的颜色,1代表黑色,2代表白色,0达标没有棋子
	private int CHESS_WHITE = 2;
	private int chess_flag = 0;//用于记录上一次下的棋子的颜色,1为黑色,2为白色,0是刚开始下棋,上一次没下棋子
	
	public GameView(Context context) {
		super(context);
		
		paint = new Paint();//实例化一个画笔
		paint.setColor(0xff000000);//设置画笔的颜色
		paint.setAntiAlias(true);//设置画笔去锯齿,没有此语句,画的线或图片周围不圆滑
		
	}
	
	@Override
	protected void onDraw(Canvas canvas) {//重写View中的该方法,该方法主要承担绘图的工作,每刷新一次,就调用一次该方法
		super.onDraw(canvas);
		
		canvas.drawColor(0xffd700);//把屏幕的底色绘成黄色,此处不仅仅是起把屏幕绘成这种颜色的作用,还有刷屏的作用,对以前绘制的进行清除
		paint.setColor(0x458b00);//此处是把画笔变成绿色,是绘制的棋盘变成绿色
		
		for(int i=0;i<GRID_NUM;i++)
		{
			//画横线
			canvas.drawLine(startX, startY+i*GRID_WIDTH,startX+(GRID_NUM-1)*GRID_WIDTH , startY+i*GRID_WIDTH, paint);
			//画纵线
			canvas.drawLine(startX+i*GRID_WIDTH, startY,startX+i*GRID_WIDTH , startY+(GRID_NUM-1)*GRID_WIDTH, paint);
		}
		
		//绘制棋子
		for(int i=0;i<GRID_NUM;i++)
		{
			for(int j=0;j<GRID_NUM;j++)
			{
				if(chess[i][j] == CHESS_BLACK)
				{
					paint.setColor(0xff000000);//黑色画笔,画黑棋
					canvas.drawCircle(startX+i*GRID_WIDTH,startY+j*GRID_WIDTH , 15, paint);
				}
				if(chess[i][j] == CHESS_WHITE)
				{
					paint.setColor(0xffffffff);//白色画笔,画白棋
					canvas.drawCircle(startX+i*GRID_WIDTH,startY+j*GRID_WIDTH , 15, paint);
				}
			}
		}
	}

	//重写View的监听触摸事件的方法
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		float touchX = event.getX();
		float touchY = event.getY();
		
		if(touchX < startX || touchX>startX+(GRID_NUM-1)*GRID_WIDTH || touchY < startY || touchY>startY+(GRID_NUM-1)*GRID_WIDTH)
		{//点击到棋盘以外的位置
			System.out.println("......哥们点跑偏了,呵呵");
		}
		else
		{
			//根据点击的位置,从而获知在棋盘上的哪个位置,即是数组的脚标
			int index_x = Math.round((touchX-startX)/GRID_WIDTH);
			int index_y = Math.round((touchY-startY)/GRID_WIDTH);
			
			System.out.println("..."+index_x+"..."+index_y);
			System.out.println("...startX"+startX+"...touchX"+touchX);
			
			
			if(chess_flag == 0)
			{//此句表示在最开始下棋的时候每次都是黑棋先下
				chess[index_x][index_y] = CHESS_BLACK;
				chess_flag = CHESS_BLACK;
				
			}else if( chess_flag == CHESS_BLACK && chess[index_x][index_y] == 0)
			{
				chess[index_x][index_y] = CHESS_WHITE;
				chess_flag = CHESS_WHITE;
			}else if(chess_flag == CHESS_WHITE && chess[index_x][index_y] == 0)
			{
				chess[index_x][index_y] = CHESS_BLACK;
				chess_flag = CHESS_BLACK;
			}
		}
		
		invalidate();//点击完成后,通知重绘即再次执行onDraw方法
		return super.onTouchEvent(event);
	}	
}

 

函数中的 if( chess_flag == CHESS_BLACK && chess[index_x][index_y] == 0)的语句中的chess[index_x][index_y] == 0主要是判断当前位置上现在是否有棋子,如果有就不能再这个位置上再放置棋子了


效果图:

android做小游戏思路 android开发小游戏_android做小游戏思路

android做小游戏思路 android开发小游戏_游戏_02