我是靠谱客的博主 难过毛衣,最近开发中收集的这篇文章主要介绍扫雷Android版详解版本程序有两个类,分别为GameView.java和Main.java,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本程序有两个类,分别为GameView.java和Main.java

GameView.java

package org.yexing.android.games.mine;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Main extends Activity {

 GameView gameView;
 @Override
 public void onCreate(Bundle icicle) {
  super.onCreate(icicle);
  gameView = new GameView(this);
  setContentView(gameView);
 }

 @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  gameView.gameState = GameView.STATE_LOST;
  super.onPause();
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  // TODO Auto-generated method stub
  gameView.onKeyDown(keyCode, event);
  return super.onKeyDown(keyCode, event);
 }
 G
 @Override
 public boolean onKeyUp(int keyCode, KeyEvent event) {
  // TODO Auto-generated method stub
  gameView.onKeyUp(keyCode, event);
  return super.onKeyUp(keyCode, event);
 }

}

package org.yexing.android.games.mine;

import java.util.Random;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

public class GameView extends View {
 private static final String TAG = "GameView";

 private RefreshHandler mRedrawHandler = new RefreshHandler();

 class RefreshHandler extends Handler {

  @Override
  public void handleMessage(Message msg) {
   GameView.this.updateView();
   GameView.this.invalidate();
  }

  public void sleep(long delayMillis) {
   this.removeMessages(0);
   sendMessageDelayed(obtainMessage(0), delayMillis);
  }
 };

 // 游戏状态 开始 胜利 失败 暂停
 public static final int STATE_PLAYING = 0;
 public static final int STATE_WIN = 1;
 public static final int STATE_LOST = 2;
 public static final int STATE_PAUSE = 3;
 public int gameState;
 //随机
 private static final Random random = new Random();
 //画笔
 private Paint paint;
 //发送消息
 private String message;
 //格子的宽度
 private static final int tileWidth = 16;
 private static final int tileHeight = 16;
 //格子的数量
 private static final int tilesCount = 19;
 private static final int margin = 16;
 private static final int titleHeight = 30;
 //棋子
 private Bitmap[] tiles;
 //表面层
 private int[][] mapSky;
 //底层
 private int[][] mapGround;
 
 private int tileCountX, tileCountY;
 private int offsetX, offsetY;
 //雷的数量
 int mineCount;
 //没有雷的方格的个数
 int safeCount;

 private int mapX, mapY;
 private boolean altKeyDown = false;
 //
 private static final int MILLIS_PER_TICK = 500;
 long startTime, lastTime;
 long time, remain;

 public GameView(Context context) {
  super(context);
  //设置画笔的属性
  paint = new Paint();
  paint.setARGB(255, 60, 60, 200);
  paint.setTextSize(12);
  //Bitmap在Android中指的是一张图片,可以是png,也可以是jpg等其他图片格式。
  tiles = new Bitmap[tilesCount];//tilesCount = 19;
  loadTiles();  
  setFocusable(true);//获得焦点
 }
/***
 * 将资源图片的ID放入tiles数组中
 */
 private void loadTiles() {
  Resources r = this.getContext().getResources();
  for (int i = 0; i < tilesCount; i++) {//初始存下19个不同的图片
   tiles[i] = BitmapFactory.decodeResource(r, R.drawable.i00 + i);
  }
 }
 
/***
 * 初始化第一层
 */
 //根据获取的尺寸渲染到view
 @Override
 protected void onLayout(boolean changed, int left, int top, int right,
   int bottom) {
  // TODO Auto-generated method stub
  super.onLayout(changed, left, top, right, bottom);
  // if(Main.gameState == Main.STATE_START)
  init(right - left, bottom - top);
  //获取当前的时间
  startTime = System.currentTimeMillis();
  //刷新屏幕
  updateView();

 }
 
   /***
    * 初始化地图,根据屏幕的长宽计算地图中格子的数量,和边缘的宽度
    * @param 宽
    * @param 高
    */
 private void init(int w, int h) {
  mapX = -1;
  mapY = -1;
  //求一个浮点数的地板,就是求一个最接近它的整数,它的值小于或等于这个浮点数。
  //在X方向上格子的数量
  tileCountX = (int) Math.floor((w - margin * 2) / tileWidth);
  //在Y方向上格子的数量
  tileCountY = (int) Math.floor((h - margin * 2 - titleHeight) / tileHeight);
  //x方向上边缘的宽度
  offsetX = (w - (tileWidth * tileCountX)) / 2;
  //在y方向上边缘的宽度
  offsetY = (h - (tileHeight * tileCountY) + titleHeight) / 2;
  //雷的数量
  mineCount = (int) Math.sqrt(tileCountX * tileCountY) * tileCountX
    * tileCountY / 100;//雷数
  //重置
  reset();
 }
/***
 * 初始化两层地图,并放雷
 */
 private void reset() {
  int x, y;
  mapSky = new int[tileCountX][tileCountY];
  mapGround = new int[tileCountX][tileCountY];
 
  for (int i = 0; i < mineCount; i++) {
   // put down mines
   do {
    //随机生成一个随机的int值介于(0~titlecountX)
    x = random.nextInt(tileCountX);
    y = random.nextInt(tileCountY);
   } while (mapGround[x][y] == 12);//避免在重复的位置布雷,设置循环
   mapGround[x][y] = 12;//12指的是有雷的那幅图片
           //周围8个相邻地方格子
   increase(x - 1, y - 1);
   increase(x - 1, y);
   increase(x - 1, y + 1);
   increase(x, y + 1);
   increase(x + 1, y + 1);
   increase(x + 1, y);
   increase(x + 1, y - 1);
   increase(x, y - 1);
  }
  // set empty tile to image i09 设置空的地域
  for (x = 0; x < tileCountX; x++) {
   for (y = 0; y < tileCountY; y++) {
    if (mapGround[x][y] == 0)
     mapGround[x][y] = 9;
   }
  }
  safeCount = tileCountX * tileCountY - mineCount;//安全的方格数
  time = 0;
  remain = mineCount;//剩余雷数
  altKeyDown = false;
  // shuffle();
 }

 private void increase(int x, int y) {
  if (x > -1 && x < tileCountX && y > -1 && y < tileCountY) {
   if (mapGround[x][y] != 12)
    mapGround[x][y]++;
  }
 }

 @Override
 public void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // Log.v(TAG, "onDraw");
  if (altKeyDown) {//红旗的图标是否未按下样式
   canvas.drawARGB(255, 255, 0, 0);
   canvas.drawBitmap(tiles[17], 30, 0, paint);
  } else {
   canvas.drawBitmap(tiles[16], 30, 0, paint);
  }

  if (gameState != STATE_LOST) {//判断笑脸与哭脸
   canvas.drawBitmap(tiles[18], 0, 0, paint);
  } else {
   canvas.drawBitmap(tiles[15], 0, 0, paint);
  }

  message = "剩余:" + remain + "  耗时" + time + "秒";
  canvas.drawText(message, 0, message.length(), 80, 15, paint);

  for (int x = 0; x < tileCountX; x += 1) {
   for (int y = 0; y < tileCountY; y += 1) {
    //创建一个矩形,最终形成一个格状的
    Rect rDst = new Rect(offsetX + x * tileWidth, offsetY + y
      * tileHeight, offsetX + (x + 1) * tileWidth, offsetY
      + (y + 1) * tileHeight);
    canvas.drawBitmap(tiles[mapGround[x][y]], null, rDst, paint);//根据数组中的数字对应画出相应的图片
    if (gameState != STATE_LOST) {
     if (mapSky[x][y] > -1) {
      canvas.drawBitmap(tiles[mapSky[x][y]], null, rDst,
        paint);
      // canvas.drawPoint(rDst.left, rDst.top, p);
     }
    } else {
     if (mapGround[x][y] != 12 && mapSky[x][y] == 10) {
      mapSky[x][y] = 14;//游戏失败后,指明插红旗的雷
     }
     if (mapSky[x][y] > -1 && mapGround[x][y] != 12
       || mapSky[x][y] == 13 || mapSky[x][y] == 10) {
      canvas.drawBitmap(tiles[mapSky[x][y]], null, rDst,
        paint);//失败后保持状态的格子
      // canvas.drawPoint(rDst.left, rDst.top, p);
     }
    }
   }
  }

 }

 private void updateView() {
  Log.v(TAG, "updateView");
  if (gameState == STATE_PLAYING) {
   time = (System.currentTimeMillis() - startTime) / 1000;
   mRedrawHandler.sleep(MILLIS_PER_TICK);
  }
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {

  int action = event.getAction();
  int x = (int) event.getX();
  int y = (int) event.getY();
  // Log.v(LOG_TAG, "action:" + action + " x:" + x + " y:" + y);

  if (action == MotionEvent.ACTION_DOWN) {
   // Log.v(TAG, "Checking start ********");
   mapX = screenX2mapX(x);
   mapY = screenY2mapY(y);

   if (gameState != STATE_LOST && mapX > -1 && mapY > -1) {
    if (gameState == STATE_PAUSE) {
     gameState = STATE_PLAYING;
     startTime = System.currentTimeMillis();
     updateView();
    }

    if (altKeyDown) {//当ALt按下时 插旗
     if (mapSky[mapX][mapY] == 0) {
      mapSky[mapX][mapY] = 10;
      remain--;
     } else if (mapSky[mapX][mapY] == 10) {
      remain++;
      mapSky[mapX][mapY] = 11;
     } else if (mapSky[mapX][mapY] == 11) {
      mapSky[mapX][mapY] = 0;
     } else if (mapSky[mapX][mapY] == -1) {//模拟扫雷左右键同时按下,sky层没有被初始化的时候为-1
      int flags = flag(mapX - 1, mapY - 1)
        + flag(mapX - 1, mapY)
        + flag(mapX - 1, mapY + 1)
        + flag(mapX, mapY + 1)
        + flag(mapX + 1, mapY + 1)
        + flag(mapX + 1, mapY)
        + flag(mapX + 1, mapY - 1)
        + flag(mapX, mapY - 1);
      if (flags == mapGround[mapX][mapY]) {
       Log.v(TAG, "flags:" + flags);
       open(mapX - 1, mapY - 1);
       open(mapX - 1, mapY);
       open(mapX - 1, mapY + 1);
       open(mapX, mapY + 1);
       open(mapX + 1, mapY + 1);
       open(mapX + 1, mapY);
       open(mapX + 1, mapY - 1);
       open(mapX, mapY - 1);
      }
     }
    } else {
     open(mapX, mapY);
    }
    invalidate();
   } else {
    if (x < 26 && y < 26) {
     gameState = STATE_PAUSE;
     reset();
     invalidate();
    }
    if (x > 30 && x < 56 && y > 0 && y < 26) {
     altKeyDown = !altKeyDown;
     invalidate();
    }
   }
  }
  return true;
 }

 private int flag(int x, int y) {
  if (x > -1 && x < tileCountX && y > -1 && y < tileCountY) {
   if (mapSky[x][y] == 10)
    return 1;
  }
  return 0;
 }

 public void open(int x, int y) {
  if (x > -1 && x < tileCountX && y > -1 && y < tileCountY) {
   if (mapSky[x][y] == -1)
    return;
   if (mapSky[x][y] == 0 || mapSky[x][y] == 11) {
    if (mapGround[x][y] == 12) {
     mapSky[x][y] = 13;
     gameState = STATE_LOST;
    } else {
     mapSky[x][y] = -1;
     safeCount--;
     if (safeCount == 0) {
      gameState = STATE_WIN;
     }
     if (mapGround[x][y] == 9) {
      open(x - 1, y - 1);
      open(x - 1, y);
      open(x - 1, y + 1);
      open(x, y + 1);
      open(x + 1, y + 1);
      open(x + 1, y);
      open(x + 1, y - 1);
      open(x, y - 1);
     }
    }
   }
  }
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  switch (keyCode) {
  case KeyEvent.KEYCODE_MENU:
   altKeyDown = true;
   return true;
  }
  return super.onKeyDown(keyCode, event);
 }

 @Override
 public boolean onKeyUp(int keyCode, KeyEvent event) {
  // TODO Auto-generated method stub
  switch (keyCode) {
  case KeyEvent.KEYCODE_MENU:
   altKeyDown = false;
   return true;
  }
  return super.onKeyUp(keyCode, event);
 }

 private int screenX2mapX(int c) {//得到横轴所在的格子
  if (c - offsetX < 0)
   return -1;
  int rtn = (c - offsetX) / tileWidth;
  if (rtn >= tileCountX)
   return -1;
  return rtn;
 }

 private int screenY2mapY(int c) {//得到纵轴所在的格子
  if (c - offsetY < 0)
   return -1;
  int rtn = (c - offsetY) / tileHeight;
  if (rtn >= tileCountY)
   return -1;
  return rtn;
 }

}

 

 

Main.java

package org.yexing.android.games.mine;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Main extends Activity {

    GameView gameView;
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        gameView = new GameView(this);
        //显示视图
        setContentView(gameView);
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        gameView.gameState = GameView.STATE_LOST;
        super.onPause();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        gameView.onKeyDown(keyCode, event);
        return super.onKeyDown(keyCode, event);
    }
    
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        gameView.onKeyUp(keyCode, event);
        return super.onKeyUp(keyCode, event);
    }

}

 

最后

以上就是难过毛衣为你收集整理的扫雷Android版详解版本程序有两个类,分别为GameView.java和Main.java的全部内容,希望文章能够帮你解决扫雷Android版详解版本程序有两个类,分别为GameView.java和Main.java所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部