扫雷小游戏

主要步骤

1.初始化
  • 用一个二维数组区装节点的值
    • -1表示地雷
    • 统计相近节点地雷个数作为非雷区的值
    • 地雷离散化,设置一个阈值,使相近区域雷数不要过高
2.事件驱动
  • 事件
    • 单击事件,翻开区域
      • 如果是区域值是0,则域翻开它的邻区,对邻区操作亦如此
    • 双击事件,可化作对相邻区域非标记区域进行单击
    • 右击事件,标记区域,再次右击则取消标记
3.成功与失败
  • 翻开地雷则失败
  • 未翻开数等于地雷数则胜利
不足之处:

计时,计数未实现

代码实现

package mine;import java.util.ArrayList;import javafx.application.Application;import javafx.beans.property.SimpleStringProperty;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.TextField;import javafx.scene.input.MouseButton;import javafx.scene.input.MouseEvent;import javafx.scene.layout.AnchorPane;import javafx.scene.layout.GridPane;import javafx.scene.layout.StackPane;import javafx.scene.text.Font;import javafx.stage.Modality;import javafx.stage.Stage;import javafx.stage.StageStyle;import javafx.stage.Window;publicclassMineextendsApplication{publicstaticvoidmain(String[] args){launch();}publicvoidstart(Stage primaryStage) throws Exception {this.primaryStage=primaryStage;//GridPane gridPane=createPane(16,30,99);
		GridPane gridPane=createPane(9,9,9);
		Scene scene=newScene(gridPane);
		primaryStage.setScene(scene);//		primaryStage.setWidth(1600);//		primaryStage.setHeight(900);
		primaryStage.setWidth(600);
		primaryStage.setHeight(600);
		primaryStage.show();}
	ButtonCell[][] tableCell;private int row;private int col;private int sum;private Window primaryStage;public GridPane createPane(int row,int col,int sum){this.row=row;this.col=col;this.sum=sum;
		int[][] table=rand(row,col,sum);
		tableCell=newButtonCell[row][col];
		GridPane pane=newGridPane();
		
		pane.setVgap(3);
		pane.setHgap(4);
		pane.setStyle("-fx-background-color:green");for(int r=0;r<row;r++){for(int c=0;c<col;c++){	
				ButtonCell cell=newButtonCell(r,c,getValue(r,c, table,row,col));
				
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED,newEventHandler<MouseEvent>(){publicvoidhandle(MouseEvent event){if(event.getClickCount()==1&&event.getButton().name().equals(MouseButton.PRIMARY.name())){singleClick(cell);}}});
				
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED,newEventHandler<MouseEvent>(){publicvoidhandle(MouseEvent event){if(event.getClickCount()==2&&event.getButton().name().equals(MouseButton.PRIMARY.name())){doubleClick(cell);}}});
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED,newEventHandler<MouseEvent>(){publicvoidhandle(MouseEvent event){if(event.getClickCount()==1&&event.getButton().name().equals(MouseButton.SECONDARY.name())){signClick(cell);}}});
				pane.add(cell, c, r);
				tableCell[r][c]=cell;}}return pane;}protectedvoidsignClick(ButtonCell cell){if(cell.open==false){if(cell.sign){
				cell.sign=false;
				cell.setText("");
				cell.setStyle("-fx-background-color:#FAFAD2");}else{
				cell.sign=true;
				cell.setText("P");
				cell.setStyle("-fx-background-color:#FF83FA");}}}privatevoidsingleClick(ButtonCell cell){if(cell.value==-1){blast();}elseif(cell.value==0){turnOver(cell);findFamily(cell, tableCell,this.row,this.col);}else{turnOver(cell);}victory();}privatevoidturnOver(ButtonCell cell){
		cell.open=true;if(cell.value==0){
			cell.setText("");
			cell.setStyle("-fx-background-color:E0EEE0;-fx-border-Stroke: #C6E2FF");}else{
			cell.setText(""+cell.value);
			cell.setStyle("-fx-background-color:#87CEFF;-fx-border-Stroke: #8A2BE2");}}privatevoiddoubleClick(ButtonCell cell){if(cell.open==true){openBrothers(cell, tableCell,this.row,this.col);}}privatevoidblast(){for(int r=0;r<row;r++){for(int c=0;c<col;c++){
				ButtonCell tmp = tableCell[r][c];if(tmp.value==-1){
					tmp.setText("M");
					tmp.setStyle("-fx-background-color:red");}}}achievement("Loser");}public int[][]rand(int x,int y,int count){
		int[][] table =newint[x][y];while( count>0){
			int tmpx =(int)(Math.random()*x);
			int tmpy =(int)(Math.random()*y);if(dispersed(tmpx,tmpy,5,table,x,y)){
				count-=1;
				
				table[tmpx][tmpy]=-1;}}return table;}public boolean dispersed(int x,int y,int dis,int[][] table,int X,int Y){if(table[x][y]==-1){returnfalse;}
		int i=x>0?(x-1):0;
		int e=y>0?(y-1):0;
		int count=1;for(;i<=x+1&&i<X;i++){for(int j=e;j<=y+1&&j<Y;j++){if(table[i][j]==-1){
					count++;}}}if(count>dis)returnfalse;returntrue;}public int getValue(int x,int y,int[][] table,int X,int Y){if(table[x][y]==-1){return-1;}
		int i=x>0?(x-1):0;
		int e=y>0?(y-1):0;
		int count=0;for(;i<=x+1&&i<X;i++){for(int j=e;j<=y+1&&j<Y;j++){if(table[i][j]==-1){
					count++;}}}return count;}publicvoidfindFamily(ButtonCell cell,ButtonCell[][] tableCell,int R,int C){
		int r=cell.row>0?(cell.row-1):0;
		int e=cell.col>0?(cell.col-1):0;for(;r<=cell.row+1&&r<R;r++){for(int j=e;j<=cell.col+1&&j<C;j++){
			    ButtonCell tmp = tableCell[r][j];if(tmp.open==false){turnOver(tmp);if(tmp.value==0){findFamily(tmp,tableCell,R,C);}}}}}publicvoidopenBrothers(ButtonCell cell,ButtonCell[][] tableCell,int R,int C){
		int r=cell.row>0?(cell.row-1):0;
		int e=cell.col>0?(cell.col-1):0;for(;r<=cell.row+1&&r<R;r++){for(int j=e;j<=cell.col+1&&j<C;j++){
			    ButtonCell tmp = tableCell[r][j];if(tmp.open==false){if(!(tmp.sign==true&&tmp.value==-1)){singleClick(tmp);}}}}}publicvoidvictory(){
		int count=0;for(int r=0;r<row;r++){for(int c=0;c<col;c++){
				ButtonCell tmp = tableCell[r][c];if(tmp.open==false){
					count++;}}}if(count==sum){achievement("Winner");}}publicvoidachievement(String str){
		StackPane sp=newStackPane();
		Label lab=newLabel(str);
		sp.getChildren().add(lab);
		sp.setStyle("-fx-background-color: linear-gradient(to right,#00eeff,#ffee00);");
		Stage s=newStage();
		s.initOwner(this.primaryStage);//设置拥有者
		s.setScene(newScene(sp,100,100));
		s.show();}}//随手写的,封装干什么,拿来就用classButtonCellextendsButton{
	int value;
	boolean sign=false;
	boolean open=false;private boolean state=false;public int col;public int row;publicButtonCell(int row,int col,int value){super("");super.setStyle("-fx-background-color: #FAFAD2");this.col=col;this.row=row;super.setPrefSize(40,40);this.value=value;}}

测试

将区域值显示出来方便测试观察

//super("");super(""+value);

点击值大于0的一个区域

来一个巨大的挑战

	GridPane gridPane=createPane(16,30,99);
	primaryStage.setWidth(1600);
	primaryStage.setHeight(900);