Android SurfaceView实现游戏2048[三]

三、实现界面,兼容多分辨率

1.效果图在文章[一]中可看到。这里首先附上layout:



    
    
        
        
    
    
    
    


其中,refresh_btn用来重置/刷新,GameView就是游戏的SurfaceView了。

2.实现游戏部分界面

从之前的文章知道,每个滑块是一个Block对象。每个滑块是圆角矩形,宽是屏幕宽/4,高等于宽。当然,每个滑块在画的时候要加上Padding,不然就贴在一起了。这样 主要考虑下多分辨率了。解决适配问题,可基于一个分辨率定坐标,然后取当前屏幕大小,与基准分辨率比较获取到缩放比例。这里就不再赘述。

画圆角矩形,可用Canvas.drawRoundRect(RectF rectF, float dx, float dy, Paint paint)。

好了,下面附上画滑块的简单代码:

for (int row = 0; row < mBlocks.length; row++) {
				for (int column = 0; column < mBlocks[row].length; column++) {
					if (!mDraw[row * mBlocks[row].length + column]) {
						continue;
					}
					RectF rectF = new RectF();
					rectF.set(column * rectWidth + mScreenAdapter.getRectPadding(), 
							row * rectHeight + mScreenAdapter.getRectPadding(), 
							(column + 1) * rectWidth - mScreenAdapter.getRectPadding(), 
							(row + 1) * rectHeight - mScreenAdapter.getRectPadding());
					paint.setColor(mBlocks[row][column].getColor());
					mScreenAdapter.drawRoundRect(rectF, canvas, paint);
					paint.setTextSize(40.0f);
					paint.setColor(Color.BLACK);
					if (mBlocks[row][column] != mBlockObjArray.get(0)) {
						mScreenAdapter.drawText(String.valueOf(mBlocks[row][column].getNumber()), 
								column * rectWidth, row * rectHeight, 
								mScreenAdapter.getRectWidth(), mScreenAdapter.getRectHeight(), 
								canvas, paint);
					}
				}
			}

其中mDraw是一个一维数组,保存的是当前滑块是否可画,用来配合生成新滑块时的动画效果。mScreenAdapter是自己实现的一个适配分辨率的类。drawRoundRect实现上就是调用canvas的drawRoundRect。最后判断是不是空块,空块的话就不画数字。

最后附上GameView代码:

package com.walk.game2048;

import java.util.Date;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * 游戏View
 * @author walk
 *
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
	
	private boolean isRun = false;
	private Thread mThread = null;
	private SurfaceHolder mHolder;
	private Canvas mCanvas;
	private Paint mPaint;
	
	private GameActivity mContext;
	
	private static final int REFRESH_FRAME = 30;

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		mContext = (GameActivity) context;
		mHolder = getHolder();
		mHolder.addCallback(this);
		mHolder.setFormat(PixelFormat.TRANSLUCENT);
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		setZOrderOnTop(true);
	}

	@Override
	public void run() {
		Date date = null;
		while (isRun) {
			date = new Date();
			if (mContext.isClose()) {
				isRun = false;
			} else {
				mContext.getLogic().run();
				draw();
			}
			try {
				Thread.sleep(Math.max(0, REFRESH_FRAME - (new Date().getTime() - date.getTime())));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

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

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		isRun = true;
		mThread = new Thread(this);
		mThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		isRun = false;
	}
	
	private void draw () {
		try {
			if (mHolder != null) {
				mCanvas = mHolder.lockCanvas();
				mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
				mContext.getLogic().paint(mCanvas, mPaint);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (mCanvas != null) {
				mHolder.unlockCanvasAndPost(mCanvas);
			}
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return mContext.getLogic().onTouchEvent(event);
	}
	

}

由于时间关系,界面部分就到这了。做饭...

PS:文中如有不对之处,敬请指出!谢谢~

你可能感兴趣的:(Android游戏开发)