Java课设--俄罗斯方块Tetris

Java程序设计课程作业报告

作业:俄罗斯方块游戏

姓名

赵璐媛

学号


程序得分

90%


作业报告

得分10%


实验总分

100%


作业目的:

  • 掌握基本的图形程序设计方法

  • 掌握Java事件处理程序编写方法

  • 掌握编写基于TCPUDP协议的网络通讯程序

  • 掌握Java的流、文件、多线程等编程技术

作业结果(学生填写):

  • 程序设计思路(300字以上,可附流程图或类图)

类之间的关系图

(注:折线箭头仅代表后者为前者的一个实例,弯箭头为继承,双向箭头为相关。)

GameFrame

GameView

Unit


Main


WatchView


DoubleGameFrame

UnitKey


CommunicateView




各个类说明

(注:红色的为类名,黄色的为该类中比较重要的实例对象。)

  1. 程序入口:Main

main方法里弹出选择提示,选择单人模式则进入singleGame函数,创建GameFrame类进行游戏(详见第2条)

选择双人模式则进入doubleGame函数,创建DoubleGameFrame类(继承自GameFrame类)进行游戏(详见第3条)


  1. 单人模式框架类:GameFrame

继承自JFrame类,包含两个主体部件GameViewWatchView(详见第4条和第5条)

1.构造方法设置布局,为WatchView的对象watchJButton添加鼠标监听器控制游戏开始和暂停,添加键盘监听器调用GameView的对象game的方法控制方块,以及计时器timer调用game中的方法控制方块下落和游戏的开始暂停;

2.方法updateData在方块落致底部时由timer调用,令gamewatch更新游戏数据(如消去行,提取一个新的下落方块,增加得分,通过关卡,改变timer的延时加快方块下落速度等),返回值为消去的行数;

3.方法resetGame在每次开始新游戏之前对数据进行重置;

4.方法restartGame在暂停时恢复游戏,否则开始新游戏;

5.方法pauseGame暂停游戏;

6.方法stopGame在游戏结束时弹出提示信息。


  1. 双人模式网络通信框架类:DoubleGameFrame

继承自GameFrame类,在此基础上又新增一个主部件CommuicateView(详见第6条)

1.构造方法使用给定的ip和发送及接受端口建立网络通信,设置布局,建立四个线程sendThreadacceptThreadsendDataThreadacceptDataThread通过输出输入流ImageIO分别发送、接受战况视图,通过输入输出流发送、接受战况数据(对方是否消去多重行数);

2.方法creatView通过截屏创建己方战况视图并返回;

3.重写父类的方法updateDataresetGamerestartGamepauseGamestopGame,取消了开始暂停功能,新增winGame方法,赢得游戏则进入winGame弹出提示信息,否则进入stopGame弹出提示信息。


  1. 游戏视图类:GameView

继承自JPanel类,通过此类操纵并显示游戏中的方块,出现在框架的最左边;

1.构造方法设置格式布局,以绿色背景的JLabel数组box填充,nextUnit列表存储后续的Unit方块(详见第7条)movingUnit是正在移动的Unit方块;

2.方法romoveRow消去可消去的行并返回消去数量、addRow增加指定行数;

3.方法creatNextUnitnextUnit中添加后续的方块Unit

4.方法getNextUnitnextUnit中取出并试着绘制新方块movingUnit,若无法绘制,返回false,说明方块已落至顶部、游戏结束;

5.方法moveUnit根据给定的指令变换或移动正在活动的方块movingUnit,在方块落至底部的时候返回false

6.方法paintUnitgetNextUnitmoveUnit所调用,通过改变JLabel的透明属性显现方块,试着在给定位置重新绘制正在移动的movingUnit,若超出边界或与已有方块重合则不绘制,返回false

7.方法resetGameendGame分别完成界面的重置、停止所有方块移动。


  1. 数据视图类:WatchView

继承自JPanel类,此类中包含数据游戏得分score、游戏关卡level,可观察当前游戏得分、关卡、下一个方块,可通过开始和暂停按钮开始或暂停游戏,出现在框架的中间;

1.构造方法设置布局;

2.方法resetData在新一轮游戏开始时重置数据;

3.方法addStartListeneraddPauseListener分别为开始和暂停按钮添加监听器;

4.方法updateData更新面板上的分数、关卡、下一个方块的信息;

5.方法getLevel为外部传递当前关卡(主要用于设置方块下落速度)。


  1. 通信视图类:CommunicateView

继承自JPanel类,此类实时显示对方的游戏战况,只在双人模式中有,出现在框架最右边;

1.构造方法设置布局;

2.方法setImage更新数据域对方战况img,并调用提供的重绘方法repaint

3.重写方法paint,设置绘图区域与放缩,被repaint方法调用。


  1. 方块类:Unit

此类中包含一个点location描述方块的位置,以及一个int数组key来描述方块的种类及形状(详见第8条)

1.两种构造方法,一种是在指定位置生成一个随机形状的Unit,另一种是用提供的key在指定位置生成指定形状的Unit

2.方法getShape返回此Unit的形状绘制在坐标系中的坐标点数组(WatchView使用)

3.方法getChangedUnit返回此Unit经过变形或位移产生的新Unit

4.方法getPaintLocation返回此Unit的绘制在坐标系中的坐标点数组(GameView使用)。


  1. 方块键值类:UnitKey

此类中list包含了所有方块形状绘制在坐标系中的点的数组;

1.方法getRandomKey产生一个随机的key值返回,key值对应着某个方块的形状;

2.方法getNextKey返回给定key值的方块经变形后对应的key值;

3.方法getShapeByKey解读给定key值对应的方块的形状,以Point数组的形式返回形状。


  • 程序使用说明(文字说明,并附界面抓图)

    1. 若要进行双人模式,可改变Main类中doubleGameIP地址和端口号(设定的两端口号之差需大于1)。按(对方IP,对方接受端口,己方接受端口)的顺序设置。

示例:A的设置(BIPB接受端口,A接受端口

B的设置(AIPA接受端口B接受端口

  1. 直接运行程序,选择游戏模式。

  1. 单人模式下可选暂停、开始,在非暂停时候点开始则直接开始新游戏。点击开始后通过方向键左右上下控制方块移动、变形、加速。右侧可看到下一个方块以及当前分数、关卡,每过1000分升一级,下落速度加快三分之一。游戏结束时提示最终得分,点开始开启新游戏。

  1. 双人模式下Main中提前设置好后就可以直接开始游戏,此时开始暂停功能已禁用,在单人模式基础上增加了观察对方战况的区域(有可能因为对方屏幕视图读写异常而花屏或卡着,暂不知道怎么处理这种情况)。若一次消去多行,对方便会涨一行。直至一方输掉游戏,游戏结束,分别提示双方是输是赢。

评语(总分优秀和不及格的报告必须有评语):






评阅日期:2015430


转载于:https://www.cnblogs.com/jinhengyu/p/7516414.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java俄罗斯方块课设的设计与实现需要考虑以下几个方面: 1.游戏界面的设计:需要设计游戏的主界面、游戏区域、下一个方块预览区等。 2.方块的设计:需要设计不同形状的方块,并实现它们的旋转、移动等操作。 3.游戏逻辑的实现:需要实现游戏的得分、等级、速度等逻辑,并且需要实现游戏的开始、暂停、结束等操作。 4.音效的实现:可以为游戏添加音效,例如方块旋转、方块落地、消除行等操作的音效。 以下是一个简单的Java俄罗斯方块课设的实现示例: ```java import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class Tetris extends JPanel implements ActionListener, KeyListener { private static final long serialVersionUID = 1L; private final Point[][][] Tetraminos = { // I-Piece { { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) }, { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) } }, // J-Piece { { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 0) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 2) }, { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 2) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 0) } }, // L-Piece { { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 2) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 2) }, { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 0) }, { new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 0) } }, // O-Piece { { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }, { new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) } }, // S-Piece { { new Point(1, 0), new Point(2, 0), new Point(0, 1), new Point(1, 1) }, { new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) }, { new Point(1, 0), new Point(2, 0), new Point(0, 1), new Point(1, 1) }, { new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) } }, // T-Piece { { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(2, 1) }, { new Point(1, 0), new Point(0, 1), new Point(1, 1), new Point(1, 2) }, { new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(1, 2) }, { new Point(1, 0), new Point(1, 1), new Point(2, 1), new Point(1, 2) } }, // Z-Piece { { new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(2, 1) }, { new Point(1, 1), new Point(0, 2), new Point(1, 2), new Point(0, 1) }, { new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(2, 1) }, { new Point(1, 1), new Point(0, 2), new Point(1, 2), new Point(0, 1) } } }; private final Color[] tetraminoColors = { Color.cyan, Color.blue, Color.orange, Color.yellow, Color.green, Color.pink, Color.red }; private Point pieceOrigin; private int currentPiece; private int rotation; private ArrayList<Integer> nextPieces = new ArrayList<Integer>(); private long score; private Color[][] well; // Creates a border around the well and initializes the dropping piece private void init() { well = new Color[12][24]; for (int i = 0; i < 12; i++) { for (int j = 0; j < 23; j++) { if (i == 0 || i == 11 || j == 22) { well[i][j] = Color.GRAY; } else { well[i][j] = Color.BLACK; } } } newPiece(); } // Put a new, random piece into the dropping position public void newPiece() { pieceOrigin = new Point(5, 2); rotation = 0; if (nextPieces.isEmpty()) { Collections.addAll(nextPieces, 0, 1, 2, 3, 4, 5, 6); Collections.shuffle(nextPieces); } currentPiece = nextPieces.get(0); nextPieces.remove(0); } // Collision test for the dropping piece private boolean collidesAt(int x, int y, int rotation) { for (Point p : Tetraminos[currentPiece][rotation]) { if (well[p.x + x][p.y + y] != Color.BLACK) { return true; } } return false; } // Rotate the piece clockwise or counterclockwise public void rotate(int i) { int newRotation = (rotation + i) % 4; if (newRotation < 0) { newRotation = 3; } if (!collidesAt(pieceOrigin.x, pieceOrigin.y, newRotation)) { rotation = newRotation; } repaint(); } // Move the piece left or right public void move(int i) { if (!collidesAt(pieceOrigin.x + i, pieceOrigin.y, rotation)) { pieceOrigin.x += i; } repaint(); } // Drops the piece one line or fixes it to the well if it can't drop public void dropDown() { if (!collidesAt(pieceOrigin.x, pieceOrigin.y + 1, rotation)) { pieceOrigin.y += 1; } else { fixToWell(); } repaint(); } // Make the dropping piece part of the well, so it is available for // linescanning. public void fixToWell() { for (Point p : Tetraminos[currentPiece][rotation]) { well[pieceOrigin.x + p.x][pieceOrigin.y + p.y] = tetraminoColors[currentPiece]; } clearRows(); newPiece(); } public void deleteRow(int row) { for (int j = row-1; j > 0; j--) { for (int i = 1; i < 11; i++) { well[i][j+1] = well[i][j]; } } } // Clear completed rows from the field and award score according to // the number of simultaneously cleared rows. public void clearRows() { boolean gap; int numClears = 0; for (int j = 21; j > 0; j--) { gap = false; for (int i = 1; i < 11; i++) { if (well[i][j] == Color.BLACK) { gap = true; break; } } if (!gap) { deleteRow(j); j += 1; numClears += 1; } } switch (numClears) { case 1: score += 100; break; case 2: score += 300; break; case 3: score += 500; break; case 4: score += 800; break; } } // Draw the falling piece private void drawPiece(Graphics g) { g.setColor(tetraminoColors[currentPiece]); for (Point p : Tetraminos[currentPiece][rotation]) { g.fillRect((p.x + pieceOrigin.x) * 26, (p.y + pieceOrigin.y) * 26, 25, 25); } } @Override public void paintComponent(Graphics g) { // Paint the well g.fillRect(0, 0, 26*12, 26*23); for (int i = 0; i < 12; i++) { for (int j = 0; j < 23; j++) { g.setColor(well[i][j]); g.fillRect(26*i, 26*j, 25, 25); } } // Display the score g.setColor(Color.WHITE); g.drawString("" + score, 19*12, 25); // Draw the currently falling piece drawPiece(g); } public static void main(String[] args) { JFrame f = new JFrame("Tetris"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(12*26+10, 26*23+25); f.setVisible(true); final Tetris game = new Tetris(); game.init(); f.add(game); // Keyboard controls f.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_UP: game.rotate(-1); break; case KeyEvent.VK_DOWN: game.dropDown(); game.score += 1; break; case KeyEvent.VK_LEFT: game.move(-1); break; case KeyEvent.VK_RIGHT: game.move(+1); break; case KeyEvent.VK_SPACE: game.dropDown(); game.score += 2; break; } } public void keyReleased(KeyEvent e) { } }); // Make the falling piece drop every second new Timer(1000, game).start(); } @Override public void actionPerformed(ActionEvent e) { dropDown(); } @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_UP: rotate(-1); break; case KeyEvent.VK_DOWN: dropDown(); score += 1; break; case KeyEvent.VK_LEFT: move(-1); break; case KeyEvent.VK_RIGHT: move(+1); break; case KeyEvent.VK_SPACE: dropDown(); score += 2; break; } } @Override public void keyReleased
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值