Android SurfaceView实现游戏2048[三]

来源:互联网 发布:世界10大云计算公司 编辑:程序博客网 时间:2024/05/14 02:22

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

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

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#FFBBADA1"    android:orientation="vertical" >        <LinearLayout         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        android:background="#b2000000"        android:padding="5dip"        >        <TextView             android:layout_width="0dip"            android:layout_height="wrap_content"            android:text="@string/app_name"            android:layout_gravity="center_vertical"            android:paddingLeft="5dip"            android:textSize="20sp"            android:textColor="@android:color/white"            android:layout_weight="1.0"            />        <ImageView             android:id="@+id/refresh_btn"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/ic_action_refresh"            android:paddingRight="5dip"            android:contentDescription="@null"            />    </LinearLayout>        <com.walk.game2048.GameView         android:id="@+id/game_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        />    </LinearLayout>
其中,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);}@Overridepublic 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();}}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isRun = true;mThread = new Thread(this);mThread.start();}@Overridepublic 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);}}}@Overridepublic boolean onTouchEvent(MotionEvent event) {return mContext.getLogic().onTouchEvent(event);}}

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

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

0 0
原创粉丝点击