码迷,mamicode.com
首页 > 其他好文 > 详细

实验3 --俄罗斯方块 with 20135335郝爽

时间:2015-06-11 00:12:57      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

一、   实验内容

(一)敏捷开发与XP

内容:1.敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。

2.极限编程(eXtreme Programming,XP)是一种全新而快捷的软件开发方法。

要点: 1. XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。

2. 我们关注其中的编码标准,结对编程,代码集体所有,测试,重构等实践。(如实验二中的TDD)

 

(二)编码标准

内容:编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

学习:

1. 软件辅助修改:在eclipse中,用source->Format进行格式规范;

2. 自己命名:包名全部小写,如: io ;类名第一个字母要大写,如:HelloWorldApp;等

(三)结对编程

内容:在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。其中的角色分配为驾驶员(控制键盘输入),领航人(起到领航、提醒作用)。

(四)版本控制

摘要:版本控制提供项目级的 undo(撤销) 功能;•   版本控制允许多人在同一代码上工作;•  版本控制系统保存了过去所作的修改的历史记录;具体步骤如下——

# 添加修改文件

$ git add 所有修改的文件

# 提交到环境中本地代码仓库

$ git commit -m ‘本次修改的描述

# push到git.shiyanlou.com,无需输入密码

$ git push

学习:按照要求指导,逐步在实验楼中完成,截图如下:

(五)重构

摘要:重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。学习:尝试Encapsulate Field(封装)功能:

原图:技术分享

(六)实践项目

同伴郝爽20135335博客地址http://www.cnblogs.com/20135335hs

1.综述

我们采取“先学习,后操作;边操作,边变通”的实验思路。具体方法是:研读要求—学习代码要素—复习TDD内容—构建测试程序—检查测试程序—测试产品代码—修改产品代码—重新检查产品代码—完成实验报告。在这一过程中,我们对各方面内容都进行了详细记录(未在实验楼中进行托管和git)

团队由两名成员组成,详细分工为:

20135335郝爽:负责前期学习的整理工作,将java代码进行必要注释,并对TDD内容进行补充;进行后期测试

20135233杨光:负责中期的测试代码开发;进行后期测试

 

2.研读要求与自我学习(20135211)

1.TDD(Test Driven Development, 测试驱动开发),

TDD的一般步骤如下:

  • 明确当前要完成的功能,记录成一个测试列表
  • 快速完成编写针对此功能的测试用例
  • 测试代码编译不通过(没产品代码呢)
  • 编写产品代码
  • 测试通过
  • 对代码进行重构,并保证测试通过(重构下次实验练习)
  • 循环完成所有功能的开发

2. 测试类具体操作:把鼠标放到项目名上,单击右键,在弹出的菜单中选定New->Source Folder新建一个测试目录test;把鼠标放到test目录上,单击右键,在弹出的菜单中选定New->JUnit Test Case新建一个测试用例类

3.实验要求要点为:程序要有GUI界面,参考用户界面和用户体验;记录TDD和重构的过程,测试代码不要少于业务代码

  

package game;

 

import java.awt.Button; 

import java.awt.Canvas; 

import java.awt.Color; 

import java.awt.Dimension; 

import java.awt.Frame; 

import java.awt.Graphics; 

import java.awt.GridLayout; 

import java.awt.Insets; 

import java.awt.Label; 

import java.awt.Panel; 

import java.awt.TextField; 

import java.awt.event.ActionEvent; 

import java.awt.event.ActionListener; 

import java.awt.event.KeyEvent; 

import java.awt.event.KeyListener; 

import java.awt.event.WindowAdapter; 

import java.awt.event.WindowEvent; 

import java.awt.event.WindowListener;

 

//俄罗斯方块类  

public class ERS_Block extends Frame { 

    public static boolean isPlay = false; 

    public static int level = 1, score = 0; 

    public static TextField scoreField, levelField; 

    public static MyTimer timer; 

    GameCanvas gameScr; 

    public static void main(String[] argus) { 

        ERS_Block ers = new ERS_Block( 

                "俄罗斯方块游戏  V1.0                   Author:Vincent"); 

        WindowListener win_listener = new WinListener(); 

        ers.addWindowListener(win_listener); 

    } 

    // 俄罗斯方块类的构造方法 

    ERS_Block(String title) { 

        super(title); 

        setSize(600, 480); 

        setLayout(new GridLayout(1, 2)); 

        gameScr = new GameCanvas(); 

        gameScr.addKeyListener(gameScr); 

        timer = new MyTimer(gameScr); 

        timer.setDaemon(true); 

        timer.start(); 

        timer.suspend(); 

        add(gameScr); 

        Panel rightScr = new Panel(); 

        rightScr.setLayout(new GridLayout(2, 1, 0, 30)); 

        rightScr.setSize(120, 500); 

        add(rightScr); 

        // 右边信息窗体的布局 

        MyPanel infoScr = new MyPanel(); 

        infoScr.setLayout(new GridLayout(4, 1, 0, 5)); 

        infoScr.setSize(120, 300); 

        rightScr.add(infoScr); 

        // 定义标签和初始值 

        Label scorep = new Label("分数:", Label.LEFT); 

        Label levelp = new Label("级数:", Label.LEFT); 

        scoreField = new TextField(8); 

        levelField = new TextField(8); 

        scoreField.setEditable(false); 

        levelField.setEditable(false); 

        infoScr.add(scorep); 

        infoScr.add(scoreField); 

        infoScr.add(levelp); 

        infoScr.add(levelField); 

        scorep.setSize(new Dimension(20, 60)); 

        scoreField.setSize(new Dimension(20, 60)); 

        levelp.setSize(new Dimension(20, 60)); 

        levelField.setSize(new Dimension(20, 60)); 

        scoreField.setText("0"); 

        levelField.setText("1"); 

        // 右边控制按钮窗体的布局 

        MyPanel controlScr = new MyPanel(); 

        controlScr.setLayout(new GridLayout(5, 1, 0, 5)); 

        rightScr.add(controlScr); 

        // 定义按钮play 

        Button play_b = new Button("开始游戏"); 

        play_b.setSize(new Dimension(50, 200)); 

        play_b.addActionListener(new Command(Command.button_play, gameScr)); 

        // 定义按钮Level UP 

        Button level_up_b = new Button("提高级数"); 

        level_up_b.setSize(new Dimension(50, 200)); 

        level_up_b.addActionListener(new Command(Command.button_levelup, 

                gameScr)); 

        // 定义按钮Level Down 

        Button level_down_b = new Button("降低级数"); 

        level_down_b.setSize(new Dimension(50, 200)); 

        level_down_b.addActionListener(new Command(Command.button_leveldown, 

                gameScr)); 

        // 定义按钮Level Pause 

        Button pause_b = new Button("游戏暂停"); 

        pause_b.setSize(new Dimension(50, 200)); 

        pause_b.addActionListener(new Command(Command.button_pause, gameScr)); 

        // 定义按钮Quit 

        Button quit_b = new Button("退出游戏"); 

        quit_b.setSize(new Dimension(50, 200)); 

        quit_b.addActionListener(new Command(Command.button_quit, gameScr)); 

        controlScr.add(play_b); 

        controlScr.add(level_up_b); 

        controlScr.add(level_down_b); 

        controlScr.add(pause_b); 

        controlScr.add(quit_b); 

        setVisible(true); 

        gameScr.requestFocus(); 

    } 

// 重写MyPanel类,使Panel的四周留空间 

class MyPanel extends Panel { 

    public Insets getInsets() { 

        return new Insets(30, 50, 30, 50); 

    } 

// 游戏画布类 

class GameCanvas extends Canvas implements KeyListener { 

    final int unitSize = 30; // 小方块边长 

    int rowNum; // 正方格的行数 

    int columnNum; // 正方格的列数 

    int maxAllowRowNum; // 允许有多少行未削 

    int blockInitRow; // 新出现块的起始行坐标 

    int blockInitCol; // 新出现块的起始列坐标 

    int[][] scrArr; // 屏幕数组 

    Block b; // 对方快的引用 

    // 画布类的构造方法 

    GameCanvas() { 

        rowNum = 15; 

        columnNum = 10; 

        maxAllowRowNum = rowNum - 2; 

        b = new Block(this); 

        blockInitRow = rowNum - 1; 

        blockInitCol = columnNum / 2 - 2; 

        scrArr = new int[32][32]; 

    } 

    // 初始化屏幕,并将屏幕数组清零的方法 

    void initScr() { 

        for (int i = 0; i < rowNum; i++) 

            for (int j = 0; j < columnNum; j++) 

                scrArr[i][j] = 0; 

        b.reset(); 

        repaint(); 

    } 

    // 重新刷新画布方法 

    public void paint(Graphics g) { 

        for (int i = 0; i < rowNum; i++) 

            for (int j = 0; j < columnNum; j++) 

                drawUnit(i, j, scrArr[i][j]); 

    }  

    // 画方块的方法 

    public void drawUnit(int row, int col, int type) { 

        scrArr[row][col] = type; 

        Graphics g = getGraphics(); 

        switch (type) { // 表示画方快的方法 

        case 0: 

            g.setColor(Color.black); 

            break; // 以背景为颜色画 

        case 1: 

            g.setColor(Color.blue); 

            break; // 画正在下落的方块 

        case 2: 

            g.setColor(Color.magenta); 

            break; // 画已经落下的方法 

        } 

        g.fill3DRect(col * unitSize, getSize().height - (row + 1) * unitSize, 

                unitSize, unitSize, true); 

        g.dispose(); 

    } 

    public Block getBlock() { 

        return b; // 返回block实例的引用 

    } 

    // 返回屏幕数组中(row,col)位置的属性值 

    public int getScrArrXY(int row, int col) { 

        if (row < 0 || row >= rowNum || col < 0 || col >= columnNum) 

            return (-1); 

        else 

            return (scrArr[row][col]); 

    } 

    // 返回新块的初始行坐标方法 

    public int getInitRow() { 

        return (blockInitRow); // 返回新块的初始行坐标 

    } 

    // 返回新块的初始列坐标方法 

    public int getInitCol() { 

        return (blockInitCol); // 返回新块的初始列坐标 

    } 

    // 满行删除方法 

    void deleteFullLine() { 

        int full_line_num = 0; 

        int k = 0; 

        for (int i = 0; i < rowNum; i++) { 

            boolean isfull = true; 

            L1: for (int j = 0; j < columnNum; j++) 

                if (scrArr[i][j] == 0) { 

                    k++; 

                    isfull = false; 

                    break L1;  

                } 

            if (isfull) 

                full_line_num++; 

            if (k != 0 && k - 1 != i && !isfull) 

                for (int j = 0; j < columnNum; j++) { 

                    if (scrArr[i][j] == 0) 

                        drawUnit(k - 1, j, 0); 

                    else 

                        drawUnit(k - 1, j, 2); 

                    scrArr[k - 1][j] = scrArr[i][j]; 

                } 

        } 

        for (int i = k - 1; i < rowNum; i++) { 

            for (int j = 0; j < columnNum; j++) { 

                drawUnit(i, j, 0); 

                scrArr[i][j] = 0; 

            } 

        } 

        ERS_Block.score += full_line_num; 

        ERS_Block.scoreField.setText("" + ERS_Block.score); 

    } 

    // 判断游戏是否结束方法 

    boolean isGameEnd() { 

        for (int col = 0; col < columnNum; col++) { 

            if (scrArr[maxAllowRowNum][col] != 0) 

                return true; 

        } 

        return false; 

    } 

    public void keyTyped(KeyEvent e) { 

    } 

    public void keyReleased(KeyEvent e) { 

    } 

    // 处理键盘输入的方法 

    public void keyPressed(KeyEvent e) { 

        if (!ERS_Block.isPlay) 

            return; 

        switch (e.getKeyCode()) { 

        case KeyEvent.VK_DOWN: 

            b.fallDown(); 

            break; 

        case KeyEvent.VK_LEFT: 

            b.leftMove(); 

            break; 

        case KeyEvent.VK_RIGHT: 

            b.rightMove(); 

            break; 

        case KeyEvent.VK_SPACE: 

            b.leftTurn(); 

            break; 

        } 

    } 

// 处理控制类 

class Command implements ActionListener { 

    static final int button_play = 1; // 给按钮分配编号 

    static final int button_levelup = 2; 

    static final int button_leveldown = 3; 

    static final int button_quit = 4; 

    static final int button_pause = 5; 

    static boolean pause_resume = true; 

    int curButton; // 当前按钮 

    GameCanvas scr; 

    // 控制按钮类的构造方法 

    Command(int button, GameCanvas scr) { 

        curButton = button; 

        this.scr = scr; 

    } 

    // 按钮执行方法 

    public void actionPerformed(ActionEvent e) { 

        switch (curButton) { 

        case button_play: 

            if (!ERS_Block.isPlay) { 

                scr.initScr(); 

                ERS_Block.isPlay = true; 

                ERS_Block.score = 0; 

                ERS_Block.scoreField.setText("0"); 

                ERS_Block.timer.resume(); 

            } 

            scr.requestFocus(); 

            break; 

        case button_levelup: 

            if (ERS_Block.level < 10) { 

                ERS_Block.level++; 

                ERS_Block.levelField.setText("" + ERS_Block.level); 

                ERS_Block.score = 0; 

                ERS_Block.scoreField.setText("" + ERS_Block.score); 

            } 

            scr.requestFocus(); 

            break; 

        case button_leveldown: 

            if (ERS_Block.level > 1) { 

                ERS_Block.level--; 

                ERS_Block.levelField.setText("" + ERS_Block.level); 

                ERS_Block.score = 0; 

                ERS_Block.scoreField.setText("" + ERS_Block.score); 

            } 

            scr.requestFocus(); 

            break; 

        case button_pause: 

            if (pause_resume) { 

                ERS_Block.timer.suspend(); 

                pause_resume = false; 

            } else { 

                ERS_Block.timer.resume(); 

                pause_resume = true; 

            } 

            scr.requestFocus(); 

            break; 

        case button_quit: 

            System.exit(0); 

        } 

    } 

// 方块类 

class Block { 

    static int[][] pattern = { 

            { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 用十六进至表示,本行表示长条四种状态 

            { 0x04e0, 0x0464, 0x00e4, 0x04c4 }, 

            { 0x4620, 0x6c00, 0x4620, 0x6c00 }, 

            { 0x2640, 0xc600, 0x2640, 0xc600 }, 

            { 0x6220, 0x1700, 0x2230, 0x0740 }, 

            { 0x6440, 0x0e20, 0x44c0, 0x8e00 }, 

            { 0x0660, 0x0660, 0x0660, 0x0660 } }; 

    int blockType; // 块的模式号(0-6) 

    int turnState; // 块的翻转状态(0-3) 

    int blockState; // 快的下落状态 

    int row, col; // 块在画布上的坐标 

    GameCanvas scr; 

    // 块类的构造方法 

    Block(GameCanvas scr) { 

        this.scr = scr; 

        blockType = (int) (Math.random() * 1000) % 7; 

        turnState = (int) (Math.random() * 1000) % 4; 

        blockState = 1; 

        row = scr.getInitRow(); 

        col = scr.getInitCol(); 

    } 

    // 重新初始化块,并显示新块 

    public void reset() { 

        blockType = (int) (Math.random() * 1000) % 7; 

        turnState = (int) (Math.random() * 1000) % 4; 

        blockState = 1; 

        row = scr.getInitRow(); 

        col = scr.getInitCol(); 

        dispBlock(1); 

    } 

    // 实现“块”翻转的方法 

    public void leftTurn() { 

        if (assertValid(blockType, (turnState + 1) % 4, row, col)) { 

            dispBlock(0); 

            turnState = (turnState + 1) % 4; 

            dispBlock(1); 

        } 

    } 

    // 实现“块”的左移的方法 

    public void leftMove() { 

        if (assertValid(blockType, turnState, row, col - 1)) { 

            dispBlock(0); 

            col--; 

            dispBlock(1); 

        } 

    } 

    // 实现块的右移 

    public void rightMove() { 

        if (assertValid(blockType, turnState, row, col + 1)) { 

            dispBlock(0); 

            col++; 

            dispBlock(1); 

        } 

    } 

    // 实现块落下的操作的方法 

    public boolean fallDown() { 

        if (blockState == 2) 

            return (false); 

        if (assertValid(blockType, turnState, row - 1, col)) { 

            dispBlock(0); 

            row--; 

            dispBlock(1); 

            return (true); 

        } else { 

            blockState = 2; 

            dispBlock(2); 

            return (false); 

        } 

    } 

    // 判断是否正确的方法 

    boolean assertValid(int t, int s, int row, int col) { 

        int k = 0x8000; 

        for (int i = 0; i < 4; i++) { 

            for (int j = 0; j < 4; j++) { 

                if ((int) (pattern[t][s] & k) != 0) { 

                    int temp = scr.getScrArrXY(row - i, col + j); 

                    if (temp < 0 || temp == 2) 

                        return false; 

                } 

                k = k >> 1; 

            } 

        } 

        return true; 

    } 

    // 同步显示的方法 

    public synchronized void dispBlock(int s) { 

        int k = 0x8000; 

        for (int i = 0; i < 4; i++) { 

            for (int j = 0; j < 4; j++) { 

                if (((int) pattern[blockType][turnState] & k) != 0) { 

                    scr.drawUnit(row - i, col + j, s); 

                } 

                k = k >> 1; 

            } 

        } 

    } 

// 定时线程 

class MyTimer extends Thread { 

    GameCanvas scr; 

    public MyTimer(GameCanvas scr) { 

        this.scr = scr; 

    } 

    public void run() { 

        while (true) { 

            try { 

                sleep((10 - ERS_Block.level + 1) * 100); 

            } catch (InterruptedException e) { 

            } 

            if (!scr.getBlock().fallDown()) { 

                scr.deleteFullLine(); 

                if (scr.isGameEnd()) { 

                    ERS_Block.isPlay = false; 

                    suspend(); 

                } else 

                    scr.getBlock().reset(); 

            } 

        } 

    } 

class WinListener extends WindowAdapter { 

    public void windowClosing(WindowEvent l) { 

        System.exit(0); 

    } 

}技术分享

 

 

 技术分享

6.实验感悟

本次实验,我们没有进入实验楼完成,自己在电脑上自主做实验,在游戏设计的时候并不是一帆风顺,有许多问题都咨询了学长与同学。

在实验中我们也有查阅网上有关的游戏资料,增长了许多知识与见识,对我的程序设计有很大的帮助。

 

实验3 --俄罗斯方块 with 20135335郝爽

标签:

原文地址:http://www.cnblogs.com/yg137565645/p/4567753.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!