扫雷小游戏

扫雷小游戏

在这里插入图片描述

主要步骤

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;

public class Mine extends Application{
	public static void main(String[] args) {
		launch();
	}
	public void start(Stage primaryStage) throws Exception {
		this.primaryStage=primaryStage;
		//GridPane gridPane=createPane(16,30,99);
		GridPane gridPane=createPane(9,9,9);
		Scene scene=new Scene(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=new ButtonCell[row][col];
		GridPane pane=new GridPane();
		
		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=new ButtonCell(r,c,getValue(r,c, table,row,col));
				
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
					public void handle(MouseEvent event) {
						if(event.getClickCount()==1&&event.getButton().name().equals(MouseButton.PRIMARY.name())) {
							singleClick(cell);
						}
					}
				});
				
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
					public void handle(MouseEvent event) {
						if(event.getClickCount()==2&&event.getButton().name().equals(MouseButton.PRIMARY.name())) {
							doubleClick(cell);
						}
					}
				});
				cell.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
					public void handle(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;
	}
	protected void signClick(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");
			}
		}
	}
	private void singleClick(ButtonCell cell) {
		if(cell.value==-1) {
			blast();
		}else if(cell.value==0) {
			turnOver(cell);
			findFamily(cell, tableCell, this.row, this.col);
		}else {
			turnOver(cell);
		}
		victory();
	}
	private void turnOver(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");
		}
			
	}
	private void doubleClick(ButtonCell cell) {		if(cell.open==true) {
			openBrothers(cell, tableCell, this.row, this.col);
		}
	}
	private void blast() {
		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 = new int[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) {
			return false;
		}
		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)
			return false;
		return true;
	}
	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;
	}
	public void findFamily(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);
					}
				}
			}
		}
	}
	public void  openBrothers(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);
					}
				}
			}
		}
	}
	public void victory() {
		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");
		}
	}
	public void achievement(String str) {
		StackPane sp=new StackPane();
		Label lab=new Label(str);
		sp.getChildren().add(lab);
		sp.setStyle("-fx-background-color: linear-gradient(to right,#00eeff,#ffee00);");
		Stage s=new Stage();
		s.initOwner(this.primaryStage);//设置拥有者
		s.setScene(new Scene(sp,100,100));
		s.show();
	}
}
//随手写的,封装干什么,拿来就用
class ButtonCell extends Button{
	int value;
	boolean sign=false;
	boolean open=false;
	private boolean state=false;
	public int col;
	public int row;
	public ButtonCell(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的一个区域
在这里插入图片描述
点击值等于0的一个区域
它将翻开相邻区域直至翻到值大于0的区域
在这里插入图片描述
点到地雷
在这里插入图片描述

来一个巨大的挑战

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值