📄 bombdialog.java
字号:
import java.util.Random;import org.eclipse.swt.SWT;import org.eclipse.swt.events.MouseEvent;import org.eclipse.swt.events.MouseListener;import org.eclipse.swt.events.PaintEvent;import org.eclipse.swt.events.PaintListener;import org.eclipse.swt.events.SelectionAdapter;import org.eclipse.swt.events.SelectionEvent;import org.eclipse.swt.events.SelectionListener;import org.eclipse.swt.graphics.Color;import org.eclipse.swt.graphics.Font;import org.eclipse.swt.graphics.FontData;import org.eclipse.swt.graphics.GC;import org.eclipse.swt.graphics.Image;import org.eclipse.swt.graphics.Point;import org.eclipse.swt.graphics.Rectangle;import org.eclipse.swt.layout.FillLayout;import org.eclipse.swt.layout.FormAttachment;import org.eclipse.swt.layout.FormData;import org.eclipse.swt.layout.FormLayout;import org.eclipse.swt.layout.GridLayout;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.widgets.Composite;import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Menu;import org.eclipse.swt.widgets.MenuItem;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.widgets.ToolBar;import org.eclipse.swt.widgets.ToolItem;/** * SWT做的扫雷游戏,差一些功能,希望大家能补上 * @author <b>Dart</b> * * 描述 : * 创建时间:2005-12-20 */public class BombDialog extends org.eclipse.swt.widgets.Dialog { /** 对话框的主Shell */ private Shell dialogShell; /** 存放Button的Composite容器 */ private Composite containerComposite; /** 一个button的2维数组 */ private Button[][] buttons; /** 这是一个存放扫雷程序中,地图的标记.标记为整数,从0-9,分别表示:周围无地雷;周围有地雷;地雷 */ private int[][] bombMap; /** button 数组中的横列大小 */ private int xNum = 10; /** button数组中的纵列大小 */ private int yNum = 10; /** 地雷的标记 */ private static final int BOMB_FLAG = 9; /** 玩家表示地雷的标记 */ private static final int MARK_FLAG = 10; /** 地雷数量 */ private int bombNum = 30; private final String BUTTON_LOCATION_PRO = "Location"; /** 游戏面板的偏移量 */ private static final int LEFT=6; private static final int TOP=5; /** * 程序入口 */ public static void main(String[] args) { try { Display display = Display.getDefault(); Shell shell = new Shell(display); BombDialog inst = new BombDialog(shell, SWT.DIALOG_TRIM); inst.open(); } catch (Exception e) { e.printStackTrace(); } } /** * 随机埋下地雷,并计算出map中其他位置的标志。 * <p> * 其他位置标志可能是从整数0-8 * <p> * 地雷位置的标记是9 * <p> * 已记录地雷位置标记为10 */ private void seedTheBomb() { // 随机数 Random da = new Random(); da.setSeed(System.currentTimeMillis()); int randomX = da.nextInt(xNum); int randomY = da.nextInt(yNum); bombMap = new int[yNum][xNum]; for (int i = 0; i < bombNum; i++) { // 不能重复在一个位置布雷 while (bombMap[randomY][randomX] == BOMB_FLAG) { randomX = da.nextInt(xNum); randomY = da.nextInt(yNum); } bombMap[randomY][randomX] = BOMB_FLAG; // 这里将这颗雷周围的表示地雷数增加1 // 由于是以这颗类为中心进行增加的,所以通过两个循环完成,当遇到脚标是自己的时候就跳过 for (int m = -1; m < 2; m++) { for (int j = -1; j < 2; j++) { if (m == 0 && j == 0) continue; // 利用异常处理解决索引超界的问题 try { if (bombMap[randomY + m][randomX + j] != BOMB_FLAG) bombMap[randomY + m][randomX + j]++; } catch (Exception e) { continue; } } } randomX = da.nextInt(xNum); randomY = da.nextInt(yNum); } for (int m = 0; m < yNum; m++) { for (int j = 0; j < xNum; j++) { System.out.print(bombMap[m][j]); } System.out.println(); } } /** * 扫雷的主对话框 * @param parent * @param style */ public BombDialog(Shell parent, int style) { super(parent, style); // 埋好地雷 seedTheBomb(); } /** * 通过Map中的标记来绘制整个面板 * @param gc 得到的GC对象 */ private void drawTheMap(GC gc){ FontData fd = new FontData(); int startY = containerComposite.getLocation().y+TOP; int startX = containerComposite.getLocation().x+LEFT; gc.setForeground(new Color(null, 128, 128, 128)); int feet = 0; int xSize = xNum * ButtonSize; int ySize = yNum * ButtonSize; // 绘制横线 for (int i = 0; i <= yNum; i++, feet += ButtonSize) { gc.drawLine(startX, startY + feet, startX + xSize, startY + feet); } feet = 0; // 绘制竖线 for (int j = 0; j <= xNum; j++, feet += ButtonSize) { gc.drawLine(startX + feet, startY, startX + feet, startY + ySize); } fd.setHeight(ButtonSize - 6); fd.setName("Arail"); Font font = new Font(null, fd); gc.setFont(font); // 画出地雷数的标记 for (int i = 0; i < yNum; i++) { startX = containerComposite.getLocation().x+LEFT; for (int j = 0; j < xNum; j++, startX += ButtonSize) { // 当它有标记地雷数的时候,我们绘制 if (bombMap[i][j] > 0 && bombMap[i][j] < 9) { gc.drawString(String.valueOf(bombMap[i][j]), startX + (ButtonSize - fd.height / 2) / 2, startY + (ButtonSize - fd.height) / 2); } } startY += ButtonSize; } } /** * 打开扫雷程序界面 * */ public void open() { try { Shell parent = getParent(); dialogShell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); createMenu(); FillLayout dialogShellLayout = new FillLayout(); dialogShell.setLayout(dialogShellLayout); newGame(); dialogShell.open(); Display display = dialogShell.getDisplay(); while (!dialogShell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } catch (Exception e) { e.printStackTrace(); } } private void createMenu() { Menu bar = new Menu(dialogShell, SWT.BAR); dialogShell.setMenuBar(bar); MenuItem fileItem = new MenuItem(bar, SWT.CASCADE); fileItem.setText("&File"); Menu fileMenu = new Menu(dialogShell, SWT.DROP_DOWN); fileItem.setMenu(fileMenu); MenuItem newItem = new MenuItem(fileMenu, SWT.NONE); newItem.setText("&New"); newItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { newGame(); } }); MenuItem exitItem = new MenuItem(fileMenu, SWT.NONE); exitItem.setText("E&xit"); exitItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { closeWindow(); } }); } protected void closeWindow() { dialogShell.dispose(); } protected void newGame() { if (containerComposite != null) { containerComposite.dispose(); } seedTheBomb(); containerComposite = new Composite(dialogShell, SWT.NONE); GridLayout continerCompositeLayout = new GridLayout(); continerCompositeLayout.makeColumnsEqualWidth = true; containerComposite.setLayout(continerCompositeLayout); containerComposite.addPaintListener(new PaintListener() { /** * 绘制containerComposite面板 */ public void paintControl(PaintEvent e) { drawTheMap(e.gc); } }); // 这里创建在containerComposite上的那些Button dialogShell.layout(); dialogShell.pack(); dialogShell.setSize(xNum*ButtonSize + 20, yNum*ButtonSize + 60); dialogShell.setImage(getImage("logo.gif")); dialogShell.setText("扫雷游戏 - 中国Eclipse社区"); // 这里创建在containerComposite上的那些Button createButtons(containerComposite); } private final int ButtonSize = 16; /** * 循环生成一个Button矩阵,并且将每个Button的逻辑位置存放到该Button对象中 <p> * 这个位置是一个Point类,获得这个类的方法是通过button的getData方法获得的。取得这个类的键值为字符串"Position" * @param containerComposite 放置Button的容器 */ private void createButtons(Composite containerComposite) { buttons = new Button[yNum][xNum]; int startY = containerComposite.getLocation().y+TOP; for (int i = 0; i < yNum; i++) { int startX = containerComposite.getLocation().x+LEFT; for (int j = 0; j < xNum; j++, startX += ButtonSize) { buttons[i][j] = new Button(containerComposite, SWT.NONE); buttons[i][j].setSize(ButtonSize, ButtonSize); buttons[i][j].setLocation(startX, startY); buttons[i][j].setData(BUTTON_LOCATION_PRO, new Point(i, j)); buttons[i][j].addMouseListener(new MouseListener() { public void mouseDoubleClick(MouseEvent e) { } public void mouseDown(MouseEvent e) { } public void mouseUp(MouseEvent e) { if (e.getSource() instanceof Button) { if (e.button == 3) { ((Button) e.getSource()) .setImage(getImage("person.gif")); } } } }); buttons[i][j].addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (e.getSource() instanceof Button) { buttonClick((Button) e.getSource());// ((Button) e.getSource()).setVisible(false); } } public void widgetDefaultSelected(SelectionEvent e) { } }); } startY += ButtonSize; } } /** * 点击Button后的事件处理 <p> * 分这几种情况: * <li>当这个Button处的位置有地雷的时候(Map值为9),玩家就算失败,游戏结束 * <li>当Button处的位置下没有雷,并且以它对应的Map值为0(就是说它周围没有任何地雷)的时候,打开它周围所有的Button * <li>当Button处的位置下没有雷,但是它周围存在地雷的时候(Map值为 1 - 8),打开这个Button * @param button */ public void buttonClick(Button button){ if(!button.getVisible()) return; // 获得这个地雷所在的位置 Point point = (Point) button.getData(BUTTON_LOCATION_PRO); int a = point.x; int b = point.y; // 如果该位置不是雷,但是周围有地雷的情况处理 if(bombMap[point.x][point.y] > 0 && bombMap[point.x][point.y] < 9){ button.setVisible(false); return; } // 如果该位置不是雷,周围也没有地雷的情况处理 if(bombMap[point.x][point.y] == 0){ button.setVisible(false); for(int i = -1;i<2;i++){ for(int j = -1;j<2;j++){ int indexX = point.x + j; int indexY = point.y + i; if(j == 0 && i ==0) continue; try{ buttonClick(buttons[indexX][indexY]); }catch(Exception e){ continue; } } } }else{ // 如果该位置是雷的情况处理 if(bombMap[point.x][point.y] == BOMB_FLAG){ dialogShell.setText("You Lose"); containerComposite.setEnabled(false); button.setImage(getImage("bom2.gif")); for(int i=0;i<xNum;i++){ for(int j=0;j<yNum;j++){ if(bombMap[i][j] == BOMB_FLAG&&(i!=point.x&&j!=point.y)){ buttons[i][j].setImage(getImage("bom1.gif")); } } }// dialogShell.close(); }else{// if(bombMap[point.x][point.y] == BOMB_FLAG){// // } } } } /** * 获得图片 * @param url * @return */ public Image getImage(String url) { try { url = url.replace('\\', '/'); if (url.startsWith("/")) url = url.substring(1); Image img = new Image(Display.getDefault(), this.getClass().getClassLoader().getResourceAsStream(url)); return img; } catch (Exception e) { return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -