Flash扫雷实验报告

 

本科学生实验报告

项目组长_熊峰 学号_    

成    员    熊峰,赖勇                           

专    业_软件工程(二专)                  

实验项目   Flash大作业扫雷                   

指导教师及职称______    

开课学期    14    至_15   学年_下_学期

上课时间   2015 3 19     66


一、实验设计方案

二、实验结果与分析

 

第二篇:扫雷扫雷

扫雷不能不说一款非常经典的游戏,无聊时候可以打发时间,虽然玩了很久,但还不知道它是怎么写的,所以自己就尝试动手做了个。

众所周知,java的swing采用mvc模式,即模型-视图-控制器,所以如果真的了解了这个模式,较c++,用java做个游戏还是比较容易的。下面是我写的扫雷的代码

import java.awt.*;

import java.io.*;

import java.net.URL;

import java.awt.geom.*;

import java.awt.event.*;

import javax.swing.*;

import java.util.ArrayDeque;

import java.util.ArrayList;

import java.util.concurrent.*;

public class MineSweep

{

public static void main(String[] args)

{

JFrame frame = new MineFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

class MineFrame extends JFrame

{

private JPanel buttonPanel;

private MinePanel mp;

private int rn,cn;

public static final int DEFAULT_WIDTH = 650; public static final int DEFAULT_HEIGHT = 450; public static final int DEFAULT_CN = 9; public static final int DEFAULT_RN = 9; public JLabel remainMine;

public JLabel mes;

private JComboBox cb;

public MineFrame()

{

setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); setTitle("扫雷");

mp = new MinePanel(DEFAULT_CN,DEFAULT_RN,this); mp.setMinenum(10);

mp.setRC(9,9);

buttonPanel = new JPanel();

add(mp,BorderLayout.CENTER);

mes = new JLabel("");

mes.setEnabled(false);

add(mes,BorderLayout.EAST);

cb = new JComboBox();

cb.setEditable(true);

cb.addItem("初级");

cb.addItem("中级");

cb.addItem("高级");

cb.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int index = cb.getSelectedIndex(); System.out.println(index);

switch(index)

{

case 0:

mp.setMinenum(10);

mp.setRC(9,9);

break;

case 1:

mp.setMinenum(40);

mp.setRC(16,16);

break;

case 2:

mp.setMinenum(99);

mp.setRC(30,16);

break;

}

}

}

);

JButton showAll = new JButton("显示所有地雷");

showAll.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

mp.showMines();

}

}

);

buttonPanel.add(showAll);

JButton replay = new JButton("重新开始");

replay.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

mp.updateMines();

}

}

);

buttonPanel.add(replay);

buttonPanel.add(cb);

remainMine = new JLabel("剩余雷数:" +mp.getMinenum()); add(remainMine,BorderLayout.SOUTH);

add(buttonPanel,BorderLayout.NORTH);

}

}

class Pair

{

public Pair(int r,int c)

{

this.r = r;

this.c =c;

}

public int r;

public int c;

}

class MinePanel extends JPanel implements MouseListener {

private int cn,rn;

private int minenum;

private Mine[][] mines;

private int hideMine = minenum;

private int ableMn ;

private MineFrame f;

private boolean over ;

private int w,h;

private boolean win;

public static ArrayList<Image> IMAGES = new ArrayList<Image>(12); public MinePanel(int rn,int cn,MineFrame f)

{

IMAGES.add(new ImageIcon(getURL(".\\img\\0.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\1.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\2.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\3.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\4.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\5.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\6.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\7.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\8.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\mine.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\11.gif")).getImage()); IMAGES.add(new ImageIcon(getURL(".\\img\\12.gif")).getImage()); this.f = f;

this.rn = rn;

this.cn = cn;

this.ableMn = rn * cn;

addMouseListener(this);

updateMines();

}

public URL getURL(String file) {

URL url =null;

try

{

url = this.getClass().getResource(file); }

catch(Exception e)

{

e.printStackTrace();

}

return url;

}

public void decAbleMn()

{

ableMn --;

}

public int getAbleMn()

{

return ableMn;

}

public void decHideMine()

{

hideMine --;

}

public void incHideMine() {

hideMine ++;

}

public int getHideMine()

{

return hideMine;

}

public void setMinenum(int n) {

minenum = n;

}

public int getMinenum()

{

return minenum;

}

public void mousePressed(MouseEvent e) {

if(!over)

{

int x = (int)e.getX();

int y = (int)e.getY();

int keyCode = e.getButton();

int c,r;

r = x/Mine.WIDTH;

c = y/Mine.HEIGHT;

switch(keyCode)

{

case MouseEvent.BUTTON1:

if(mines[r][c].getFlag() == false) {

try

{

mines[r][c].setOpen();

decAbleMn();

if(mines[r][c].getImage() == 9) {

over = true;

decHideMine();

showMines();

}

else if(mines[r][c].getImage() == 0) {

if(getAbleMn() == rn * cn - minenum) {

win = true;

}

openNear(r,c);

}

}

catch(Exception ex)

{

//e.printStackTrace();

}

repaint();

}

break;

case MouseEvent.BUTTON3:

if( mines[r][c].isOpen() == false || mines[r][c].getFlag() == true) {

if(mines[r][c].getFlag() == true)

{

incHideMine();

mines[r][c].setFlag();

repaint();

}

else if(hideMine > 0)

{

mines[r][c].setFlag();

decHideMine();

repaint();

}

}

break;

}

}

}

public void mouseReleased(MouseEvent e)

{

}

public void mouseClicked(MouseEvent e)

{

}

public void mouseEntered(MouseEvent e)

{}

public void mouseExited(MouseEvent e)

{}

private ArrayDeque<Pair> queue = new ArrayDeque<Pair>(20); public void openNear(int r,int c)

{

int i,j;

i = r;

j = c;

for(int n = -1; n <= 1; n ++)

{

r = i + n;

if(r >= 0 && r <mines.length)

for(int k = -1; k <=1; k ++)

{

c = j + k;

if(c >= 0 && c < mines[r].length)

{

if(mines[r][c].isOpen() == false && mines[r][c].getImage() == 0) {

mines[r][c].setOpen();

queue.add(new Pair(r,c));

}

else

{

if(mines[r][c].getFlag() ==true)

{

mines[r][c].setFlag();

incHideMine();

}

mines[r][c].setOpen();

}

}

}

}

for(i = 0 ;i < queue.size(); i ++) {

Pair p = queue.poll();

openNear(p.r,p.c);

}

}

public void setRC(int rn,int cn)

{

this.rn = rn;

this.cn = cn;

updateMines();

repaint();

}

public void updateMines()

{

removeAll();

win = false;

over = false;

f.setSize((10 +rn) * 20,(cn + 10) * 20); setSize(rn * Mine.HEIGHT,cn * Mine.WIDTH); mines = new Mine[rn][cn];

for(int i = 0;i < mines.length;i ++)

for(int j = 0 ;j < mines[i].length; j ++) {

mines[i][j] = new Mine(i,j);

}

int mn = getMinenum();

hideMine = mn;

for(int i = 0; i <mn;i ++)

{

int r,c;

do

{

r = (int)(Math.random() * rn);

c = (int)(Math.random() * cn);

}while(mines[r][c].getImage() == 9); mines[r][c].setImage(9);

}

generateNum();

repaint();

}

public void generateNum()

{

int r,c;

for(int i = 0 ;i < mines.length;i ++) for(int j = 0 ;j < mines[i].length; j ++) if(mines[i][j].getImage() != 9) {

int cnum = 0 ;

for(int n = -1; n <= 1; n ++) {

r = i + n;

if(r >= 0 && r < mines.length) for(int k = -1 ;k <=1; k ++) {

c = j + k;

if(c >= 0 && c < mines[i].length) {

if(mines[r][c].getImage() == 9) cnum ++;

}

}

}

mines[i][j].setImage(cnum);

}

}

public void paintComponent(Graphics g) {

super.paintComponent(g);

int c = 0;

Graphics2D g2 = (Graphics2D) g;

for(int i = 0 ;i < mines.length; i ++)

for(int j = 0 ;j < mines[i].length; j ++)

{

g2.setColor(mines[i][j].getColor());

g2.draw(mines[i][j].getShape());

if(mines[i][j].getFlag() == true && mines[i][j].isOpen() == false)

g.drawImage(IMAGES.get(10),mines[i][j].getW(),mines[i][j].getH(),Mine.HEIGHT,Mine.WIDTH,this);

if(mines[i][j].isOpen()&& mines[i][j].getFlag() == false ) {

g.drawImage(IMAGES.get(mines[i][j].getImage()),mines[i][j].getW(),mines[i][j].getH() ,Mine.HEIGHT,Mine.WIDTH,this);

c ++;

}

}

f.remainMine.setText("剩余雷数:" + getHideMine() );

}

public void showMines()

{

removeAll();

for(int i = 0 ;i <mines.length; i ++)

for(int j = 0 ; j < mines[i].length; j ++)

{

if(mines[i][j].getImage() == 9)

{

if(mines[i][j].getFlag() == false)

mines[i][j].setOpen();

}

else

{

if(mines[i][j].getFlag() == true)

{

mines[i][j].setOpen();

mines[i][j].setFlag();

mines[i][j].setImage(11);

}

}

}

hideMine = 0;

repaint();

}

}

class Mine

{

private Rectangle2D rect = null;

public static final ImageIcon IMAGE = new ImageIcon("mine.gif"); public static final int HEIGHT = 20;

public static final int WIDTH = 20;

private boolean flag = false;

private boolean open = false;

public static final Color DEFAULT_COLOR = Color.BLACK;

private int image = 0;

private Color color;

private boolean isMine = false;

private int w,h;

public Mine(int r,int c)

{

this.w = r * HEIGHT;

this.h = c * HEIGHT;

rect = new Rectangle2D.Double(1.0D *r * HEIGHT,1.0D *c * WIDTH ,1.0D *HEIGHT,1.0D *WIDTH);

setColor(DEFAULT_COLOR);

}

public void setMine()

{

isMine = true;

}

public boolean isMine()

{

return isMine;

}

public void setColor(Color c)

{

this.color = c;

}

public Color getColor() {

return color;

}

public void setOpen() {

open = true;

}

public boolean isOpen() {

return open;

}

public void setImage(int n) {

image =n;

}

public int getImage() {

return image;

}

public int getW()

{

return w;

}

public int getH()

{

return h;

}

public void setFlag()

{

flag = !flag;

}

public boolean getFlag()

{

return flag;

}

public Shape getShape()

{

return rect;

}

}

代码主要包含三个类,MineSweep,MinePanel和Mine类。

MineSweep包含main函数,为程序的入口,此外还负责初始化一个游戏界面的框架。

MinePanel为整个程序的核心,负责响应鼠标事件,游戏逻辑的处理,视图的刷新。其包含的openNear和generateNum方法为逻辑处理的核心。openNear方法主要功能是当被打开的一个方格不包含任何内容时(即它周围不包含雷),则它打开周围不为地雷的方格。这个方法主要用到广度优先搜索算法,用一个队列实现。而generateNum方法目的是初始化地图,即它是生成每个雷周围的数字。 Mine表示每个方格,里面包含每个方格的属性,flag是判断该方格是否被右键标上旗子,open判断该格子是否已经被打开,isMine判断是否是地雷,此外还有其他属性。

整个程序的逻辑流程如下

扫雷扫雷

最后,附上程序包。解压后直接双击扫雷.jar即可运行。