首页>代码>java swing开发的俄罗斯方块游戏,包含完整代码+详细注释>/ItcastTetris1.02_final/src/cn/itcast/tetris/controller/Controller.java
package cn.itcast.tetris.controller; import java.awt.Font; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.HashSet; import java.util.Set; import javax.swing.JLabel; import cn.itcast.tetris.entities.Ground; import cn.itcast.tetris.entities.Shape; import cn.itcast.tetris.entities.ShapeFactory; import cn.itcast.tetris.listener.GameListener; import cn.itcast.tetris.listener.GroundListener; import cn.itcast.tetris.listener.ShapeListener; import cn.itcast.tetris.util.Global; import cn.itcast.tetris.view.GamePanel; /** * 控制器<BR> * 控制Ground, Snake, Food<BR> * 负责游戏的逻辑<BR> * 处理按键事件<BR> * <BR> * */ public class Controller extends KeyAdapter implements ShapeListener, GroundListener { protected Set<GameListener> listeners = new HashSet<GameListener>(); /** * 图形工厂 * */ protected ShapeFactory shapeFactory; protected Shape shape; protected Ground ground; protected GamePanel gamePanel; protected JLabel gameInfoLabel; /** * 当前的游戏状态 */ protected boolean playing; /** * * @param shapeFactory * @param ground * @param gamePanel */ public Controller(ShapeFactory shapeFactory, Ground ground, GamePanel gamePanel) { super(); this.shapeFactory = shapeFactory; this.ground = ground; this.gamePanel = gamePanel; } /** * 多接受一个 JTextComponent, 可以给在这个组件上显示提示信息 * * @param shapeFactory * @param ground * @param gamePanel * @param gameInfoLabel */ public Controller(ShapeFactory shapeFactory, Ground ground, GamePanel gamePanel, JLabel gameInfoLabel) { this(shapeFactory, ground, gamePanel); this.setGameInfoLabel(gameInfoLabel); } /** * 处理键盘按键 <BR> * LEFT: 向左移动<BR> * RIGHT:向右移动<BR> * DOWN: 向下移动<BR> * UP: 变形<BR> * PAGE UP: 加快速度<BR> * PAGE DOWN: 减慢速度<BR> * Y: 重新开始游戏<BR> * ENTER: 暂停/继续 */ @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() != KeyEvent.VK_Y && !playing) return; switch (e.getKeyCode()) { /** * 方向左 */ case KeyEvent.VK_LEFT: if (isPausingGame()) { this.continueGame(); } shape.setSwift(false); if (isPlaying() && ground.isMoveable(shape, Shape.LEFT)) shape.moveLeft(); break; /** * 方向右 */ case KeyEvent.VK_RIGHT: if (isPausingGame()) { this.continueGame(); } shape.setSwift(false); if (isPlaying() && ground.isMoveable(shape, Shape.RIGHT)) shape.moveRight(); break; /** * 方向上 */ case KeyEvent.VK_UP: if (isPlaying()) { if (!shape.isPause()) { if (ground.isMoveable(shape, Shape.ROTATE)) { shape.setSwift(false); shape.rotate(); } } else { if (ground.isMoveable(shape, Shape.UP)) shape.moveUp(); else { shape.die(); shape = shapeFactory.getShape(this); } } } break; /** * 方向下 */ case KeyEvent.VK_DOWN: if (isPausingGame()) { this.continueGame(); } if (isPlaying() && isShapeMoveDownable(shape)) shape.moveDown(); break; /** * PAGE UP */ case KeyEvent.VK_PAGE_UP: shape.speedUp(); break; /** * PAGE DOWN */ case KeyEvent.VK_PAGE_DOWN: shape.speedDown(); break; /** * 反引号,换一个图形 */ case KeyEvent.VK_BACK_QUOTE: if (isPlaying()) { shape.die(); shape = shapeFactory.getShape(this); } break; case KeyEvent.VK_ENTER: if (isPausingGame()) this.continueGame(); else this.pauseGame(); break; case KeyEvent.VK_Y: if (!isPlaying()) newGame(); break; case KeyEvent.VK_SPACE: if (isPlaying() && !isPausingGame()) shape.setSwift(true); break; } /** * 重新显示 */ gamePanel.redisplay(ground, shape); if (gameInfoLabel != null) gameInfoLabel.setText(this.getNewInfo()); } /** * 询问一下图形是否可以下落,如果不能下落了,就会让图形变成障碍物<BR> * 这个方法是同步的 */ public synchronized boolean isShapeMoveDownable(Shape s) { if (shape == null) return true; if (!playing || shape != s) return false; if (ground.isMoveable(shape, Shape.DOWN)) return true; shape.die(); ground.accept(shape); if (playing && !ground.isFull()) { shape = shapeFactory.getShape(this); } gamePanel.redisplay(ground, shape); if (gameInfoLabel != null) gameInfoLabel.setText(this.getNewInfo()); return false; } /** * 处理图形触发的 shapeMovedDown (图形下落) 事件<BR> * 将会重新显示 */ public void shapeMovedDown(Shape s) { // TODO Auto-generated method stub if (playing && ground != null && shape != null) gamePanel.redisplay(ground, shape); } /** * 开始一个新游戏 */ public void newGame() { playing = true; ground.init(); ground.addGroundListener(this); Global.CURRENT_SPEED = Global.DEFAULT_SPEED; shape = shapeFactory.getShape(this); if (playing) gamePanel.redisplay(ground, shape); if (gameInfoLabel != null) gameInfoLabel.setText(this.getNewInfo()); for (GameListener l : listeners) l.gameStart(); } /** * 停止当前游戏 */ public void stopGame() { if (shape == null) return; playing = false; for (GameListener l : listeners) l.gameOver(); } /** * 暂停游戏 */ public void pauseGame() { if (shape == null) return; shape.setPause(true); for (GameListener l : listeners) l.gamePause(); } /** * 继续游戏 */ public void continueGame() { shape.setPause(false); for (GameListener l : listeners) l.gameContinue(); } /** * 游戏是否是在暂停状态 */ public boolean isPausingGame() { return shape.isPause(); } /** * 获得游戏的最新提示信息 * * @return */ public String getNewInfo() { if (!playing || ground.isFull()) return " ";// "提示: 按 Y 开始新游戏"; else return new StringBuffer().append("提示: ").append(" 速度 ").append( shape.getSpeed()).append("毫秒/格").toString(); } public ShapeFactory getShapeFactory() { return shapeFactory; } public void setShapeFactory(ShapeFactory shapeFactory) { this.shapeFactory = shapeFactory; } public Ground getGround() { return ground; } public void setGround(Ground ground) { this.ground = ground; } public GamePanel getGamePanel() { return gamePanel; } public void setGamePanel(GamePanel gamePanel) { this.gamePanel = gamePanel; } /** * 处理Ground 触发的 beforeDeleteFullLine 事件将会改变满行的颜色并暂停一段时间 */ public void beforeDeleteFullLine(Ground ground, int lineNum) { // TODO Auto-generated method stub ground.changeFullLineColor(lineNum); gamePanel.redisplay(ground, shape); try { Thread.sleep(Global.STAY_TIME); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 处理Ground 触发的 fullLineDeleted 事件, 这个方法什么也没做, 只是打印了一句话 */ public void fullLineDeleted(Ground ground, int deletedLineCount) { // TODO Auto-generated method stub System.out.println("消了 " + deletedLineCount + " 行"); } /** * 是否正在游戏中 * * @return */ public boolean isPlaying() { if (playing && !ground.isFull()) return true; return false; } /** * 得到显示提示信息的组件 * * @return */ public JLabel getGameInfoLabel() { return gameInfoLabel; } /** * 设置 * * @param gameInfoLabel */ public void setGameInfoLabel(JLabel gameInfoLabel) { this.gameInfoLabel = gameInfoLabel; this.gameInfoLabel.setSize(Global.WIDTH * Global.CELL_WIDTH, 20); this.gameInfoLabel.setFont(new Font("宋体", Font.PLAIN, 12)); gameInfoLabel.setText(this.getNewInfo()); } /** * 处理Ground 的 groundIsFull() 事件, 将触发游戏结束事件 */ public void groundIsFull(Ground ground) { // TODO Auto-generated method stub if (playing) { playing = false; for (GameListener l : listeners) l.gameOver(); } } /** * 添加监听器, 可添加多个 * * @param l */ public void addGameListener(GameListener l) { if (l != null) this.listeners.add(l); } /** * 移除监听器 * * @param l */ public void removeGameListener(GameListener l) { if (l != null) this.listeners.remove(l); } }

chy520 LV1
2024年6月2日
ClydeSon LV5
2023年12月18日
微信网友_6770780673069056 LV2
2023年12月9日
npc也有忧伤 LV3
2022年3月19日
guzhiguo0313 LV5
2022年2月12日
闫小玥 LV8
2021年12月22日
秒速一千米 LV2
2021年9月4日
jnagri LV6
2021年7月6日
zhangjian800 LV1
2021年5月25日
ybc629 LV3
2020年12月23日

dushine LV3
4月10日
luoyanglin LV2
2024年9月14日
2824163870szy
2024年7月1日
暂无贡献等级
zr20050503 LV2
2024年6月27日
hainabian1977 LV2
2024年6月24日
bill1234 LV1
2024年6月23日
chy520 LV1
2024年5月29日
douxing
2024年3月5日
暂无贡献等级
crapcrap LV2
2024年2月1日
zhaoyunlong36987
2024年1月23日
暂无贡献等级