- 浏览: 203151 次
- 性别:
- 来自: 湖南
文章分类
最新评论
MineSweeper是一个不错的Android开源扫雷游戏,对于初学Android开发网的网友可能有很大的帮助,对于Java游戏开发也有一定的参考意义。该游戏主要有以下技术值得学习:
1. 个性化字体,计分器使用的是LED字体,可以帮助我们如何导入外部字体在Android平台中显示。
2. 带图片的Toast,下面的You won in 36 seconds这个Toast使用了自定义的布局,可以显示图片和文字。
3. 自定义Button控件,可以看到标记是否为雷,显示附近地雷数量的按钮控件,初学者可以很容易的学习到Android开发中常用的自定义控件技术。
4. 因为游戏实时性不高,这里没有用到SurfaceView,下次Android开发网给大家提供一个将对高级些的例子。
关键代码如下:
main.xml
smiley_button_states.xml
Block.java
MinesweeperGame.java
1. 个性化字体,计分器使用的是LED字体,可以帮助我们如何导入外部字体在Android平台中显示。
2. 带图片的Toast,下面的You won in 36 seconds这个Toast使用了自定义的布局,可以显示图片和文字。
3. 自定义Button控件,可以看到标记是否为雷,显示附近地雷数量的按钮控件,初学者可以很容易的学习到Android开发中常用的自定义控件技术。
4. 因为游戏实时性不高,这里没有用到SurfaceView,下次Android开发网给大家提供一个将对高级些的例子。
关键代码如下:
main.xml
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="0,2" 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="40sp" android:text="000" /> <ImageButton android:id="@+id/Smiley" android:layout_column="1" android:background="@drawable/smiley_button_states" android:scaleType="center" android:padding="5dip" android:layout_width="48px" 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="40sp" android:text="000" /> </TableRow> <TableRow> <TextView android:layout_column="0" android:layout_width="fill_parent" android:layout_height="50px" 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>
smiley_button_states.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:state_pressed="false" android:layout_width="48px" android:layout_height="48px" android:drawable="@drawable/smile" /> <item android:state_focused="true" android:state_pressed="true" android:layout_width="48px" android:layout_height="48px" android:drawable="@drawable/surprise" /> <item android:state_focused="false" android:state_pressed="true" android:layout_width="48px" android:layout_height="48px" android:drawable="@drawable/surprise" /> <item android:layout_width="48px" android:layout_height="48px" android:drawable="@drawable/smile" /> </selector>
Block.java
package com.VertexVerveInc.Games; import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.Button; public class Block extends Button { private boolean isCovered; // is block covered yet private boolean isMined; // does the block has a mine underneath private boolean isFlagged; // is block flagged as a potential mine private boolean isQuestionMarked; // is block question marked private boolean isClickable; // can block accept click events private int numberOfMinesInSurrounding; // number of mines in nearby blocks public Block(Context context) { super(context); } public Block(Context context, AttributeSet attrs) { super(context, attrs); } public Block(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } // set default properties for the block public void setDefaults() { isCovered = true; isMined = false; isFlagged = false; isQuestionMarked = false; isClickable = true; numberOfMinesInSurrounding = 0; this.setBackgroundResource(R.drawable.square_blue); setBoldFont(); } // mark the block as disabled/opened // update the number of nearby mines public void setNumberOfSurroundingMines(int number) { this.setBackgroundResource(R.drawable.square_grey); updateNumber(number); } // set mine icon for block // set block as disabled/opened if false is passed 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); } } // set mine as flagged // set block as disabled/opened if false is passed 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); } } // set mine as question mark // set block as disabled/opened if false is passed public void setQuestionMarkIcon(boolean enabled) { this.setText("?"); if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); this.setTextColor(Color.RED); } else { this.setTextColor(Color.BLACK); } } // set block as disabled/opened if false is passed // else enable/close it public void setBlockAsDisabled(boolean enabled) { if (!enabled) { this.setBackgroundResource(R.drawable.square_grey); } else { this.setBackgroundResource(R.drawable.square_blue); } } // clear all icons/text public void clearAllIcons() { this.setText(""); } // set font as bold private void setBoldFont() { this.setTypeface(null, Typeface.BOLD); } // uncover this block public void OpenBlock() { // cannot uncover a mine which is not covered if (!isCovered) return; setBlockAsDisabled(false); isCovered = false; // check if it has mine if (hasMine()) { setMineIcon(false); } // update with the nearby mine count else { setNumberOfSurroundingMines(numberOfMinesInSurrounding); } } // set text as nearby mine count public void updateNumber(int text) { if (text != 0) { this.setText(Integer.toString(text)); // select different color for each number // we have already skipped 0 mine count 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; } } } // set block as a mine underneath public void plantMine() { isMined = true; } // mine was opened // change the block icon and color public void triggerMine() { setMineIcon(true); this.setTextColor(Color.RED); } // is block still covered public boolean isCovered() { return isCovered; } // does the block have any mine underneath public boolean hasMine() { return isMined; } // set number of nearby mines public void setNumberOfMinesInSurrounding(int number) { numberOfMinesInSurrounding = number; } // get number of nearby mines public int getNumberOfMinesInSorrounding() { return numberOfMinesInSurrounding; } // is block marked as flagged public boolean isFlagged() { return isFlagged; } // mark block as flagged public void setFlagged(boolean flagged) { isFlagged = flagged; } // is block marked as a question mark public boolean isQuestionMarked() { return isQuestionMarked; } // set question mark for the block public void setQuestionMarked(boolean questionMarked) { isQuestionMarked = questionMarked; } // can block receive click event public boolean isClickable() { return isClickable; } // disable block for receive click events public void setClickable(boolean clickable) { isClickable = clickable; } }
MinesweeperGame.java
package com.VertexVerveInc.Games; import java.util.Random; import android.app.Activity; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; 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.TableRow.LayoutParams; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; public class MinesweeperGame extends Activity { private TextView txtMineCount; private TextView txtTimer; private ImageButton btnSmile; private TableLayout mineField; // table layout to add mines to 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 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtMineCount = (TextView) findViewById(R.id.MineCount); txtTimer = (TextView) findViewById(R.id.Timer); // set font style for timer and mine count to LCD style Typeface lcdFont = Typeface.createFromAsset(getAssets(), "fonts/lcd2mono.ttf"); txtMineCount.setTypeface(lcdFont); txtTimer.setTypeface(lcdFont); 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() { // plant mines and do rest of the calculations createMineField(); // display all blocks in UI showMineField(); minesToFind = totalNumberOfMines; isGameOver = false; secondsPassed = 0; } private void showMineField() { // remember we will not show 0th and last Row and Columns // they are used for calculation purposes only 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 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 < numberOfRowsInMineField + 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; // add Click Listener // this is treated as Left Mouse click blocks[row][column].setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // 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 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; // count number of mines in surrounding blocks 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); } } 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; if (secondsPassed < 10) { txtTimer.setText("00" + Integer.toString(secondsPassed)); } else if (secondsPassed < 100) { txtTimer.setText("0" + Integer.toString(secondsPassed)); } else { 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(); } }
发表评论
-
Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
2015-12-18 22:23 516转载请注明出处:http:// ... -
android arcgis map应用
2013-10-14 20:11 13911 符号渲染 1.1 Symbol Symbol主要是对Gr ... -
lost android 开发教程二
2012-04-19 13:13 1923第二季课程介绍 1、控件使用方法介绍 Sprinner, ... -
android基础
2011-08-10 21:23 1060lost in android Linux 环境 ... -
3G应用开发之Android
2011-04-10 21:12 1654什么是3G 3G,全称为3rd Generation,中文含义 ... -
应用、permission、资源
2011-02-25 13:45 1484应用 为程序添加Menu菜单 //创建OptionsMenu ... -
文件存取、数据库编程
2011-02-25 13:41 728文件存取、数据库编程 -
新版Android开发可视化UI设计DroidDraw
2011-02-24 15:16 1270新版Android开发可视化UI设计DroidDraw -
Android 基础UI编程4
2011-02-23 11:39 1404Android 基础UI编程 专业相框设计 ImageView ... -
Android UI编程基础3
2011-02-23 09:11 1089Android UI编程基础 EditText 与TextVi ... -
Android 基础UI编程2
2011-02-21 10:29 1077Android 基础UI编程 标题、状态栏的隐藏 标题栏隐藏 ... -
Android 基础UI编程1
2011-02-18 15:45 959Android 基础UI编程 更改与显示文字标签 TextVi ... -
android开发--布局
2011-02-17 16:25 1056Android应用开发3 使用Bundle在Activity间 ... -
Android 模拟器
2011-02-17 15:40 1470Android 模拟器 模拟器参数 参数格式 option 选 ... -
Android开发--Dalvik ADB
2011-02-17 10:41 1541Android虚拟机Dalvik Dalvik冲击 随着Goo ... -
Android开发环境搭建
2011-02-17 09:38 1353Android开发环境搭建 ADV的创建 ADT0.9.1 版 ... -
基础入门一
2011-02-17 09:12 1086开放手机联盟--Open HandsetAlliance 什么 ...
相关推荐
【Java扫雷游戏完整项目代码】是一个基于Java编程语言实现的经典扫雷游戏的代码实现。在计算机科学领域,扫雷游戏通常被用作一个教学工具,帮助初学者理解逻辑推理、算法设计以及基本的图形用户界面(GUI)编程。在...
java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java实现扫雷游戏java实现扫雷游戏java实现扫雷游戏 java...
Qt扫雷游戏是一款基于Qt框架开发的经典游戏,旨在为毕设、课设或其他项目开发提供一个有趣而具有挑战性的实践案例。这款游戏不仅实现了扫雷的核心玩法,而且在界面设计和用户体验方面进行了精心雕琢。 主要特点: ...
AS3扫雷游戏是一款基于ActionScript 3.0(AS3)编程语言开发的经典小游戏,旨在帮助初学者理解和掌握AS3的基本语法、事件处理、显示对象以及游戏逻辑。以下是关于AS3扫雷游戏的一些关键知识点: 1. **ActionScript ...
扫雷游戏是一款广为人知的益智游戏,它考验玩家的逻辑推理能力和观察力。通过分析提供的C#源代码,我们可以学习到游戏的核心算法、用户界面设计以及事件处理等方面的知识。 首先,扫雷游戏的实现离不开数据结构的...
【Python扫雷游戏设计】是计算机科学与工程学院的一次课程设计任务,旨在培养学生面向对象程序设计的能力,提高代码质量和效率。在这个项目中,学生需要使用Python语言来实现经典的游戏——扫雷。通过这个设计,学生...
【扫雷游戏源程序】是一种基于C++编程语言开发的小型桌面游戏,旨在帮助程序员提升C++语言的应用技能,特别是对于Visual C++(VC)环境的掌握。扫雷游戏是微软Windows操作系统内置的经典游戏之一,它通过逻辑推理和...
【扫雷游戏源代码】是基于C#编程语言在Visual Studio(VS)环境中开发的一款经典数字游戏。扫雷游戏的设计和实现涉及多个编程和技术知识点,包括窗口应用开发、事件处理、数组逻辑、随机数生成以及游戏规则的算法...
【Cocos Creator 扫雷游戏资源工程】 Cocos Creator 是一款强大的2D游戏开发引擎,它提供了便捷的可视化编辑工具和高效的游戏开发框架,使得开发者能够轻松创建各种类型的游戏,包括经典的扫雷游戏。扫雷游戏,作为...
用java编写的扫雷游戏,有兴趣的可以研究研究
通过html+css+jquery实现经典扫雷游戏,可以直接在浏览器上运行
Python扫雷游戏是一款经典的逻辑推理游戏,通过编程实现可以让我们深入了解Python编程语言的特性以及游戏逻辑的设计。在这款基于Python3.7版本编写的扫雷游戏中,开发者充分展示了Python的面向对象编程思想、条件...
【Android扫雷游戏Mine源码】是一个专门为Android平台设计的扫雷游戏的源代码实现,旨在帮助开发者了解和学习Android游戏开发。这个项目不仅提供了完整的扫雷游戏逻辑,还包含了丰富的注释,使得初学者能够更容易地...
扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码扫雷游戏Java源代码...
QT扫雷游戏源码是一个基于QT框架,使用C++编程语言实现的经典扫雷游戏项目。对于初学者来说,这是一个极好的学习资源,可以帮助他们深入理解QT框架和C++编程语言在实际项目中的应用。 首先,QT是一个跨平台的C++...
【C++ MFC扫雷游戏】是一个典型的C++面向对象编程项目,主要应用于计算机专业的课程设计,通过实现扫雷游戏来巩固和应用MFC(Microsoft Foundation Classes)框架的知识。MFC是微软提供的一套用于构建Windows应用...
【扫雷游戏-Swing】是一款基于Java Swing图形用户界面(GUI)开发的经典益智游戏,旨在帮助初学者提升编程逻辑,巩固数组运用和深化位运算理解。Swing是Java提供的一个用于创建桌面应用的库,它允许开发者构建美观且...
java课程设计作业——基于java实现的扫雷游戏(源码+设计说明文档+可执行文件),直接点击“扫雷.exe”即可运行 --利用swing做出的扫雷桌面游戏,运行时直接双击可执行文件夹下的“扫雷.exe”即可 java课程设计...
【扫雷游戏与QT框架】 扫雷游戏,作为一款经典的逻辑推理游戏,旨在锻炼玩家的空间想象和逻辑思维能力。在这款基于QT开发的扫雷游戏中,我们能够看到开发者充分利用了QT框架的优势,构建了一个功能丰富的游戏环境。...
【Java扫雷游戏】是一款基于Java编程语言开发的桌面版小游戏,它继承了经典扫雷游戏的玩法,同时也融入了开发者独特的设计元素。在大学期间,开发者利用课余时间研究并实现了这款游戏,旨在锻炼自己的编程技能,同时...