Android用SurfaceView写一个简单有趣的游戏--《数字组合》之一

来源:互联网 发布:linux已安装软件位置 编辑:程序博客网 时间:2024/06/05 15:00

最近突然有了一个想法--做一款android的简单游戏练练手,既要实现起来简单(毕竟只有一个人,框架什么的暂且就不用考虑了),又要能够达到对android知识框架的复习和游戏要有可玩性,终于用了几个星期写完了。和大家分享分享体会吧。

      本来打算写一个专栏的。看以后的时间吧。

     首先介绍一下游戏的主要思想和SurfaceView也就是游戏主界面的代码分享,后续部分再更新吧。

     在点击 开始游戏 后,进行组合数字的选择,根据难易程度系统默认选择2和8,选择界面中间显示选择的组合数字,第一个数字表示第一个组合数字,
        即在游戏过程中能被整除的那个数字,第二个数字表示第二个组合数字,即在游戏过程中不能被整除的那个数字。选择结束后开始游戏。
        在游戏准备完成后开始游戏,随机下落一定范围内的数字,判断该数字是否被第一个组合数字整除而不能被第二个数字整除,若是,点击该数字,分数加上对应值,否则分数减去对应值。
        下落数字的范围会随着等级的提升变大。下落速度和数字的产生速度也为随之加快。当分数小于0或错过的正确值大于5时游戏结束!

截图

  

1.游戏主界面activity

package com.gymyang.number.views;import android.graphics.BitmapFactory;import android.view.KeyEvent;import android.view.View;import com.gymyang.number.BaseActivity;import com.gymyang.number.R;import com.gymyang.number.utils.DeviceTools;import com.gymyang.number.utils.GlobalFields;/** *  Class Name: NumberGameActivity.java *  Function: *  主逻辑activity *     Modifications:    *   *  @author Administrator  *  @DateTime 2014-11-11 下午8:09:55     *  @version 1.0  */public class NumberGameActivity extends BaseActivity{private GameView gameView;//private TextView noticeTx;@Overrideprotected void initView(){loadResource();//setContentView(R.layout.game_view);//gameView = (GameView) findViewById(R.id.game_view_main);//noticeTx = (TextView) findViewById(R.id.game_view_notice);gameView = new GameView(this,this);setContentView(gameView);}/** *  Function: * 加载资源 *  @author Administrator  *  @DateTime 2014-11-12 上午9:22:40 */private void loadResource(){GlobalFields.DEVICE_WIDTH = DeviceTools.getDeviceInfo(this)[0];GlobalFields.DEVICE_HEIGHT = DeviceTools.getDeviceInfo(this)[1];GlobalFields.BG_GRAY = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_gray); GlobalFields.BG_GREEN = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_green); GlobalFields.BG_WHITE = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_white); GlobalFields.BG_RED = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_red);GlobalFields.NUMBER_1 = BitmapFactory.decodeResource(getResources(), R.drawable.num1);GlobalFields.NUMBER_2 = BitmapFactory.decodeResource(getResources(), R.drawable.num2);GlobalFields.NUMBER_3 = BitmapFactory.decodeResource(getResources(), R.drawable.num3);GlobalFields.PAUSE_BG = BitmapFactory.decodeResource(getResources(), R.drawable.pause_bg);GlobalFields.PAUSE_BTNBG = BitmapFactory.decodeResource(getResources(), R.drawable.pause_button_bg);GlobalFields.scaleWidth = GlobalFields.DEVICE_WIDTH / (float)GlobalFields.BG_GRAY.getWidth();GlobalFields.scaleHeight = GlobalFields.DEVICE_HEIGHT / (float)GlobalFields.BG_GRAY.getHeight();GlobalFields.BG_GRAY = DeviceTools.resizeBitmap(GlobalFields.BG_GRAY);GlobalFields.PAUSE_BG = DeviceTools.resizeBitmap(GlobalFields.PAUSE_BG,GlobalFields.DEVICE_WIDTH / 5 *4, GlobalFields.DEVICE_HEIGHT / 4);GlobalFields.PAUSE_BTNBG = DeviceTools.resizeBitmap(GlobalFields.PAUSE_BTNBG,GlobalFields.DEVICE_WIDTH / 5 *2 - 10,GlobalFields.PAUSE_BG.getHeight() / 4);}@Overrideprotected void setListener(){}@Overrideprotected void logicWork(){}@Overridepublic void onClick(View v){}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event){if(keyCode == KeyEvent.KEYCODE_BACK){if(gameView.CURRENT_STATE == gameView.PREPARE_FINISH){gameView.CURRENT_STATE = gameView.GAME_PAUSE;}//MyWindowManager.showErrorDialog(getBaseContext(), "游戏暂停!");return true;}return super.onKeyDown(keyCode, event);}}


2.游戏主界面SurfaceView具体实现

package com.gymyang.number.views;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Paint.Align;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import com.gymyang.number.sprite.BaseSprite;import com.gymyang.number.sprite.LevelText;import com.gymyang.number.sprite.NumberBlock;import com.gymyang.number.sprite.NumberBlockManager;import com.gymyang.number.sprite.ScoreText;import com.gymyang.number.sprite.StateBar;import com.gymyang.number.sprite.TouchAble;import com.gymyang.number.utils.DeviceTools;import com.gymyang.number.utils.GlobalFields;import com.gymyang.number.utils.LevelManager;/** *  Class Name: GameView.java *  Function: *  大管家 *     Modifications:    *   *  @author Administrator  *  @DateTime 2014-11-11 下午10:36:53     *  @version 1.0  */public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable{/** GameView单例存在 */private static GameView gameView;public static GameView getInstance(){return gameView;}private NumberGameActivity activity;private SurfaceHolder surfaceHolder;private Paint paint;// 游戏进行状态private boolean flag = true;private Canvas canvas;/** 格子宽度 */public int BLOCK_WIDTH;/** 格子高度  */public int BLOCK_HEIGHT;/** 准备开始 */private final int PREPARE_START = 200;/** 准备完成*/public final int PREPARE_FINISH = 201;/** 游戏结束 */private final int GAME_OVER = 202;/** 暂停 */public final int GAME_PAUSE = 203;/** 当前进度状态 */public int CURRENT_STATE = PREPARE_START;/** * 格子对象集合 */private LinkedList<BaseSprite> blockSprites;/** 死掉了的精灵 */private List<BaseSprite> deadSprites;/** 数字格子管理 */private NumberBlockManager numberBlockManager;private StateBar stateBar;private float dp = 1;public GameView(Context context,NumberGameActivity activity){super(context);this.activity = activity;paint = new Paint();getHolder().addCallback(this);surfaceHolder = getHolder();gameView = this;GlobalFields.dp = DeviceTools.getScreenDensity(context);dp = GlobalFields.dp;}public GameView(Context context){super(context);paint = new Paint();getHolder().addCallback(this);surfaceHolder = getHolder();gameView = this;GlobalFields.dp = DeviceTools.getScreenDensity(context);dp = GlobalFields.dp;}@Overridepublic void surfaceCreated(SurfaceHolder holder){paint.setColor(Color.WHITE);paint.setTextSize(30*dp);GlobalFields.SCORE = 0;LevelManager.initChildren();BLOCK_WIDTH = GlobalFields.DEVICE_WIDTH / GlobalFields.CURRENT_COLUMNS;BLOCK_HEIGHT = GlobalFields.DEVICE_HEIGHT / GlobalFields.CURRENT_LINES;blockSprites = new LinkedList<BaseSprite>();deadSprites = new ArrayList<BaseSprite>();numberBlockManager = new NumberBlockManager();stateBar = new StateBar();resetBitmap();new Thread(this){}.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height){}@Overridepublic void surfaceDestroyed(SurfaceHolder holder){}/** *  Function: * 拉伸格子背景资源 *  @author Administrator  *  @DateTime 2014-11-12 下午2:57:30 */private void resetBitmap(){GlobalFields.BG_GREEN = DeviceTools.resizeBitmap(GlobalFields.BG_GREEN,BLOCK_WIDTH,BLOCK_HEIGHT);GlobalFields.BG_RED = DeviceTools.resizeBitmap(GlobalFields.BG_RED,BLOCK_WIDTH,BLOCK_HEIGHT);GlobalFields.BG_WHITE = DeviceTools.resizeBitmap(GlobalFields.BG_WHITE,BLOCK_WIDTH,BLOCK_HEIGHT);}@Overridepublic void run(){while (flag) {synchronized (surfaceHolder) {try {canvas = surfaceHolder.lockCanvas();canvas.drawBitmap(GlobalFields.BG_GRAY, 0, 0, paint);updateState();ondraw(canvas);} catch (Exception e) {// TODO: handle exception} finally {if(canvas != null){surfaceHolder.unlockCanvasAndPost(canvas);}}}try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}}/** *  Function: * 更新状态 *  @author Administrator  *  @DateTime 2014-11-12 下午3:37:47 */private void updateState(){deadSprites.clear();for(BaseSprite sprite : blockSprites){if(!sprite.isAlive()){deadSprites.add(sprite);}}blockSprites.removeAll(deadSprites);}/** *  Function: *  *  @author Administrator  *  @DateTime 2014-11-11 下午11:31:45 *  @param canvas2 */private void ondraw(Canvas canvas){if(CURRENT_STATE == PREPARE_START){drawDevideLines(canvas);}else if(CURRENT_STATE == PREPARE_FINISH){drawDevideLines(canvas);// 绘制数字格子numberBlockManager.drawSelf(canvas, paint);for(BaseSprite sprite : blockSprites){sprite.drawSelf(canvas, paint);}// 绘制状态栏drawStateBar(canvas);if(GlobalFields.MISSED < 0 || GlobalFields.SCORE < 0){CURRENT_STATE = GAME_OVER;}}else if(CURRENT_STATE == GAME_PAUSE){// TODO 游戏暂停drawPause(canvas);//canvas.drawText("游戏暂停", GlobalFields.DEVICE_WIDTH / 2 -20, GlobalFields.DEVICE_HEIGHT / 2 -20, paint);}else if(CURRENT_STATE == GAME_OVER){// TODO 游戏结束drawGameOver(canvas);}}private int overHeight = 0;/** *  Function: * 游戏结束 *  @author Administrator  *  @DateTime 2014-11-16 下午2:36:52 */private void drawGameOver(Canvas canvas){int preColor = paint.getColor();float textSize = paint.getTextSize();Align preTextStyle = paint.getTextAlign();paint.setColor(Color.RED);paint.setTextSize(32*dp);paint.setTextAlign(Paint.Align.CENTER);canvas.drawText("Game Over !",GlobalFields.DEVICE_WIDTH / 2,overHeight, paint);paint.setColor(preColor);paint.setTextSize(textSize);paint.setTextAlign(preTextStyle);if(overHeight < GlobalFields.DEVICE_HEIGHT / 2){overHeight += 50;}else if(overHeight >= GlobalFields.DEVICE_HEIGHT / 2 && overHeight < GlobalFields.DEVICE_HEIGHT / 2 + 20){overHeight += 5;}else if(overHeight >= GlobalFields.DEVICE_HEIGHT / 2 + 20 && overHeight < GlobalFields.DEVICE_HEIGHT){overHeight += 50;}else if(overHeight >= GlobalFields.DEVICE_HEIGHT){// TODO 回到主界面flag = false;activity.finish();}}private int pauseHeight = 0;private int pauseWidth = (GlobalFields.DEVICE_WIDTH - GlobalFields.PAUSE_BG.getWidth()) / 2;private int pauseTextHeight = pauseHeight + (GlobalFields.PAUSE_BG.getHeight() - GlobalFields.PAUSE_BTNBG.getHeight());/** 退出游戏 触摸区域 */private Rect exitTouchArea;/** 继续游戏 触摸区域 */private Rect goonTouchArea;/** *  Function: * 绘制暂停状态 *  @author Administrator  *  @DateTime 2014-11-16 下午1:33:12 */private void drawPause(Canvas canvas){if(exitTouchArea != null){exitTouchArea = null;}if(goonTouchArea != null){goonTouchArea = null;}exitTouchArea = new Rect(pauseWidth + 5, (pauseHeight +pauseTextHeight - 5),(pauseWidth + 5) + GlobalFields.PAUSE_BTNBG.getWidth(), (pauseHeight +pauseTextHeight - 5) + GlobalFields.PAUSE_BTNBG.getHeight());goonTouchArea = new Rect((pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5), (pauseHeight +pauseTextHeight - 5),(pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5) + GlobalFields.PAUSE_BTNBG.getWidth(), (pauseHeight +pauseTextHeight - 5) + GlobalFields.PAUSE_BTNBG.getHeight());int preColor = paint.getColor();float textSize = paint.getTextSize();Align preTextStyle = paint.getTextAlign();canvas.drawBitmap(GlobalFields.PAUSE_BG, pauseWidth, pauseHeight, paint);canvas.drawBitmap(GlobalFields.PAUSE_BTNBG, pauseWidth + 5, pauseHeight +pauseTextHeight - 5, paint);canvas.drawBitmap(GlobalFields.PAUSE_BTNBG, pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5,pauseHeight +pauseTextHeight - 5, paint);paint.setColor(Color.BLUE);paint.setTextSize(28*dp);paint.setTextAlign(Paint.Align.CENTER);canvas.drawText("游戏暂停",pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2,pauseHeight + GlobalFields.PAUSE_BG.getHeight() / 2, paint);paint.setTextSize(18*dp);canvas.drawText("返回菜单", pauseWidth + 5 + GlobalFields.PAUSE_BTNBG.getWidth() / 2, pauseHeight +pauseTextHeight + GlobalFields.PAUSE_BTNBG.getHeight() / 2, paint);canvas.drawText("继续游戏", pauseWidth + GlobalFields.PAUSE_BTNBG.getWidth()/2*3 + 5,pauseHeight +pauseTextHeight + GlobalFields.PAUSE_BTNBG.getHeight() / 2, paint);paint.setColor(preColor);paint.setTextSize(textSize);paint.setTextAlign(preTextStyle);if(pauseHeight < GlobalFields.DEVICE_HEIGHT / 2 - GlobalFields.PAUSE_BG.getHeight() / 2){pauseHeight += 60;}}/** *  Function: * 绘制状态栏 *  @author Administrator  *  @DateTime 2014-11-12 下午7:50:30 */private void drawStateBar(Canvas canvas){stateBar.drawSelf(canvas, paint);}private boolean isAddNumber = false;/** *  Function: *请求加入格子  *  @author Administrator  *  @DateTime 2014-11-12 下午3:22:09 */public void apply2AddNumber(){synchronized (surfaceHolder) {int raceWay = 0, number = 0;raceWay = (int) (Math.random() * GlobalFields.CURRENT_COLUMNS);number = (int) (Math.random() * GlobalFields.MAX_NUMBER + 1);isAddNumber = false;// TODO 添加数字格子if(blockSprites.size() > 0){//BaseSprite sprite = blockSprites.getLast();for(int i=blockSprites.size()-1 ; i>0 ;i--){BaseSprite sprite = blockSprites.get(i);if(sprite.locationX == raceWay){if(sprite.locationY > BLOCK_HEIGHT){blockSprites.add(new NumberBlock(raceWay, number));}isAddNumber = true;break;}}if(!isAddNumber){blockSprites.add(new NumberBlock(raceWay, number));isAddNumber = true;}}else{blockSprites.add(new NumberBlock(raceWay, number));isAddNumber = true;}}}/** *  Function: *请求加入加分显示 *  @author Administrator  *  @DateTime 2014-11-12 下午3:22:09 */public void apply2AddScoreText(int x,int y,String msg,int flag){synchronized (surfaceHolder) {// TODO 请求加入加分显示blockSprites.add(new ScoreText(x, y, msg, flag));}}/** *  Function: * 等级上升 *  @author Administrator  *  @DateTime 2014-11-13 下午12:07:36 */public void requestAddLevel(){synchronized (surfaceHolder) {// TODO 请求加入加分显示blockSprites.add(new LevelText());}}/** *  Function: * 请求重新绘制格子 *  @author Administrator  *  @DateTime 2014-11-13 下午12:07:36 */public void requestReDraw(){BLOCK_WIDTH = GlobalFields.DEVICE_WIDTH / GlobalFields.CURRENT_COLUMNS;BLOCK_HEIGHT = GlobalFields.DEVICE_HEIGHT / GlobalFields.CURRENT_LINES;DRAW_DEVIDE_LINE = 1;DRAW_DEVIDE_COLUMN = 1;DRAW_TIME = 1;i=1;j=1;k=1;SPACE=6;GlobalFields.BG_WHITE = DeviceTools.resizeBitmap(GlobalFields.BG_WHITE, BLOCK_WIDTH, BLOCK_HEIGHT);GlobalFields.BG_GREEN = DeviceTools.resizeBitmap(GlobalFields.BG_GREEN, BLOCK_WIDTH, BLOCK_HEIGHT);GlobalFields.BG_RED = DeviceTools.resizeBitmap(GlobalFields.BG_RED, BLOCK_WIDTH, BLOCK_HEIGHT);CURRENT_STATE = PREPARE_START;}/********************************** 传递触摸事件 **************************************/@Overridepublic boolean onTouchEvent(MotionEvent event){if(CURRENT_STATE == GAME_PAUSE){int x = (int) event.getX();int y = (int) event.getY();if (exitTouchArea.contains(x, y)) {CURRENT_STATE = GAME_OVER;pauseHeight = 0;return true;}if(goonTouchArea.contains(x, y)){CURRENT_STATE = PREPARE_FINISH;pauseHeight = 0;return true;}}else{for (BaseSprite sprite : blockSprites) {if (sprite instanceof TouchAble) {if (((TouchAble) sprite).onTouch(event)) {return true;}}}}return false;}/******************************** 绘制分割线 ****************************************/// 列分割线游标private int DRAW_DEVIDE_LINE = 1;// 行分割线游标private int DRAW_DEVIDE_COLUMN = 1;// 倒计时游标private int DRAW_TIME = 1;// 行列遍历 最大值int i=1,j=1,k=1,SPACE=6;/** *  Function: * 绘制分割线 *  @author Administrator  *  @DateTime 2014-11-12 上午9:31:11 */private void drawDevideLines(Canvas canvas){drawNotice();paint.setStyle(Paint.Style.STROKE);paint.setColor(Color.LTGRAY);// 绘制列分割线for(int x=1;x<=i;x++){canvas.drawLine(BLOCK_WIDTH * x, 0, BLOCK_WIDTH * x, GlobalFields.DEVICE_HEIGHT, paint);}if(DRAW_DEVIDE_LINE % SPACE == 0){i++;}if(i >= GlobalFields.CURRENT_COLUMNS){// 回归i,j 避免溢出i = GlobalFields.CURRENT_COLUMNS - 1;}else{DRAW_DEVIDE_LINE++;}// 绘制行分割线if(DRAW_DEVIDE_LINE >= (GlobalFields.CURRENT_COLUMNS - 1)*SPACE){for(int y=1;y<=j;y++){canvas.drawLine(0, BLOCK_HEIGHT * y, GlobalFields.DEVICE_WIDTH, BLOCK_HEIGHT * y, paint);}if(DRAW_DEVIDE_COLUMN % SPACE == 0){j++;}if(j >= GlobalFields.CURRENT_LINES){// 回归i,j 避免溢出j = GlobalFields.CURRENT_LINES - 1;}else{DRAW_DEVIDE_COLUMN++;}}// 准备倒计时if(DRAW_DEVIDE_COLUMN >= (GlobalFields.CURRENT_LINES - 1)*SPACE){int left = GlobalFields.DEVICE_WIDTH / 2 - GlobalFields.NUMBER_1.getWidth() / 2; int top = GlobalFields.DEVICE_HEIGHT / 2 - GlobalFields.NUMBER_1.getHeight() / 2; if(k == 1){canvas.drawBitmap(GlobalFields.NUMBER_3, left, top, paint);}else if(k == 2){canvas.drawBitmap(GlobalFields.NUMBER_2, left, top, paint);}else if(k == 3){canvas.drawBitmap(GlobalFields.NUMBER_1, left, top, paint);CURRENT_STATE = PREPARE_FINISH;}if(DRAW_TIME % SPACE == 0){k++;}if(k < 3){DRAW_TIME++;}}}private int noticeHeight = GlobalFields.DEVICE_HEIGHT/4*3;private void drawNotice(){int preColor = paint.getColor();float textSize = paint.getTextSize();Align preTextStyle = paint.getTextAlign();paint.setTextAlign(Paint.Align.CENTER);paint.setTextSize(16*dp);paint.setColor(Color.rgb(8, 103, 23));canvas.drawText("点击能被组合数字一:【"+GlobalFields.SENSETIVE_NUMBER+"】",GlobalFields.DEVICE_WIDTH / 2,noticeHeight, paint);canvas.drawText("但不能被组合数字二: 【"+GlobalFields.SENSETIVE_NUMBER2+"】 的数",GlobalFields.DEVICE_WIDTH / 2, noticeHeight+30, paint);canvas.drawText("等级越高!速度越快!数字越大!",GlobalFields.DEVICE_WIDTH / 2, noticeHeight+60, paint);canvas.drawText("你准备好了吗?",GlobalFields.DEVICE_WIDTH / 2, noticeHeight+90, paint);noticeHeight -= 20;paint.setColor(preColor);paint.setTextSize(textSize);paint.setTextAlign(preTextStyle);}}


 

1 0
原创粉丝点击