- 浏览: 582056 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (411)
- webservice (3)
- oracle (37)
- sqlserver (8)
- j2ee (56)
- linux (7)
- javaweb (47)
- office (1)
- struts (23)
- hibernate (11)
- spring (29)
- 网络 (2)
- tomcat (13)
- tongweb (0)
- weblogic (0)
- powerdesiginer (3)
- svn (3)
- js (20)
- ie (2)
- 编译 (3)
- css (2)
- 操作系统 (5)
- Android (41)
- jbpm4.3 (1)
- fckeditor (3)
- 操作excel (2)
- db2常用命令 (1)
- ibatis (5)
- mysql (16)
- 表达式语言 (1)
- java方式调用存储过程 (1)
- ca (1)
- linux客户端 (1)
- 电子数码 (1)
- 行业应用 (12)
- 开发工具 (4)
- 面试 (1)
- 计算机原理 (1)
- NOSQL (5)
- 虚拟机 (1)
- nginx (0)
- velocity (2)
- jndi (1)
- spring mvc (39)
- springmvc (32)
- 安全 (5)
- htmleditor (6)
- iphone4 (1)
- html (4)
- jstl (2)
- ckeditor (5)
- 连接池 (1)
- jquery (6)
- 分页 (1)
- 技术研发规则 (1)
- javamail (1)
- maven (2)
- upload (1)
- log (1)
- 测试 (10)
- spring roo (1)
- 版本控制 (2)
- find bugs (0)
- jsf (0)
- springroo (0)
- 小道理 (1)
- 小道理,技术标准 (1)
- jsf (0)
- bitbao (2)
- redmine (3)
- 团队意识 (1)
- mybatis (2)
- jquery mobile (1)
- flexpaper (0)
- json (4)
- URLRewriteFilte (1)
- html5 (1)
- 都乐保活动 (0)
- openfire (0)
- TreeMap (1)
- build (0)
- javaweb,tag (0)
- algorithm (1)
- tag (2)
- 扯淡 (0)
- mac (2)
- 叶一火(老一) (1)
- 游玩 (1)
- 编码 (1)
- 上线部署 (0)
- 研发管理 (0)
- thumbnailator (2)
- 旅游 (0)
- bingweibo (1)
- 杂谈 (4)
- ktv (1)
- weibo (1)
- 爱情 (2)
- 饮食 (1)
- MediaWiki (1)
- git (1)
- 版本库 (1)
- servlet (1)
- 感悟 (1)
- 人生 (1)
- highcharts (1)
- poi (0)
- websphere (0)
- php (1)
最新评论
-
woshixushigang:
good
org.springframework.beans.TypeMismatchException: Failed to convert property valu -
nathanleewei:
org.springframework.jdbc.core.B ...
org.springframework.beans.TypeMismatchException: Failed to convert property valu -
浪禾木:
请问是ckeditor\contents.css吗?改过以后 ...
ckeditor自动换行问题 -
simusuishi:
刚哥威武!
ckeditor取值赋值问题 -
a455642158:
收割完毕……
Android开源项目源码下载(不断更新中)
扫雷4Android(附源码)
最近由于项目需要学习了一下Android ,感觉汗不错。做了一个Android版的扫雷游戏。
游戏简介
在此游戏中,我们使用一个块的网格,其中有一些随机的地雷
下面是效果图
一、应用程序布局
使用TableLayout布局控件。设置3行。
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/back"> <TableRow> <TextView android:id="@+id/timer" android:layout_column="0" android:layout_width="fill_parent" android:layout_height="48px" android:gravity="center_horizontal" android:padding="5dip" android:textColor="#FFFFFF" android:textSize="35sp" android:text=" 0" /> <ImageButton android:id="@+id/smiley" android:layout_column="1" android:scaleType="center" android:padding="5dip" android:layout_width="48px" android:background="@drawable/smiley_button_states" android:layout_height="48px" /> <TextView android:id="@+id/minecount" android:layout_column="2" android:layout_width="fill_parent" android:layout_height="48px" android:gravity="center_horizontal" android:padding="5dip" android:textColor="#FFFFFF" android:textSize="35sp" android:text="000" /> </TableRow> <TableRow> <TextView android:layout_column="0" android:layout_height="50px" android:layout_width="fill_parent" android:layout_span="3" android:padding="10dip" /> </TableRow> <TableRow> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/minefield" android:layout_width="260px" android:layout_height="260px" android:gravity="bottom" android:stretchColumns="*" android:layout_span="3" android:padding="5dip"> </TableLayout> </TableRow> </TableLayout>
二、地雷块
Block.java
/** * 地雷的块,继承自Button * @author 记忆的永恒 * */ public class Block extends Button { private boolean isCovered; // 块是否覆盖 private boolean isMined; // 下个块 private boolean isFlagged; // 是否将该块标记为一个潜在的地雷 private boolean isQuestionMarked; // 是否是块的问题标记 private boolean isClickable; // 是否可以单击 private int numberOfMinesInSurrounding; // 在附近的地雷数量块 public Block(Context context) { super(context); // TODO Auto-generated constructor stub } public Block(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public Block(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 设置默认参数 */ public void setDefaults() { isCovered = true; isMined = false; isFlagged = false; isQuestionMarked = false; isClickable = true; numberOfMinesInSurrounding = 0; this.setBackgroundResource(R.drawable.square_blue); setBoldFont(); } public void setNumberOfSurroundingMines(int number) { this.setBackgroundResource(R.drawable.square_grey); updateNumber(number); } public void setMineIcon(boolean enabled) { this.setText("M"); if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED); } else { this.setTextColor(Color.BLACK); } } public void setFlagIcon(boolean enabled) { this.setText("F"); if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED); } else { this.setTextColor(Color.BLACK); } } public void setQuestionMarkIcon(boolean enabled) { this.setText("?"); if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED); } else { this.setTextColor(Color.BLACK); } } public void setBlockAsDisabled(boolean enabled) { if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); } else { this.setTextColor(R.drawable.square_blue); } } public void clearAllIcons() { this.setText(""); } private void setBoldFont() { this.setTypeface(null, Typeface.BOLD); } public void OpenBlock() { if (!isCovered) { return; } setBlockAsDisabled(false); isCovered = false; if (hasMine()) { setMineIcon(false); } else { setNumberOfSurroundingMines(numberOfMinesInSurrounding); } } public void updateNumber(int text) { if (text != 0) { this.setText(Integer.toString(text)); switch (text) { case 1: this.setTextColor(Color.BLUE); break; case 2: this.setTextColor(Color.rgb(0, 100, 0)); break; case 3: this.setTextColor(Color.RED); break; case 4: this.setTextColor(Color.rgb(85, 26, 139)); break; case 5: this.setTextColor(Color.rgb(139, 28, 98)); break; case 6: this.setTextColor(Color.rgb(238, 173, 14)); break; case 7: this.setTextColor(Color.rgb(47, 79, 79)); break; case 8: this.setTextColor(Color.rgb(71, 71, 71)); break; case 9: this.setTextColor(Color.rgb(205, 205, 0)); break; } } } public void plantMine() { isMined = true; } public void triggerMine() { setMineIcon(true); this.setTextColor(Color.RED); } public boolean isCovered() { return isCovered; } public boolean hasMine() { return isMined; } public void setNumberOfMinesInSurrounding(int number) { numberOfMinesInSurrounding = number; } public int getNumberOfMinesInSorrounding() { return numberOfMinesInSurrounding; } public boolean isFlagged() { return isFlagged; } public void setFlagged(boolean flagged) { isFlagged = flagged; } public boolean isQuestionMarked() { return isQuestionMarked; } public void setQuestionMarked(boolean questionMarked) { isQuestionMarked = questionMarked; } public boolean isClickable() { return isClickable; } public void setClickable(boolean clickable) { isClickable = clickable; } } 三、主界面 1.TableLayout动态添加行 mineField = (TableLayout)findViewById(R.id.MineField); private void showMineField() { for (int row = 1; row < numberOfRowsInMineField + 1; row++) { TableRow tableRow = new TableRow(this); tableRow.setLayoutParams(new LayoutParams((blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding)); for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { blocks[row][column].setLayoutParams(new LayoutParams( blockDimension + 2 * blockPadding, blockDimension + 2 * blockPadding)); blocks[row][column].setPadding(blockPadding, blockPadding, blockPadding, blockPadding); tableRow.addView(blocks[row][column]); } mineField.addView(tableRow,new TableLayout.LayoutParams( (blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding)); } }
2.定时器Handler
private Handler timer = new Handler(); private int secondsPassed = 0; public void startTimer(){ if (secondsPassed == 0) { timer.removeCallbacks(updateTimeElasped); // tell timer to run call back after 1 second timer.postDelayed(updateTimeElasped, 1000); } } public void stopTimer() { // disable call backs timer.removeCallbacks(updateTimeElasped); } // timer call back when timer is ticked private Runnable updateTimeElasped = new Runnable() { public void run() { long currentMilliseconds = System.currentTimeMillis(); ++secondsPassed; txtTimer.setText(Integer.toString(secondsPassed)); // add notification timer.postAtTime(this, currentMilliseconds); // notify to call back after 1 seconds // basically to remain in the timer loop timer.postDelayed(updateTimeElasped, 1000); } }; 3.第一次点击 private boolean isTimerStarted; // check if timer already started or not blocks[row][column].setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // start timer on first click if (!isTimerStarted) { startTimer(); isTimerStarted = true; } ... } });
4.第一次点击无雷
private boolean areMinesSet; // check if mines are planted in blocks blocks[row][column].setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { ... // set mines on first click if (!areMinesSet) { areMinesSet = true; setMines(currentRow, currentColumn); } } }); private void setMines(int currentRow, int currentColumn) { // set mines excluding the location where user clicked Random rand = new Random(); int mineRow, mineColumn; for (int row = 0; row < totalNumberOfMines; row++) { mineRow = rand.nextInt(numberOfColumnsInMineField); mineColumn = rand.nextInt(numberOfRowsInMineField); if ((mineRow + 1 != currentColumn) || (mineColumn + 1 != currentRow)) { if (blocks[mineColumn + 1][mineRow + 1].hasMine()) { row--; // mine is already there, don't repeat for same block } // plant mine at this location blocks[mineColumn + 1][mineRow + 1].plantMine(); } // exclude the user clicked location else { row--; } } int nearByMineCount; // count number of mines in surrounding blocks ... }
5.点击雷块的效果
private void rippleUncover(int rowClicked, int columnClicked) { // don't open flagged or mined rows if (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged()) { return; } // open clicked block blocks[rowClicked][columnClicked].OpenBlock(); // if clicked block have nearby mines then don't open further if (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0 ) { return; } // open next 3 rows and 3 columns recursively for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { // check all the above checked conditions // if met then open subsequent blocks if (blocks[rowClicked + row - 1][columnClicked + column - 1].isCovered() && (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0) && (rowClicked + row - 1 < numberOfRowsInMineField + 1) && (columnClicked + column - 1 < numberOfColumnsInMineField + 1)) { rippleUncover(rowClicked + row - 1, columnClicked + column - 1 ); } } } return; }
6.以问好标记空白
blocks[row][column].setOnLongClickListener(new OnLongClickListener() { public boolean onLongClick(View view) { // simulate a left-right (middle) click // if it is a long click on an opened mine then // open all surrounding blocks ... // if clicked block is enabled, clickable or flagged if (blocks[currentRow][currentColumn].isClickable() && (blocks[currentRow][currentColumn].isEnabled() || blocks[currentRow][currentColumn].isFlagged())) { // for long clicks set: // 1. empty blocks to flagged // 2. flagged to question mark // 3. question mark to blank // case 1. set blank block to flagged if (!blocks[currentRow][currentColumn].isFlagged() && !blocks[currentRow][currentColumn].isQuestionMarked()) { blocks[currentRow][currentColumn].setBlockAsDisabled(false); blocks[currentRow][currentColumn].setFlagIcon(true); blocks[currentRow][currentColumn].setFlagged(true); minesToFind--; //reduce mine count updateMineCountDisplay(); } // case 2. set flagged to question mark else if (!blocks[currentRow][currentColumn].isQuestionMarked()) { blocks[currentRow][currentColumn].setBlockAsDisabled(true); blocks[currentRow][currentColumn].setQuestionMarkIcon(true); blocks[currentRow][currentColumn].setFlagged(false); blocks[currentRow][currentColumn].setQuestionMarked(true); minesToFind++; // increase mine count updateMineCountDisplay(); } // case 3. change to blank square else { blocks[currentRow][currentColumn].setBlockAsDisabled(true); blocks[currentRow][currentColumn].clearAllIcons(); blocks[currentRow][currentColumn].setQuestionMarked(false); // if it is flagged then increment mine count if (blocks[currentRow][currentColumn].isFlagged()) { minesToFind++; // increase mine count updateMineCountDisplay(); } // remove flagged status blocks[currentRow][currentColumn].setFlagged(false); } updateMineCountDisplay(); // update mine display } return true; } });
7.记录胜负
// check status of the game at each step if (blocks[currentRow + previousRow][currentColumn + previousColumn].hasMine()) { // oops game over finishGame(currentRow + previousRow, currentColumn + previousColumn); } // did we win the game if (checkGameWin()) { // mark game as win winGame(); } private boolean checkGameWin() { for (int row = 1; row < numberOfRowsInMineField + 1; row++) { for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { if (!blocks[row][column].hasMine() && blocks[row][column].isCovered()) { return false; } } } return true; }
8.完整代码
MinesweeperGame.java package com.VertexVerveInc.Games; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; import android.widget.TableRow.LayoutParams; public class MinesweeperGame extends Activity { private TextView txtMineCount; private TextView txtTimer; private ImageButton btnSmile; private TableLayout mineField; private Block blocks[][]; // blocks for mine field private int blockDimension = 24; // width of each block private int blockPadding = 2; // padding between blocks private int numberOfRowsInMineField = 9; private int numberOfColumnsInMineField = 9; private int totalNumberOfMines = 10; // timer to keep track of time elapsed private Handler timer = new Handler(); private int secondsPassed = 0; private boolean isTimerStarted; // check if timer already started or not private boolean areMinesSet; // check if mines are planted in blocks private boolean isGameOver; private int minesToFind; // number of mines yet to be discovered /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test); txtMineCount = (TextView) findViewById(R.id.minecount); txtTimer = (TextView) findViewById(R.id.timer); btnSmile = (ImageButton) findViewById(R.id.smiley); btnSmile.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { endExistingGame(); startNewGame(); } }); mineField = (TableLayout)findViewById(R.id.minefield); showDialog("Click smiley to start New Game", 2000, true, false); } private void startNewGame() { createMineField(); // display all blocks in UI showMineField(); minesToFind = totalNumberOfMines; isGameOver = false; secondsPassed = 0; } private void createMineField() { // we take one row extra row for each side // overall two extra rows and two extra columns // first and last row/column are used for calculations purposes only // x|xxxxxxxxxxxxxx|x // ------------------ // x| |x // x| |x // ------------------ // x|xxxxxxxxxxxxxx|x // the row and columns marked as x are just used to keep counts of near // by mines blocks = new Block[numberOfRowsInMineField + 2][numberOfColumnsInMineField + 2]; for (int row = 0; row < numberOfColumnsInMineField + 2; row++) { for (int column = 0; column < numberOfColumnsInMineField + 2; column++) { blocks[row][column] = new Block(this); blocks[row][column].setDefaults(); // pass current row and column number as final int's to event // listeners // this way we can ensure that each event listener is associated // to // particular instance of block only final int currentRow = row; final int currentColumn = column; blocks[row][column].setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // start timer on first click if (!isTimerStarted) { startTimer(); isTimerStarted = true; } // set mines on first click if (!areMinesSet) { areMinesSet = true; setMines(currentRow, currentColumn); } // this is not first click // check if current block is flagged // if flagged the don't do anything // as that operation is handled by LongClick // if block is not flagged then uncover nearby blocks // till we get numbered mines if (!blocks[currentRow][currentColumn].isFlagged()) { // open nearby blocks till we get numbered blocks rippleUncover(currentRow, currentColumn); // did we clicked a mine if (blocks[currentRow][currentColumn].hasMine()) { // Oops, game over finishGame(currentRow, currentColumn); } // check if we win the game if (checkGameWin()) { // mark game as win winGame(); } } } }); // add Long Click listener // this is treated as right mouse click listener blocks[row][column] .setOnLongClickListener(new OnLongClickListener() { public boolean onLongClick(View view) { // simulate a left-right (middle) click // if it is a long click on an opened mine then // open all surrounding blocks if (!blocks[currentRow][currentColumn] .isCovered() && (blocks[currentRow][currentColumn] .getNumberOfMinesInSorrounding() > 0) && !isGameOver) { int nearbyFlaggedBlocks = 0; for (int previousRow = -1; previousRow < 2; previousRow++) { for (int previousColumn = -1; previousColumn < 2; previousColumn++) { if (blocks[currentRow + previousRow][currentColumn + previousColumn] .isFlagged()) { nearbyFlaggedBlocks++; } } } // if flagged block count is equal to nearby // mine count // then open nearby blocks if (nearbyFlaggedBlocks == blocks[currentRow][currentColumn] .getNumberOfMinesInSorrounding()) { for (int previousRow = -1; previousRow < 2; previousRow++) { for (int previousColumn = -1; previousColumn < 2; previousColumn++) { // don't open flagged blocks if (!blocks[currentRow + previousRow][currentColumn + previousColumn] .isFlagged()) { // open blocks till we get // numbered block rippleUncover( currentRow + previousRow, currentColumn + previousColumn); // did we clicked a mine if (blocks[currentRow + previousRow][currentColumn + previousColumn] .hasMine()) { // oops game over finishGame( currentRow + previousRow, currentColumn + previousColumn); } // did we win the game if (checkGameWin()) { // mark game as win winGame(); } } } } } // as we no longer want to judge this // gesture so return // not returning from here will actually // trigger other action // which can be marking as a flag or // question mark or blank return true; } // if clicked block is enabled, clickable or // flagged if (blocks[currentRow][currentColumn] .isClickable() && (blocks[currentRow][currentColumn] .isEnabled() || blocks[currentRow][currentColumn] .isFlagged())) { // for long clicks set: // 1. empty blocks to flagged // 2. flagged to question mark // 3. question mark to blank // case 1. set blank block to flagged if (!blocks[currentRow][currentColumn] .isFlagged() && !blocks[currentRow][currentColumn] .isQuestionMarked()) { blocks[currentRow][currentColumn] .setBlockAsDisabled(false); blocks[currentRow][currentColumn] .setFlagIcon(true); blocks[currentRow][currentColumn] .setFlagged(true); minesToFind--; // reduce mine count updateMineCountDisplay(); } // case 2. set flagged to question mark else if (!blocks[currentRow][currentColumn] .isQuestionMarked()) { blocks[currentRow][currentColumn] .setBlockAsDisabled(true); blocks[currentRow][currentColumn] .setQuestionMarkIcon(true); blocks[currentRow][currentColumn] .setFlagged(false); blocks[currentRow][currentColumn] .setQuestionMarked(true); minesToFind++; // increase mine count updateMineCountDisplay(); } // case 3. change to blank square else { blocks[currentRow][currentColumn] .setBlockAsDisabled(true); blocks[currentRow][currentColumn] .clearAllIcons(); blocks[currentRow][currentColumn] .setQuestionMarked(false); // if it is flagged then increment mine // count if (blocks[currentRow][currentColumn] .isFlagged()) { minesToFind++; // increase mine // count updateMineCountDisplay(); } // remove flagged status blocks[currentRow][currentColumn] .setFlagged(false); } updateMineCountDisplay(); // update mine // display } return true; } }); } } } private void showMineField() { for (int row = 1; row < numberOfRowsInMineField + 1; row++) { TableRow tableRow = new TableRow(this); tableRow.setLayoutParams(new LayoutParams( (blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding)); for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { blocks[row][column].setLayoutParams(new LayoutParams( blockDimension + 2 * blockPadding, blockDimension + 2 * blockPadding)); blocks[row][column].setPadding(blockPadding, blockPadding, blockPadding, blockPadding); tableRow.addView(blocks[row][column]); } mineField.addView(tableRow, new TableLayout.LayoutParams( (blockDimension + 2 * blockPadding) * numberOfColumnsInMineField, blockDimension + 2 * blockPadding)); } } private void endExistingGame() { stopTimer(); // stop if timer is running txtTimer.setText("000"); // revert all text txtMineCount.setText("000"); // revert mines count btnSmile.setBackgroundResource(R.drawable.smile); // remove all rows from mineField TableLayout mineField.removeAllViews(); // set all variables to support end of game isTimerStarted = false; areMinesSet = false; isGameOver = false; minesToFind = 0; } private boolean checkGameWin() { for (int row = 1; row < numberOfRowsInMineField + 1; row++) { for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { if (!blocks[row][column].hasMine() && blocks[row][column].isCovered()) { return false; } } } return true; } private void updateMineCountDisplay() { if (minesToFind < 0) { txtMineCount.setText(Integer.toString(minesToFind)); } else if (minesToFind < 10) { txtMineCount.setText("00" + Integer.toString(minesToFind)); } else if (minesToFind < 100) { txtMineCount.setText("0" + Integer.toString(minesToFind)); } else { txtMineCount.setText(Integer.toString(minesToFind)); } } private void winGame() { stopTimer(); isTimerStarted = false; isGameOver = true; minesToFind = 0; // set mine count to 0 // set icon to cool dude btnSmile.setBackgroundResource(R.drawable.cool); updateMineCountDisplay(); // update mine count // disable all buttons // set flagged all un-flagged blocks for (int row = 1; row < numberOfRowsInMineField + 1; row++) { for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { blocks[row][column].setClickable(false); if (blocks[row][column].hasMine()) { blocks[row][column].setBlockAsDisabled(false); blocks[row][column].setFlagIcon(true); } } } // show message showDialog("You won in " + Integer.toString(secondsPassed) + " seconds!", 1000, false, true); } private void finishGame(int currentRow, int currentColumn) { isGameOver = true; // mark game as over stopTimer(); // stop timer isTimerStarted = false; btnSmile.setBackgroundResource(R.drawable.sad); // show all mines // disable all blocks for (int row = 1; row < numberOfRowsInMineField + 1; row++) { for (int column = 1; column < numberOfColumnsInMineField + 1; column++) { // disable block blocks[row][column].setBlockAsDisabled(false); // block has mine and is not flagged if (blocks[row][column].hasMine() && !blocks[row][column].isFlagged()) { // set mine icon blocks[row][column].setMineIcon(false); } // block is flagged and doesn't not have mine if (!blocks[row][column].hasMine() && blocks[row][column].isFlagged()) { // set flag icon blocks[row][column].setFlagIcon(false); } // block is flagged if (blocks[row][column].isFlagged()) { // disable the block blocks[row][column].setClickable(false); } } } // trigger mine blocks[currentRow][currentColumn].triggerMine(); // show message showDialog("You tried for " + Integer.toString(secondsPassed) + " seconds!", 1000, false, false); } private void setMines(int currentRow, int currentColumn) { // set mines excluding the location where user clicked Random rand = new Random(); int mineRow, mineColumn; for (int row = 0; row < totalNumberOfMines; row++) { mineRow = rand.nextInt(numberOfColumnsInMineField); mineColumn = rand.nextInt(numberOfRowsInMineField); if ((mineRow + 1 != currentColumn) || (mineColumn + 1 != currentRow)) { if (blocks[mineColumn + 1][mineRow + 1].hasMine()) { row--; // mine is already there, don't repeat for same block } // plant mine at this location blocks[mineColumn + 1][mineRow + 1].plantMine(); } // exclude the user clicked location else { row--; } } int nearByMineCount; for (int row = 0; row < numberOfRowsInMineField + 2; row++) { for (int column = 0; column < numberOfColumnsInMineField + 2; column++) { // for each block find nearby mine count nearByMineCount = 0; if ((row != 0) && (row != (numberOfRowsInMineField + 1)) && (column != 0) && (column != (numberOfColumnsInMineField + 1))) { // check in all nearby blocks for (int previousRow = -1; previousRow < 2; previousRow++) { for (int previousColumn = -1; previousColumn < 2; previousColumn++) { if (blocks[row + previousRow][column + previousColumn].hasMine()) { // a mine was found so increment the counter nearByMineCount++; } } } blocks[row][column] .setNumberOfMinesInSurrounding(nearByMineCount); } // for side rows (0th and last row/column) // set count as 9 and mark it as opened else { blocks[row][column].setNumberOfMinesInSurrounding(9); blocks[row][column].OpenBlock(); } } } } private void rippleUncover(int rowClicked, int columnClicked) { // don't open flagged or mined rows if (blocks[rowClicked][columnClicked].hasMine() || blocks[rowClicked][columnClicked].isFlagged()) { return; } // open clicked block blocks[rowClicked][columnClicked].OpenBlock(); // if clicked block have nearby mines then don't open further if (blocks[rowClicked][columnClicked].getNumberOfMinesInSorrounding() != 0) { return; } // open next 3 rows and 3 columns recursively for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { // check all the above checked conditions // if met then open subsequent blocks if (blocks[rowClicked + row - 1][columnClicked + column - 1] .isCovered() && (rowClicked + row - 1 > 0) && (columnClicked + column - 1 > 0) && (rowClicked + row - 1 < numberOfRowsInMineField + 1) && (columnClicked + column - 1 < numberOfColumnsInMineField + 1)) { rippleUncover(rowClicked + row - 1, columnClicked + column - 1); } } } return; } public void startTimer() { if (secondsPassed == 0) { timer.removeCallbacks(updateTimeElasped); // tell timer to run call back after 1 second timer.postDelayed(updateTimeElasped, 1000); Log.i("tag",String.valueOf((timer.postDelayed(updateTimeElasped, 1000))) ); } } public void stopTimer() { // disable call backs timer.removeCallbacks(updateTimeElasped); } // timer call back when timer is ticked private Runnable updateTimeElasped = new Runnable() { public void run() { long currentMilliseconds = System.currentTimeMillis(); ++secondsPassed; txtTimer.setText(Integer.toString(secondsPassed)); // add notification timer.postAtTime(this, currentMilliseconds); // notify to call back after 1 seconds // basically to remain in the timer loop timer.postDelayed(updateTimeElasped, 1000); } }; private void showDialog(String message, int milliseconds, boolean useSmileImage, boolean useCoolImage) { // show message Toast dialog = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG); dialog.setGravity(Gravity.CENTER, 0, 0); LinearLayout dialogView = (LinearLayout) dialog.getView(); ImageView coolImage = new ImageView(getApplicationContext()); if (useSmileImage) { coolImage.setImageResource(R.drawable.smile); } else if (useCoolImage) { coolImage.setImageResource(R.drawable.cool); } else { coolImage.setImageResource(R.drawable.sad); } dialogView.addView(coolImage, 0); dialog.setDuration(milliseconds); dialog.show(); Log.i("tag", "showDialog()"); } }
发表评论
-
Android 菜单(OptionMenu)大全 建立你自己的菜单
2011-04-29 12:09 1000Android 菜单(OptionMenu)大全 建立你自己 ... -
Android学习点点滴滴之获取系统可用内存
2011-04-29 12:08 969Android学习点点滴滴之获取系统可用内存 ... -
Android学习点点滴滴之获取正在运行的进程
2011-04-29 12:07 1064Android学习点点滴滴之获取正在运行的进程 ... -
Android 应用程序窗体显示状态操作(requestWindowFeature()的应用)
2011-04-29 12:07 1229Android 应用程序窗体显示状态操作(requestWi ... -
Android游戏开发教程汇总
2011-04-29 12:06 1104Android游戏开发教程汇总 把最近搜集到 ... -
Android 对话框(Dialog)大全 建立你自己的对话框
2011-04-29 12:06 870Android 对话框(Dialog)大全 建立你自己的对话框 ... -
Android资源总结(开发工具/环境搭建/教程/论坛/博客/反编译工具)
2011-04-29 12:05 930Android资源总结(开发工具/环境搭建/教程/论坛/博客 ... -
android Toast大全(五种情形)建立属于你自己的Toast
2011-04-29 12:04 823android Toast大全(五种情形)建立属于你自己的T ... -
通过创建一个位图的XY Chart来学习Android绘图类Rect,Paint,Bitmap,Canvas(附源码)
2011-04-29 12:03 1827通过创建一个位图的XY Chart来学习Android绘图类 ... -
Android2.3操作系统即将发布,亮点解读
2011-04-29 12:02 1055Android2.3操作系统即将发布,亮点解读 ... -
Android之Bundle传递数据详解与实例及Bundle与SharedPreferences的区别
2011-04-29 12:02 1271Android之Bundle传递数据详解与实例及Bundle ... -
Android开源项目源码下载(不断更新中)
2011-04-29 12:01 5813Android开源项目源码下 ... -
android控件之VideoView建立自己的播放器
2011-04-29 12:01 1173android控件之VideoView建立自己的播放器 ... -
Android控件之ZoomButton缩放按钮
2011-04-29 12:00 1123Android控件之ZoomButton缩放按钮 ... -
Android控件之ZoomControls缩放控件
2011-04-29 12:00 1341Android控件之ZoomControls缩放控件 ... -
Android简单数据存储类SharedPreferences详解及实例(通过“记住密码”功能学习SharedPreferences)
2011-04-29 11:58 1169Android简单数据存储类SharedPreference ... -
Android布局控件之LinearLayout详解
2011-04-29 11:58 1371Android布局控件之LinearLa ... -
Android控件之SlidingDrawer(滑动式抽屉)详解与实例
2011-04-29 11:56 1329Android控件之SlidingDrawer ... -
转Android系统架构
2011-04-29 11:55 901转Android系统架构 Android的系统 ... -
Android学习资料分享(不断更新中)
2011-04-29 11:54 1382Android学习资料分享(不断更新中) 最近 ...
相关推荐
Android应用源码之扫雷游戏源码.zip项目安卓应用源码下载Android应用源码之扫雷游戏源码.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考
android 扫雷 游戏 源码: android
【Android扫雷游戏_安卓源码.zip】是一个包含有Android平台扫雷游戏的完整源代码的压缩包。这个源码项目对于学习Android开发,特别是游戏编程的初学者来说,是一份非常有价值的参考资料。通过分析和研究这个源码,...
《扫雷小游戏 完整源码 MFC C++》是一个基于C++编程语言,利用Microsoft Foundation Class (MFC) 库开发的项目。MFC 是微软提供的一套面向对象的类库,它使得开发者能够更方便地使用Windows API,简化Windows应用...
一个简易的扫雷小游戏源码,可供android初学者参考学习
这款"Android扫雷游戏源码"提供了一次深入理解Android游戏开发、逻辑编程和用户体验设计的绝佳机会。下面我们将详细探讨其中涉及的关键知识点。 1. **Android Studio IDE**:Android扫雷游戏的开发通常使用Google的...
android studio 安卓扫雷小游戏源代码 运用Android 制作扫雷游戏,制作简单,没有复杂的代码,对于熟悉Android的页面布局,跳转有帮助理解=。这个扫雷还有点瑕疵,广大程序员们可以对其修改和完善。
运用Android 制作扫雷游戏,制作简单,没有复杂的代码,对于熟悉Android的页面布局,跳转有帮助理解=。这个扫雷还有点瑕疵,广大程序员们可以对其修改和完善。
【Android扫雷源码解析】 Android扫雷是一款经典的逻辑游戏,移植自PC平台,通过学习其源码,我们可以深入理解Android应用开发中的多种技术。以下将详细解析此源码中的关键知识点。 1. **Android应用架构**:...
【Android扫雷游戏源码】是一款基于Android平台的扫雷游戏开发示例,适用于学习和理解Android游戏开发的初级开发者。源码结构清晰,可以直接在Eclipse集成开发环境中导入并运行,为学习Android编程提供了实战参考。 ...
Android应用源码之扫雷游戏源码
Android游戏源码扫雷支持标记重来级别计时是一个安卓扫雷应用源码,功能基本跟windows的扫雷是一样的。支持三种难度模式,支持旗子标注,支持重新开始,支持完成计时。
在这个"Android扫雷程序源码"中,我们可以深入学习以下几个关键知识点: 1. **Android SDK**:首先,你需要安装Android SDK,它是开发Android应用的基础,包含了构建、调试和运行Android应用所需的所有工具。 2. *...
本压缩包包含的是一个Android平台上的扫雷游戏源码,是学习Android开发,特别是游戏编程的一个很好的参考资料。通过分析这个源码,我们可以深入理解Android应用的基本架构,以及如何实现一个简单的游戏逻辑。 1. **...
【Android扫雷游戏Mine源码】是一个专门为Android平台设计的扫雷游戏的源代码实现,旨在帮助开发者了解和学习Android游戏开发。这个项目不仅提供了完整的扫雷游戏逻辑,还包含了丰富的注释,使得初学者能够更容易地...
在Android平台上,扫雷是一款经典的逻辑游戏,它源自Windows操作系统中的同名游戏。这个"Android 扫雷源代码"提供了一个实现扫雷游戏的基础框架,适用于Android开发人员学习和研究。下面将详细介绍这个源代码中涉及...
【ANDROID扫雷源码】是Android平台上实现的经典扫雷游戏的源代码,它涉及到了许多Android开发中的核心知识点。在Android应用开发中,扫雷游戏的实现可以让我们深入理解Android UI设计、事件处理、数据结构以及算法等...
【Android扫雷源码解析】 Android扫雷是一款基于Android平台的经典益智游戏,它的源码为我们揭示了在移动设备上实现此类游戏的基本步骤和技术。在这个简单的应用中,开发者使用了基本的Android编程语言——Java,...
【Android的扫雷游戏源码】是一个典型的移动平台上的逻辑游戏开发实例,它基于Android操作系统,展示了如何利用Java编程语言和Android SDK构建一个交互式的应用。这个游戏的核心是通过算法实现雷区的生成、用户交互...
【Android游戏:扫雷源码解析】 扫雷是一款广受欢迎的经典益智游戏,它在Windows系统中被广泛熟知。在Android平台上,我们同样可以找到它的身影。本篇将深入探讨一个基于Android开发的扫雷游戏源码,分析其设计思路...