JAVA程序设计课程设计
之
俄罗斯方块
年级:13级
班级:T412 网络工程
指导老师:朱林
小组成员:
20138346021 许浩洋
时间:2015年11月11日
在现代,高科技的飞跃发展,人们工作习惯的改变,特别是电脑的大量普及,人们生活节奏越来越快,一些有趣的桌面游戏已经成为人们在使用计算机进行工作或学习之余休闲娱乐的首选,而俄罗斯方块游戏是人们最熟悉的小游戏之一。俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。 为此,我们设计了一款简单的俄罗斯方块JAVA游戏程序,以便更好的满足广大电脑工作者闲暇之余的消遣,并且也让我们学到编程技术与团队意识。
关键字:俄罗斯方块、JAVA游戏、编程
题目名称:俄罗斯方块
题目类型:设计型
课程设计目的:
1)了解Java的基本使用方法。
2)熟悉eclipse的运行环境。
3)用JAVA来设计一个俄罗斯方块的小游戏。
4)基本实现俄罗斯方块的应用功能。
实验原理:
JAVA程序分析与设计、类的灵活运用、多态技术、模板技术、异常处理等。
实验内容:
本俄罗斯方块游戏是对于随机给出不同的形状(长条形、Z字形、反Z形、田字形、L字形、反L形、T字型)下落填充给定的区域,若填满一条便消掉,记分。若在游戏中各形状填满了给定区域,为输者。
本项目是为了实现俄罗斯方块的基本功能而设计的,基本能够达到俄罗斯方块的各种游戏性。项目需求分析如下:
1)由方块组成的不同的随机图形会从区域上方开始缓慢落下。
2)玩家可以做的操作有:
以90度为单位旋转方每一格块。
以格子为单位左右移动方块,让方块加速落下。
3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的随机图形会出现在区域上方开始落下。
4)当区域中某一列横向格子全部由方块填满,则该列会自动消除并成为玩家的得分。
5)一次性销毁不同行数方块得分不同,一行1分,两行2分,三行5分,四行10分。
6)当固定的方块堆到区域最上方,则游戏结束。
代码:
package Tetris;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.s;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TetrisPanel extends JPanel{
//?????20?10?
private static final int ROWS = 20;
private static final int COLS = 10;
//????????
private Cell[][] wall = new Cell[ROWS][COLS];
//?????????
private static final int CELL_SIZE = 25;
//????
private int score;
//??????
private int lines;
//????????????(0?=0?,1?=1?,2?=4?,3?=10?,4?=20?)
private static final int [] SCORE_LEVEL ={0,1,4,10,20};
//??????
private boolean gameOver = false;
//??????
private boolean pause = false;
//?????????
private Tetromino currentTetro ;
//??????????
private Tetromino nextTetro ;
//???????
private Timer timer;
public static void main(String[] args){
JFrame frame = new JFrame("?????");
int width = (COLS+8)*CELL_SIZE+100;
int height = ROWS*CELL_SIZE+100;
frame.setSize(width, height);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//????????
frame.setLayout(null);
TetrisPanel panel = new TetrisPanel();
panel.setLocation(45, 35);
panel.setSize((COLS+8)*CELL_SIZE,ROWS*CELL_SIZE+1);
frame.add(panel);
frame.setVisible(true);
panel.action();
}
public void paint(Graphics g){
super.paint(g);
//??????
this.paintBackground(g);
//?????
paintWall(g);
//?????
paintScore(g);
//??????
paintTetrisBorder(g);
//????????
paintCurrentTetro(g);
//????????
paintNextTetro(g);
}
//
private static final int BG_COLOR = 0xC3D5EA;
//
private static final int BORDER_COLOR = 0x667799;
//
private static final int FONT_COLOR = 0x000000;
//???????
public void paintBackground(Graphics g){
g.setColor(new Color(BG_COLOR));
//this.setBackground(new Color(BG_COLOR));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
}
//????????
public void paintWall(Graphics g){
for(int row=0;row<ROWS;row++){
for(int col=0;col<COLS;col++){
Cell cell = wall[row][col];
int x =col*CELL_SIZE;
int y= row*CELL_SIZE;
if(cell==null){
g.setColor(new Color(BORDER_COLOR));
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}else{
g.setColor(new Color(cell.getColor()));
g.fillRect(x, y, CELL_SIZE, CELL_SIZE);
g.setColor(new Color(BORDER_COLOR));
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}
}
}
}
//????????
public void paintScore(Graphics g){
int x = 12*CELL_SIZE;
int y = 6*CELL_SIZE;
Font font = new Font("??",Font.BOLD,23);
String msg ="??:"+score;
g.setColor(new Color(FONT_COLOR));
g.setFont(font);
g.drawString(msg, x, y);
y+=2*CELL_SIZE;
msg = "??:"+lines;
g.drawString(msg, x, y);
if(gameOver){
msg = "(T_T)?S???";
y+=2*CELL_SIZE;
x-=CELL_SIZE;
g.drawString(msg, x, y);
}else if(pause){
msg = "?C???";
y+=2*CELL_SIZE;
g.drawString(msg, x, y);
}else{
msg = "?P???";
y+=2*CELL_SIZE;
g.drawString(msg, x, y);
}
}
//?????????
public void paintTetrisBorder(Graphics g){
g.setColor(new Color(BORDER_COLOR));
g.drawRect(0, 0, CELL_SIZE*(COLS+8)-1, CELL_SIZE*ROWS);
}
//???????????
public void paintCurrentTetro( Graphics g){
if(currentTetro==null){
//????????,??????
return;
}
for(Cell cell:currentTetro.cells){
int row = cell.getRow();
int col = cell.getCol();
int x = col*CELL_SIZE;
int y = row*CELL_SIZE;
g.setColor(new Color(cell.getColor()));
g.fillRect(x, y, CELL_SIZE, CELL_SIZE);
g.setColor(new Color(BORDER_COLOR));
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}
}
//???????????
public void paintNextTetro( Graphics g){
if(nextTetro==null){
//????????,??????
return;
}
for(Cell cell:nextTetro.cells){
int row = cell.getRow();
int col = cell.getCol();
int x = (col+9)*CELL_SIZE;
int y = (row+1)*CELL_SIZE;
g.setColor(new Color(cell.getColor()));
g.fillRect(x, y, CELL_SIZE, CELL_SIZE);
g.setColor(new Color(BORDER_COLOR));
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}
}
//???????????
public void action(){
startGameAction();
//???????????
this.requestFocus();
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
int key= e.getKeyCode();
if(gameOver){
if(key==KeyEvent.VK_S){
startGameAction();
}
return;
}
if(pause){
if(key==KeyEvent.VK_C){
continueAction();
}
return;
}
switch(key){
case KeyEvent.VK_DOWN:
softDownAction();
break;
case KeyEvent.VK_LEFT:
moveLeftAction();
break;
case KeyEvent.VK_RIGHT:
moveRightAction();
break;
case KeyEvent.VK_UP:
rotateRightAction();
break;
case KeyEvent.VK_SPACE:
hardDownAction();
break;
case KeyEvent.VK_P:
pauseAction();
break;
}
repaint();
}
//???????
private void pauseAction() {
pause = true;
timer.cancel();
}
//???????
private void continueAction() {
pause = false;
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
softDownAction();
repaint();
}
}, 500, 500);
}
});
}
//???????????S??????
public void startGameAction(){
gameOver = false;
pause = false;
score = 0;
lines = 0;
//???????
emptyWall();
//?????????
nextTetromino();
//???????
timer = new Timer();
//???????
timer.schedule(new TimerTask() {
public void run() {
//?????????????(????)
softDownAction();
//????
repaint();
}
}, 500, 500);
}
//?????????
public void emptyWall(){
for(int row =0;row<ROWS;row++){
//wall[row]??????null??
s.fill(wall[row], null);
}
}
//??(??)???????,1.?????????2.????????
public void nextTetromino(){
if(nextTetro==null){
//???nextTetro?null????????
nextTetro = Tetromino.randomTetromino();
}
//?????????????????
currentTetro = nextTetro;
nextTetro = Tetromino.randomTetromino();
}
//????????,???????????????????????????
//?????????????????????????????????
public void softDownAction(){
if(canDown()){
//??????????
currentTetro.softDown();
}else{
//??????????
tetrominoLandToWall();
//????????????????
destroy();
//???????????????????
if(gameOver()){
//??????
gameOverAction();
}else{
//???????????
nextTetromino();
}
}
}
//????????????(???????????????)
private boolean canDown() {
//???????
Cell [] cells = currentTetro.cells;
for(Cell cell:cells){
if(cell.getRow()==ROWS-1){
return false;
}
}
//??????????????
for(Cell cell:cells){
int row = cell.getRow();
int col = cell.getCol();
Cell block = wall[row+1][col];
if(block!=null){
return false;
}
}
return true;
}
//??“??”???,??????????????row???col,?cell????????wall[row][col]???
private void tetrominoLandToWall() {
Cell [] cells = currentTetro.cells;
for(Cell cell:cells){
int row = cell.getRow();
int col = cell.getCol();
//?cell????????wall[row][col]???
wall[row][col]=cell;
}
}
//???????
private void destroy() {
//?????????
int lines =0;
for(int row =0 ;row<ROWS;row++){
//?????????
if(fullCells(row)){
//????
clearLine(row);
//??????????
lines++;
}
}
//???????????????????????
score += SCORE_LEVEL[lines];
this.lines += lines;
}
//?????????cell???
private boolean fullCells(int row) {
Cell[]line = wall[row];
for(int i=0; i
if(line[i]==null){
//???????????cell,?????
return false;
}
}
return true;
}
//???????,??:(???????????????,??????null??)
private void clearLine(int row) {
//??????????????????
for(int i=row; i>=1;i--){
//wall[row] = s.copyOf(wall[row-1], COLS);
System.arraycopy(wall[row-1], 0, wall[row], 0, COLS);
}
//??????null??
s.fill(wall[0], null);
}
//????????(??:??????????????????????cell??????)
private boolean gameOver() {
gameOver = wall[0][3]!=null||wall[0][4]!=null;
return gameOver;
}
//????????(?????)
private void gameOverAction() {
//?????
timer.cancel();
}
//???????????????:1.???????????2.????????????
//?????
private void moveLeftAction() {
currentTetro.moveLeft();
if(outOfBounds()||coincide()){
currentTetro.moveRight();
}
}
//???????????????????
private boolean coincide() {
for(Cell cell:currentTetro.cells){
int col = cell.getCol();
int row = cell.getRow();
//System.out.println(col+":"+row);
if(wall[row][col]!= null){
return true;
}
}
return false;
}
//??????????????
private boolean outOfBounds() {
for(Cell cell:currentTetro.cells){
int col = cell.getCol();
if(col<0||col>=COLS){
return true;
}
}
return false;
}
//?????
private void moveRightAction() {
currentTetro.moveRight();
if(outOfBounds()||coincide()){
currentTetro.moveLeft();
}
}
//???????????
private void hardDownAction() {
//????????
while(canDown()){
currentTetro.softDown();
}
//?????
tetrominoLandToWall();
//???????
destroy();
if(gameOver()){
gameOverAction();
}else{
nextTetromino();
}
}
//??????
private void rotateRightAction() {
currentTetro.rotateRight();
if(outOfBounds()||coincide()){
currentTetro.rotateLeft();
}
}
}
2.2.2方块类
代码:
package Tetris;
//?????????????
public class Cell {
//?????????????
private int row;
//?????????????
private int col;
//??????
private int color;
public Cell(int row, int col, int color){
this.row = row;
this.col = col;
this.color = color;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
//???????
public void down() {
row++;
}
//???????
public void left() {
col--;
}
//???????
public void right() {
col++;
}
}
2.2.3七种方块旋转属性定义类
代码:
package Tetris;
import java.util.Random;
//?????,?7???:I T S Z J L O
public abstract class Tetromino {
//??????????????
public static final int I_COLOR =0xff9988;
public static final int T_COLOR =0x44ff88;
public static final int S_COLOR =0x704077;
public static final int Z_COLOR =0xccee00;
public static final int J_COLOR =0xff1144;
public static final int L_COLOR =0x1122ff;
public static final int O_COLOR =0x6642bb;
//??????????(Cell)??
protected Cell[]cells = new Cell[4];
//?????????????(????)
protected Offset[] states;
//???????
protected class Offset{
int row0,col0;
int row1,col1;
int row2,col2;
int row3,col3;
public Offset(int row0,int col0,
int row1,int col1,
int row2,int col2,
int row3,int col3){
this.row0 = row0;
this.col0 = col0;
this.row1 = row1;
this.col1 = col1;
this.row2 = row2;
this.col2 = col2;
this.row3 = row3;
this.col3 = col3;
}
}
//?????????????
public static Tetromino randomTetromino(){
Random random = new Random();
//
int type = random.nextInt(7);
switch(type){
case 0:
return new I();
case 1:
return new T();
case 2:
return new J();
case 3:
return new O();
case 4:
return new S();
case 5:
return new L();
case 6:
return new Z();
}
return null;
}
//???????,??????????
public void softDown() {
for(int i=0;i<cells.length;i++){
cells[i].down();
}
}
public void moveLeft() {
for(int i=0;i<cells.length;i++){
cells[i].left();
}
}
public void moveRight() {
for(int i=0;i<cells.length;i++){
cells[i].right();
}
}
//????????
private int index = 9999;
//????
public void rotateRight() {
index++;
Offset offset = states[index%states.length];
Cell axis = cells[0];
cells[1].setRow(axis.getRow()+offset.row1);
cells[1].setCol(axis.getCol()+offset.col1);
cells[2].setRow(axis.getRow()+offset.row2);
cells[2].setCol(axis.getCol()+offset.col2);
cells[3].setRow(axis.getRow()+offset.row3);
cells[3].setCol(axis.getCol()+offset.col3);
}
//????
public void rotateLeft() {
index--;
Offset offset = states[index%states.length];
Cell axis = cells[0];
cells[1].setRow(axis.getRow()+offset.row1);
cells[1].setCol(axis.getCol()+offset.col1);
cells[2].setRow(axis.getRow()+offset.row2);
cells[2].setCol(axis.getCol()+offset.col2);
cells[3].setRow(axis.getRow()+offset.row3);
cells[3].setCol(axis.getCol()+offset.col3);
}
}
//I??????
class I extends Tetromino{
public I(){
//I????????????????????
cells[0] = new Cell(0,4,I_COLOR);
cells[1] = new Cell(0,3,I_COLOR);
cells[2] = new Cell(0,5,I_COLOR);
cells[3] = new Cell(0,6,I_COLOR);
//I??????????
states = new Offset[]{
new Offset(0,0,-1,0,1,0,2,0),
new Offset(0,0,0,-1,0,1,0,2)
};
}
}
//T??????
class T extends Tetromino{
public T(){
//T????????????????????
cells[0] = new Cell(0,4,T_COLOR);
cells[1] = new Cell(0,3,T_COLOR);
cells[2] = new Cell(0,5,T_COLOR);
cells[3] = new Cell(1,4,T_COLOR);
//T??????????
states = new Offset[]{
new Offset(0,0,1,0,-1,0,0,-1),
new Offset(0,0,0,1,0,-1,-1,0),
new Offset(0,0,-1,0,1,0,0,1),
new Offset(0,0,0,-1,0,1,1,0)
};
}
}
//S??????
class S extends Tetromino{
public S(){
//S????????????????????
cells[0] = new Cell(0,4,S_COLOR);
cells[1] = new Cell(1,3,S_COLOR);
cells[2] = new Cell(0,5,S_COLOR);
cells[3] = new Cell(1,4,S_COLOR);
//S??????????
states = new Offset[]{
new Offset(0,0,1,0,-1,-1,0,-1),
new Offset(0,0,0,1,1,-1,1,0)
};
}
}
//J??????
class J extends Tetromino{
public J(){
//J????????????????????
cells[0] = new Cell(0,4,J_COLOR);
cells[1] = new Cell(0,3,J_COLOR);
cells[2] = new Cell(0,5,J_COLOR);
cells[3] = new Cell(1,5,J_COLOR);
//J??????????
states = new Offset[]{
new Offset(0,0,-1,0,1,0,1,-1),
new Offset(0,0,0,1,0,-1,-1,-1),
new Offset(0,0,-1,0,1,0,-1,1),
new Offset(0,0,0,-1,0,1,1,1)
};
}
}
//L??????
class L extends Tetromino{
public L(){
//L????????????????????
cells[0] = new Cell(0,4,L_COLOR);
cells[1] = new Cell(0,3,L_COLOR);
cells[2] = new Cell(0,5,L_COLOR);
cells[3] = new Cell(1,3,L_COLOR);
//L??????????
states = new Offset[]{
new Offset(0,0,-1,0,1,0,-1,-1),
new Offset(0,0,0,1,0,-1,-1,1),
new Offset(0,0,1,0,-1,0,1,1),
new Offset(0,0,0,-1,0,1,1,-1)
};
}
}
//Z??????
class Z extends Tetromino{
public Z(){
//Z????????????????????
cells[0] = new Cell(0,4,Z_COLOR);
cells[1] = new Cell(0,3,Z_COLOR);
cells[2] = new Cell(1,4,Z_COLOR);
cells[3] = new Cell(1,5,Z_COLOR);
//Z??????????
states = new Offset[]{
new Offset(0,0,-1,0,0,-1,1,-1),
new Offset(0,0,0,-1,1,0,1,1)
};
}
}
//O??????
class O extends Tetromino{
public O(){
//O????????????????????
cells[0] = new Cell(0,4,O_COLOR);
cells[1] = new Cell(0,5,O_COLOR);
cells[2] = new Cell(1,4,O_COLOR);
cells[3] = new Cell(1,5,O_COLOR);
//O??????????
states = new Offset[]{
new Offset(0,0,0,1,1,0,1,1)
};
}
}
测试结果:
开始:游戏自动开始,方块下落;
暂停:P键游戏暂停;
继续:C键游戏继续;
重来:S键重新开始
退出:游戏退出;
(注:游戏在输入法英文状态下才可运行)
测试结果:
方向键“?”:旋转方块;
方向键“?”:使方块加速下落;
方向键“?”:使方块左移;
方向键“?”:使方块右移。
空格键“space”:方块立即下落.
3.2.3 游戏结束测试
本程序中还存在一些不足之处,例如:
1.进一步地功能扩展,如添加音效等;
2.美化玩家进入游戏的界面;
3.对软件进行进一步更详细的测试,以保证软件的可用性和适应性;
4.利用internet 进行用户意见的收集,以加强对软件的及时更新;
5.当游戏结束时,最顶上的方块会出现一些小问题,需要改进。
通过短短的一周的时间,我们从一个对JAVA编程懵懂的学生到现在可以试着用JAVA进行简单程序的设计与编写,虽然在实验过程中,我们遇到了许多的困难,特别是因为大多数的同学还不太适应面向对象的编程风格和思想,看待问题时总是想到用什么结构来实现该功能,而没有将问题看成一个封装的整体来考虑,所以在这次课程设计中我们接触、体验了面向对象设计,使得思维在向面过程向面向对象过度。而且,在这个过程中,我们还学到了彼此之间怎么去配合,我们一致认为同伴之间的合作是最重要的。在程序的设计中,我们彼此之间在设计的选择中发生了很多的分歧,但是通过大家的讨论协商,都达到了一个共识,最后大家共同努力完成了这次设计实验。所以,首先,在这里,感谢朱林老师在这周来的教导,以及感谢小组同学在这段时间里的帮助,因为有你们,才使我们这次课程设计能够预期完成老师布置的任务。
本文来源:https://www.2haoxitong.net/k/doc/ce2ffe470242a8956bece4c4.html
文档为doc格式