1 importMypackage.ErsBox;2 importMypackage.ErsBlock;3 importMypackage.GameCanvas;4 importMypackage.ControlPanel;5
6 import javax.swing.*;7 import java.awt.*;8 import java.awt.event.*;9
10 public class ErsBlocksGame extendsJFrame {11 //定义各种参数
12 privateGameCanvas canvas;13 privateControlPanel ctrlPanel;14 privateJPanel plButton;15 privateJPanel ctrlPanelwithButton;16 private ErsBlock block; //当前活动的块
17 private boolean playing; //当前游戏的状态
18 private final static int PER_LINE_SCORE = 100; //填满一行得100;
19 public final static int PER_LEVEL_SCORE = PER_LINE_SCORE * 20; //升级所需的得分
20 public final static int MAX_LEVEL = 10;21 public final static int DEFAULT_LEVEL = 5;22
23 //控制面板的按钮
24 privateJButton25 btPlay = new JButton("开始"),26 btPause = new JButton("暂停"),27 btStop = new JButton("停止"),28 btTurnLevelUp = new JButton("增加难度"),29 btTurnLevelDown = new JButton("降低难度");30
31 //定时器(用于定时更新信息面板信息)
32 Timer timer;33
34 //相关菜单(项)声明
35 private JMenuBar bar =newJMenuBar();36 privateJMenu37 mGame = new JMenu("游戏"),38 mControl = new JMenu("控制"),39 mInfo = new JMenu("帮助");40 privateJMenuItem41 //游戏
42 miNewGame = new JMenuItem("新游戏"),43 miSetBlockColor = new JMenuItem("设置方块颜色"),44 miSetBackColor = new JMenuItem("设置背景颜色"),45 miTurnHarder = new JMenuItem("增加难度"),46 miTurnEasier = new JMenuItem("降低难度"),47 miExit = new JMenuItem("退出"),48 //控制
49 miPlay = new JMenuItem("开始"),50 miPause = new JMenuItem("暂停"),51 miResume = new JMenuItem("继续"),52 miStop = new JMenuItem("停止"),53 //菜单
54 miAuthor = new JMenuItem("作者: Java游戏设计组"),55 miSourceInfo = new JMenuItem("版本: 1.0");56
57 publicErsBlocksGame(String title) {58 super(title);59 setSize(315, 392);60 Dimension scrSize =Toolkit.getDefaultToolkit().getScreenSize();61 setLocation((scrSize.width - getSize().width)/2, (scrSize.height - getSize().height)/2);62 ctrlPanel = newControlPanel();63 plButton = new JPanel(new GridLayout(5,1));64 ctrlPanelwithButton = new JPanel(newBorderLayout());65
66 //创建菜单
67 createMenu();68 //为控制按钮设置监听器
69 createButton();70 //设置键盘监听器
71 ctrlPanel.addKeyListener(new ControlKeyListener());//addKeyListener not for JFrame;
72
73 Container container =getContentPane();74 container.setLayout(new BorderLayout(6, 0));75 canvas = new GameCanvas(20, 12);76 //放置
77 ctrlPanelwithButton.add(ctrlPanel,BorderLayout.NORTH);78 ctrlPanelwithButton.add(plButton, BorderLayout.SOUTH);79 container.add(canvas, BorderLayout.CENTER);80 container.add(ctrlPanelwithButton, BorderLayout.EAST);81 //增加监听器
82 addWindowListener(newWindowAdapter() {83 public voidwindowClosing(WindowEvent we) {84 stopGame();85 System.exit(0);86 }87 });88 addComponentListener(newComponentAdapter() {89 public voidcomponentResized(ComponentEvent ce) {90 canvas.fanning();91 }92 });93
94 //设置定时器
95 timer = new Timer(500, newActionListener() {96 public voidactionPerformed(ActionEvent ae) {97 ctrlPanel.setScore(getScore());98 int scoreForLevelUpdate =getScoreForLevelUpdate();99 if(scoreForLevelUpdate >= PER_LEVEL_SCORE && scoreForLevelUpdate > 0)100 levelUpdate();101 }102 });103 timer.start();//启动
104
105 setVisible(true);106 canvas.fanning();107 }108
109 private voidcreateButton() {110 plButton.add(btPlay);111 plButton.add(btPause);112 plButton.add(btStop);113 plButton.add(btTurnLevelUp);114 plButton.add(btTurnLevelDown);115 //plButton.setBorder(border);116 //设置各种按钮的监听器行为
117 btPlay.addActionListener(newActionListener() {118 public voidactionPerformed(ActionEvent ae) {119 playGame();120 }121 });122
123 btPause.addActionListener(newActionListener() {124 public voidactionPerformed(ActionEvent ae) {125 if (btPause.getText().equals(new String("暂停"))) {126 pauseGame();127 } else{128 resumeGame();129 }130 }131 });132
133 btStop.addActionListener(newActionListener() {134 public voidactionPerformed(ActionEvent ae) {135 stopGame();136 }137 });138
139 btTurnLevelUp.addActionListener(newActionListener() {140 public voidactionPerformed(ActionEvent ae) {141 try{142 int level =ctrlPanel.getLevel();143 if (level
150 btTurnLevelDown.addActionListener(newActionListener() {151 public voidactionPerformed(ActionEvent ae) {152 try{153 int level =ctrlPanel.getLevel();154 if (level > 1)155 ctrlPanel.setLevel(level - 1);156 } catch(NumberFormatException e) {}157 requestFocus();158 }159 });160 }161
162
163
164 private voidcreateMenu() {165 bar.add(mGame);166 bar.add(mControl);167 bar.add(mInfo);168
169 mGame.add(miNewGame);170 mGame.addSeparator(); //分隔条
171 mGame.add(miSetBackColor);172 mGame.add(miSetBlockColor);173 mGame.addSeparator();174 mGame.add(miTurnHarder);175 mGame.add(miTurnEasier);176 mGame.addSeparator();177 mGame.add(miExit);178
179 mControl.add(miPlay);180 mControl.add(miPause);181 mControl.add(miResume);182 mControl.add(miStop);183
184 mInfo.add(miAuthor);185 mInfo.add(miSourceInfo);186
187 setJMenuBar(bar);188
189 //设置对应的菜单响应事件190
191 //设置快捷键
192 miPause.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_MASK));193 miResume.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));194
195 //开始菜单项
196 miPlay.addActionListener(newActionListener() {197 public voidactionPerformed(ActionEvent ae) {198 stopGame();199 reset();200 setLevel(DEFAULT_LEVEL);201 }202 });203
204 miNewGame.addActionListener(newActionListener() {205 public voidactionPerformed(ActionEvent ae) {206 stopGame();207 reset();208 setLevel(DEFAULT_LEVEL);209 }210 });211
212 miSetBlockColor.addActionListener(newActionListener() {213 public voidactionPerformed(ActionEvent ae) {214 Color newFrontColor = JColorChooser.showDialog(ErsBlocksGame.this, "设置方块颜色", canvas.getBlockColor());215 if(newFrontColor != null)216 canvas.setBlockColor(newFrontColor);217 }218 });219
220 miSetBackColor.addActionListener(newActionListener() {221 public voidactionPerformed(ActionEvent ae) {222 Color newBackColor = JColorChooser.showDialog(ErsBlocksGame.this, "设置背景颜色", canvas.getBackgroundColor());223 if(newBackColor != null)224 canvas.setBackgroundColor(newBackColor);225 }226 });227
228 miTurnHarder.addActionListener(newActionListener() {229 public voidactionPerformed(ActionEvent ae) {230 int curLevel =getLevel();231 if(curLevel
236 miTurnEasier.addActionListener(newActionListener() {237 public voidactionPerformed(ActionEvent ae) {238 int curLevel =getLevel();239 if(curLevel > 1)240 setLevel(curLevel - 1);241 }242 });243
244 miExit.addActionListener(newActionListener() {245 public voidactionPerformed(ActionEvent ae) {246 System.exit(0);247 }248 });249
250 //控制
251 miPlay.addActionListener(newActionListener() {252 public voidactionPerformed(ActionEvent ae) {253 playGame();254 }255 });256
257 miPause.addActionListener(newActionListener() {258 public voidactionPerformed(ActionEvent ae) {259 pauseGame();260 }261 });262
263 miResume.addActionListener(newActionListener() {264 public voidactionPerformed(ActionEvent ae) {265 resumeGame();266 }267 });268
269 miStop.addActionListener(newActionListener() {270 public voidactionPerformed(ActionEvent ae) {271 stopGame();272 }273 });274 }275
276 /*控制方法*/
277 //重置
278 public voidreset() {279 ctrlPanel.reset();280 canvas.reset();281 }282 //get&set
283 public booleanisPlaying() {284 returnplaying;285 }286
287 publicErsBlock getCurBlock() {288 returnblock;289 }290
291 publicGameCanvas getCanvas() {292 returncanvas;293 }294
295 public intgetLevel() {296 returnctrlPanel.getLevel();297 }298
299 public void setLevel(intlevel) {300 if(level < 11 && level > 0)301 ctrlPanel.setLevel(level);302 }303
304 public intgetScore() {305 if(canvas != null)306 returncanvas.getScore();307 return 0;308 }309
310 public intgetScoreForLevelUpdate() {311 if(canvas != null)312 returncanvas.getScoreForLevelUpdate();313 return 0;314 }315
316
317 public void setPauseButtonLabel(booleanpause) {318 btPause.setText(pause ? "暂停" : "继续");319 }320
321 //控制函数(主要是让按钮事件调用)
322 public voidplayGame() {323 play();324 btPlay.setEnabled(false);325 miPlay.setEnabled(false);326 ctrlPanel.requestFocus();327 }328
329 public voidpauseGame() {330 if(block != null)331 block.pauseMove();332 //btPause.setEnabled(false);
333 miPause.setEnabled(false);334 miResume.setEnabled(true);335 setPauseButtonLabel(false);336 }337
338 public voidresumeGame() {339 if(block != null)340 block.resumeMove();341 //btPause.setEnabled(true);
342 miPause.setEnabled(true);343 miResume.setEnabled(false);344 setPauseButtonLabel(true);345 ctrlPanel.requestFocus();346 }347
348 public voidstopGame() {349 playing = false;350 if(block != null)351 block.stopMove();352 miPlay.setEnabled(true);353 miPause.setEnabled(true);354 miResume.setEnabled(false);355 btPlay.setEnabled(true);356 btPause.setEnabled(true);357 }358
359 public booleanlevelUpdate() {360 int curLevel =getLevel();361 if(curLevel
369 //内部实现
370 private voidplay() {371 reset();372 playing = true;373 Thread thread = new Thread(newGame());374 thread.start();375 }376
377 private voidreportGameOver() {378 JOptionPane.showMessageDialog(this, "游戏结束");379 }380
381 /*方向键的类,作为监听类*/
382 private class ControlKeyListener extendsKeyAdapter {383 public voidkeyPressed(KeyEvent ke) {384 /*debug*/
385 //System.out.println("direction key");
386 if (!isPlaying())387 return;388 ErsBlock block =getCurBlock();389 switch(ke.getKeyCode()) {390 caseKeyEvent.VK_DOWN:391 block.moveDown();392 break;393 caseKeyEvent.VK_LEFT:394 block.moveLeft();395 break;396 caseKeyEvent.VK_RIGHT:397 block.moveRight();398 break;399 caseKeyEvent.VK_UP:400 block.turnNext();401 break;402 default:403 break;404 }405 }406 }407
408 /*Game内部类,用于产生一个新的游戏局*/
409 private class Game implementsRunnable {410 public voidrun() {411 //随机产生一个方块
412 int col = (int) (Math.random() * (canvas.getCols() - 3)),413 style = ErsBlock.STYLES[(int)(Math.random()*7)][(int)(Math.random()*4)];414 while(playing) {415 if(block != null) {416 if(block.isAlive()) { //判断线程是否在活动状态
417 try{418 Thread.currentThread().sleep(100);419 }420 catch(InterruptedException ie) {421 ie.printStackTrace();422 }423 continue;424 }425 }426 checkFullLine();427 if(isGameOver()) {428 miPlay.setEnabled(true);429 miPause.setEnabled(true);430 miResume.setEnabled(false);431 btPause.setEnabled(true);432 btPlay.setEnabled(true);433 reportGameOver();434 return;435 }436 //创建一个游戏块
437 block = new ErsBlock(style, 0, col, getLevel(), canvas);438 block.start();439
440 /*debug*/
441 //System.out.println("new block");442
443 //生成下一个的列和类型
444 col = (int) (Math.random()*(canvas.getCols() - 3));445 style = (int)ErsBlock.STYLES[(int)(Math.random()*7)][(int)(Math.random()*4)];446 ctrlPanel.setTipStyle(style);447 }448 }449
450 /*检查是否有填满的一行*/
451 public voidcheckFullLine() {452 int i, j, row;//i最大的检查行次数
453 for(i = 0; i < canvas.getRows(); ++i) {454 row = -1; //需要移动的行
455 boolean fullLineColorBox = true;456 for(j = 0; j < canvas.getCols(); ++j) {457 if(!canvas.getBox(i, j).isColorBox()) {458 fullLineColorBox = false;459 break;460 }461 }462 if(fullLineColorBox) {463 row = i--;464 canvas.removeLine(row); //i之上的行都在下移一行
465 }466 }467 }468
469 private booleanisGameOver() {470 for(int j = 0; j < canvas.getCols(); j++) {471 ErsBox box = canvas.getBox(0, j);472 if(box.isColorBox()) {473 /*debug*/
474 System.out.println("isGameOver:why");475 return true;476 }477 }478 return false;479 }480 }481
482 public static voidmain(String[] args) {483 new ErsBlocksGame("俄罗斯方块游戏");484 }485 }