本科学生实验报告
项目组长_熊峰 学号_
成 员 熊峰,赖勇
专 业_软件工程(二专)
实验项目 Flash大作业扫雷
指导教师及职称______
开课学期 14 至_15 学年_下_学期
上课时间 2015 年3 月19 至 6月6 日
一、实验设计方案
二、实验结果与分析
扫雷不能不说一款非常经典的游戏,无聊时候可以打发时间,虽然玩了很久,但还不知道它是怎么写的,所以自己就尝试动手做了个。
众所周知,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即可运行。
多媒体技术设计实验报告专业:__网络工程_________________年级:___09级___________________…
商丘职业技术学院20xx级电子商务专业学生实训报告Photoshop学生学号学生姓名指导教师实训地点二0一二年三月二十五日实验实训…
写字动画一项目实训名称写字动画实训时间9月13日9月13日二项目实训学时数本实训项目预计实训学时数为2课时三项目实训目标了解Fla…
实训心得这个礼拜学校安排我们进行Flash的实训虽然时间不是很长仅仅为期五天但是我受益匪浅这次实训让我对Flash有了进一步的了解…
计算机创新实践报告初级题目以世博为题材的FLASH应用学院信息学院系别计算机专业计算机年级大二学号10083243姓名逄丽导师史令…
丽水学院计算机实验报告1附页共页第页丽水学院计算机实验报告一实验目的和要求1通过本实验达到对前面所学的课件素材处理技术的综合运用和…