java-课程设计
1.团队成员及负责模块
成员 | 负责模块 |
---|---|
聂闽鹭 | 界面设计,游戏界面设计,难度选择 |
郑钧 | 雷分布算法,失败重来选择,计时 |
2.git提交记录
3.项目介绍
仿照传统游戏扫雷制作了一个扫雷小游戏
4.功能架构图
1.流程图
2.UML类图
5.运行截图
6.主要代码
1.主要流程
void launch(){
GameUtil.START_TIME = System.currentTimeMillis();//开始时间
this.setVisible(true);//可见
if(GameUtil.state==3){
this.setSize(500,500);
}else{
this.setSize(width,height);//窗口大小
}
//this.setSize(width,height);//窗口大小
this.setLocationRelativeTo(null);//居中显示
this.setTitle("扫雷");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭方法
//鼠标事件
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
switch(GameUtil.state){
case 0:
//左键被点击
if(e.getButton()==1){
GameUtil.MOUSE_x = e.getX();
GameUtil.MOUSE_Y =e.getY();
GameUtil.LEFT = true;
}
//右键被点击
if(e.getButton()==3){
GameUtil.MOUSE_x = e.getX();
GameUtil.MOUSE_Y =e.getY();
GameUtil.RIGHT = true;
}
case 1:
case 2:
if(e.getButton()==1) {
if (e.getX() > GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W / 2)
&& e.getX() < GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W / 2) + GameUtil.SQUARE_LENGTH
&& e.getY() > GameUtil.OFFSET
&& e.getY() < GameUtil.OFFSET + GameUtil.SQUARE_LENGTH) {
mapBottom.reGame();
mapTop.reGame();
GameUtil.FLAG_NUM = 0;
GameUtil.START_TIME = System.currentTimeMillis();
GameUtil.state = 0;
}
}
//单机滚轮,切换难度
if(e.getButton()==2){
GameUtil.state=3;
begin=true;
}
break;
case 3:
if(e.getButton()==1){
GameUtil.MOUSE_x = e.getX();
GameUtil.MOUSE_Y = e.getY();
begin = gameSelect.hard();
}
break;
}
}
});
while(true){
repaint();
begin();
try {
Thread.sleep(40);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
设置了鼠标监视器,来判断当前是点击空格还是插旗子或者选择难度,根据选择难度绘制各个难度对应的窗口大小
2.地雷初始化
void newRay(){
for(int i=0;i<GameUtil.RAY_MAX*2;i=i+2){
x=(int)(Math.random()*GameUtil.MAP_W+1);//1-12
y=(int)(Math.random()*GameUtil.MAP_H+1);//1-12
rays[i]=x;
rays[i+1]=y;
//判断坐标是否存在
for(int j=0;j<i;j+=2){
if(x==rays[j]&&y==rays[j+1]){
i=i-2;
isplace = false;
break;
}
}
//将坐标放入数组
if(isplace){
rays[i] = x;
rays[i+1] = y;
}
isplace = true;
}
for (int i= 0;i<GameUtil.RAY_MAX*2;i=i+2){
GameUtil.DATA_BUTTON[rays[i]][rays[i+1]]=-1;
}
}
初始化地雷
3.游戏重置
void reGame(){
for (int i = 1; i <= GameUtil.MAP_W; i++) {
for (int j = 1; j <= GameUtil.MAP_H; j++) {
GameUtil.DATA_BUTTON[i][j]=0;
}
}
bottomRay.newRay();
bottomNum.newNum();
}
游戏返回初始状态
4.失败判断
boolean boom() {
for (int i = 1; i < GameUtil.MAP_W; i++) {
for (int j = 1; j <= GameUtil.MAP_H; j++) {
if (GameUtil.DATA_BUTTON[i][j] == -1 && GameUtil.DATA_TOP[i][j] == -1) {
GameUtil.state=2;
seeBoom();
return true;
}
}
}
return false;
}
判断是否有踩雷,如果踩到地雷则失败
5.胜利判断
boolean victory(){
//统计未打开格子数
int count = 0;
for (int i = 1; i < GameUtil.MAP_W; i++) {
for (int j = 1; j <= GameUtil.MAP_H; j++) {
if(GameUtil.DATA_TOP[i][j]!=-1){
count++;
}
}
}
if(count==GameUtil.RAY_MAX){
GameUtil.state=1;
for (int i = 1; i < GameUtil.MAP_W; i++) {
for (int j = 1; j <= GameUtil.MAP_H; j++) {
//未翻开,变成旗
if(GameUtil.DATA_TOP[i][j]==0){
GameUtil.DATA_TOP[i][j]=1;
}
}
}
return true;
}
return false;
}
统计未打开格子的数量,如果剩下的格子数量与雷的数量相同,则胜利
6.操作的逻辑判断
void logic(){
temp_x=0;
temp_y=0;
if(GameUtil.MOUSE_x>GameUtil.OFFSET&&GameUtil.MOUSE_Y>3*GameUtil.OFFSET){
temp_x = (GameUtil.MOUSE_x-GameUtil.OFFSET)/GameUtil.SQUARE_LENGTH+1;
temp_y = (GameUtil.MOUSE_Y-GameUtil.OFFSET*3)/GameUtil.SQUARE_LENGTH+1;
}
if(temp_x>=1&&temp_x<=GameUtil.MAP_W
&&temp_y>=1&&temp_y<=GameUtil.MAP_H){
if(GameUtil.LEFT){
//覆盖则翻开
if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
GameUtil.DATA_TOP[temp_x][temp_y]=-1;
}
spaceOpen(temp_x,temp_y);
GameUtil.LEFT = false;
}
if(GameUtil.RIGHT){
//覆盖则插旗
if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
GameUtil.DATA_TOP[temp_x][temp_y]=1;
GameUtil.FLAG_NUM++;
}
//插旗则取消
else if(GameUtil.DATA_TOP[temp_x][temp_y]==1){
GameUtil.DATA_TOP[temp_x][temp_y]=0;
GameUtil.FLAG_NUM--;
}
else if(GameUtil.DATA_TOP[temp_x][temp_y]==-1){
numOpen(temp_x,temp_y);
}
GameUtil.RIGHT = false;
}
}
boom();
victory();
}
判断操作的逻辑
背景设计
界面背景
地雷
旗帜
三个表情
打印格式
void paintSelf(Graphics g){
g.setColor(Color.blue);
//画竖线
for(int i = 0;i<=GameUtil.MAP_W;i++){
g.drawLine(GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
3*GameUtil.OFFSET,
GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
3*GameUtil.OFFSET+GameUtil.MAP_H*GameUtil.SQUARE_LENGTH);
}
//画横线
for(int i = 0;i<=GameUtil.MAP_H;i++){
g.drawLine(GameUtil.OFFSET,
3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
GameUtil.OFFSET+GameUtil.MAP_W*GameUtil.SQUARE_LENGTH,
3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH);
}
for(int i=1;i<=GameUtil.MAP_W;i++){
for( int j =1;j<= GameUtil.MAP_H;j++){
//雷
if(GameUtil.DATA_BUTTON[i][j]==-1) {
g.drawImage(GameUtil.lei,
GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
GameUtil.SQUARE_LENGTH - 2,
GameUtil.SQUARE_LENGTH - 2,
null);
}
//数字
if(GameUtil.DATA_BUTTON[i][j]>=0) {
g.drawImage(GameUtil.images[GameUtil.DATA_BUTTON[i][j]],
GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
GameUtil.SQUARE_LENGTH - 2,
GameUtil.SQUARE_LENGTH - 2,
null);
}
}
}
//绘制数字,倒计时
GameUtil.drawWord(g,""+(GameUtil.RAY_MAX-GameUtil.FLAG_NUM),GameUtil.OFFSET,2*GameUtil.OFFSET,30,Color.red);
GameUtil.drawWord(g,""+(GameUtil.END_TIME-GameUtil.START_TIME)/1000,
GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W-1),
2*GameUtil.OFFSET,30,Color.black);
switch(GameUtil.state){
case 0:
GameUtil.END_TIME = System.currentTimeMillis();
g.drawImage(GameUtil.face,
GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
GameUtil.OFFSET,
null);
break;
case 1:
g.drawImage(GameUtil.win,
GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
GameUtil.OFFSET,
null);
break;
case 2:
g.drawImage(GameUtil.over,
GameUtil.OFFSET+GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2),
GameUtil.OFFSET,
null);
break;
}
}