俄罗斯方块实验报告.doc_第1页
俄罗斯方块实验报告.doc_第2页
俄罗斯方块实验报告.doc_第3页
俄罗斯方块实验报告.doc_第4页
俄罗斯方块实验报告.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

南京邮电大学通达学院算法与数据结构设计报告( 2016/ 2017学年 第 二 学期)专 业软件工程嵌入式学 号 姓 名学 号 姓 名学 号 姓 名指 导 教 师指 导 单 位计算机学院计算机科学与技术系日 期2017-5-26评 分 细 则评分项优秀良好中等差遵守机房规章制度上机时的表现学习态度程序准备情况程序设计能力团队合作精神课题功能实现情况算法设计合理性报告书写认真程度内容详实程度验收答辩情况评分等级姓名(组长)姓名(组员1)姓名(组员2)姓名(组员3)简 短 评 语指导教师签名日期2017-5-27备注评分等级有五种:优秀、良好、中等、及格、不及格26目录课题内容-1算法设计与分析-1算法实现-9测试数据及结果分析-38调试过程中的问题-40总结-41俄罗斯方块1、 课题内容实现俄罗斯方块游戏。主要功能为游戏界面显示、上下左右键响应以及当前得分统计。通过该课题全面熟悉数组、字符串等的使用。掌握设计的基本方法及友好界面的设计。课题要求:1、 游戏界面显示:下落方块和方块堆、左右移动、旋转、删除行等特效以及得分。2、 动作选择:上下左右键对应于旋转、加速、左右移动的功能。3、 得分统计判断:判定能否消除行、并统计得分总数等。扩展要求:1、 用户数据管理。2、 游戏玩法:由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。基本规则1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。I:一次最多消除四层J(左右):最多消除三层,或消除二层L:最多消除三层,或消除二层O:消除一至二层S(左右):最多二层,容易造成孔洞Z (左右):最多二层,容易造成孔洞T:最多二层(1)部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。方块会从区域上方开始缓慢继续落下。(2)玩家可以做的操作有:以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。(3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。(4)当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。(5)当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。(6)一般来说,游戏还会提示下一个要落下的方块,熟练的玩家会计算到下一个方块,评估要如何进行。由于游戏能不断进行下去对商业用游戏不太理想,所以一般还会随着游戏的进行而加速提高难度。2、 算法设计与分析I、俄罗斯方块游戏需要解决的问题包括(1)、随机产生方块并自动下移(2)、用 键变体(3)、用 键和 键左右移动方块,按Q退出,按space暂停II、俄罗斯方块游戏需要设计的功能函数包括(1)、声明俄罗斯方块的结构体(2)、函数原型声明(3)、制作游戏窗口(4)、制作俄罗斯方块(5)、判断是否可动(6) 、随机产生俄罗斯方块类型序号(7) 、判断是否满行并删除满行的俄罗斯方块(8)暂停,继续功能(9)新游戏创建(10)用户的创建,分数用户名的保存,查看分数TetrisScorePanelnameScore类之间的关系tetrisblokMembersTetris类(主要类)该类包含main方法,应为应用程序的主类。该类用来创建游戏的用户界面,事件处理功能和menu餐单,用户信息的存储。整个程序从该类的main方法开始执行。成员变量:String userName;构造方法:TetrisuserName=JOptionPane.showInputDialog(null, 输入你的名字);if(userName=null|userName.equals()userName=无名氏;/如果没有命名就定义为无名氏内部类:Members,TetrisblockTetrisblok类:用来设计游戏界面。游戏界面显示在由Tetrisblok类创建的整个用户界面的中(Center)区,游戏的即时分数、方块的效果图及方的预览功能都在整个类里面实现。用来封装俄罗斯小方块。一个方块的属性是由方块1位置即x和y的坐标、颜色决定的。成员变量private int blockType; Timer timer=null; private int turnState; private int x; private int y; private int i = 0; int j = 0; static int score = 0; int flag = 0; int delay=1000; / 定义已经放下的方块x=0-12,y=0-22; int map = new int1424; / 方块的形状 第一组代表方块类型有S、Z、L、J、I、O、T 7种 第二组 代表旋转几次 第三四组为 方块矩阵 private final int shapes成员方法: public void newblock()public void drawwall()public void newmap()public void newgame()public void turn();public void left(); public void right(); public void down() ; public int blow(int x, int y, int blockType, int turnState); public void delline() ; public int gameover(int x, int y); public void add(int x, int y, int blockType, int turnState); public void paintComponent(Graphics g); public void keyPressed(KeyEvent e); public void keyTyped(KeyEvent e)Members类:用来创建io流,在D盘中查找username.txt文件,如果没有就创建。并且在username和score中间用:隔开,方便以后用split对其进行分割。成员变量:private FileWriter fw=null;private BufferedWriter bw=null;private FileReader fr=null;private BufferedReader br=null; Tetris tt=null; boolean vip=true;/如果有usernametxt这个文件的话 就返回true并且允许查看分数 判断是否有用户已经创建了 ArrayList al=new ArrayList();成员方法:getMembers()saveMembers()getpaint()GetMembers()方法获取username.txt 的File对象NameScore类: private String username; private String score;public String getUsername() public String getUsername() public void setUsername(String username) public String getScore() 每一个用户的分数和姓名存到一个对象NameScore类。ScorePanel类;Vector col=null;Vector rol=null;JTable jt;public ScorePanel(ArrayList al) throws IOException这个是用来接收Tetris类中传递过来的储存NameScore对象的ArrayList集合,然后把用迭代器将集合中的每一个对象的username和score取出来然后放到Vector中。然后添加到JTable中。三、算法实现1.0 Tetris类(主要类) Tetris类功能该类包含main方法,应为应用程序的主类。该类用来创建游戏的用户界面,事件处理功能和menu餐单,用户信息的存储。整个程序从该类的main方法开始执行。成员变量:String userName; 构造方法:Tetris 实现在初始化的时候进行弹框 如果没有输入值则就将username命名为无名氏public Tetris() throws IOExceptionuserName=JOptionPane.showInputDialog(null, 输入你的名字);if(userName=null|userName.equals()userName=无名氏;/如果没有命名就定义为无名氏final JMenuItem pause; final JMenuItem goon;final JMenuItem getscore;final JMenuItem exit;final JMenuItem saveexit;newgame.addActionListener(new ActionListener()菜单事件点击menuitem中的各个选项,会运行的函数pause.addActionListener(new ActionListener()goon.addActionListener(new ActionListener()getscore.addActionListener(new ActionListener()exit.addActionListener(new ActionListener()saveexit.addActionListener(new ActionListener()high.addActionListener(new ActionListener()2.Tetrisblok类Tetrisblok类功能:用来设计游戏界面。游戏界面显示在由Tetrisblok类创建的整个用户界面的中(Center)区,游戏的即时分数、方块的效果图及方的预览功能都在整个类里面实现。用来封装俄罗斯小方块。实现创建新游戏,暂停,继续并且通过调用members类来实现用户姓名,分数的存储,和记录的读取 。画出俄罗斯方块的形状和变形之后的形状是根据三维数组来的 private final int shapes = new int 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 , 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 这个只是一种形状和变换之后的形状还有s,z,j,l,t和方形Newblock()方法Newblock方法的功能这个方法是产生一个新的方块,并且判断游戏是否已经结束,如果游戏结束的话就弹出一个提示框并且将Map清零 blockType = (int) (Math.random() * 1000) % 7; turnState = (int) (Math.random() * 1000) % 4;x = 4; y = 0; if (gameover(x, y) = 1) newmap(); drawwall(); score = 0; JOptionPane.showMessageDialog(null, GAME OVER); Blow方法(判断方块的下一个动作是否合法)Blow方法功能for循环出所有4*4表格中的值,每当取到一个1的时候表示这是方块的组成元素之一 ,mapx+b+zy+a表示组成元素之一碰撞到障碍物的时候 或者碰撞到墙壁的时候 因为墙壁是2。返回1就是合法,返回0就是不合法public int blow(int x, int y, int blockType, int turnState) for (int a = 0; a 4; a+) for (int b = 0; b 4; b+) if (shapesblockTypeturnStatea * 4 + b = 1) & (mapx + b + 1y + a = 1) | (shapesblockTypeturnStatea * 4 + b = 1) & (mapx + b + 1y + a = 2) return 0; return 1; Deline()方法Deline()方法功能判断每一行是否满行,满行的话就消行,消行就上让满行的上一行的每一个元素下移一行。public void delline() int c = 0; for (int b = 0; b 23; b+) for (int a = 0; a 0; d-) /这行是上面的那行下来 需要消行上面的那行下来就嫩实现消行 for (int e = 0; e 12; e+) maped = maped - 1; c = 0; paintComponent(Graphics g)方法:这个方法实现画笔的功能,将当前正在运行的方块和已经存在的画到panel中,并且显示已经得到的分数因为每个方块都是有一个含有16个元素的数组组成所以要从第一个元素开始查找到最后一个,如果有一个元素为1就表示这个位置是一个方块的组成。同样的固定的方块也是这样画出来的。 super.paintComponent(g); / 画当前方块 for (j = 0; j 16; j+) if (shapesblockTypeturnStatej = 1) g.fillRect(j % 4 + x + 1) * 15, (j / 4 + y) * 15, 15, 15); / 画已经固定的方块 在这里变成13列 23行 for (j = 0; j 23; j+) for (i = 0; i 13; i+) if (mapij = 1) g.fillRect(i * 15, j * 15, 15, 15); if (mapij = 2) g.drawRect(i * 15, j * 15, 15, 15); g.drawString(score= + score, 200, 10); / g.drawString(你的名字:+new Tetris().userName, 200, 30); g.drawString(抵制不良游戏,, 200, 80); g.drawString(拒绝盗版游戏。, 200, 100); g.drawString(注意自我保护,, 200, 120); g.drawString(谨防受骗上当。, 200, 140); g.drawString(适度游戏益脑,, 200, 160); g.drawString(沉迷游戏伤身。, 200, 180); g.drawString(合理安排时间,, 200, 200); g.drawString(享受健康生活。, 200, 220); 键盘事件当你按上下左右的时候回触发相应的事件 public void turn()public void left()public void right() public void down()add方法:add方法的功能:因为每个方块是由16个元素构成,16个元素又可以构成4行4列。从第一行开始,后面的每一列,如果map中在正在运行的方块的当前位置的x坐标+1是一个0的话,也就表示x的下一个位置不是墙或是已经形成的障碍物就让这个正在运行的方块成为下一个障碍物,也就是Map数组中对应位置的元素改为1public void add(int x, int y, int blockType, int turnState) int j = 0; for (int a = 0; a 4; a+) for (int b = 0; b 4; b+) if (mapx + b + 1y + a = 0) mapx + b + 1y + a = shapesblockTypeturnStatej; ; j+; Members类;这个类主要是用来对用户的名字和的分进行储存,和读取,并且能够创建新的面板(得分面板)private FileWriter fw=null;private BufferedWriter bw=null;private FileReader fr=null;private BufferedReader br=null;Tetris tt=null; boolean vip=true;/如果有usernametxt这个文件的话 就返回true并且允许查看分数 判断是否有用户已经创建了ArrayList al=new ArrayList();/将每一个用户对象存储到集合中saveMembers()方法储存用户信息的方式使用io流在d盘中创建txt的文件,这个方法是创建file对象,如果d盘中没有txt文件就想创建。将用户信息写在txt文件中并且将username和score之间用:分开为了之后的方法将他分开。并且在文件存在将FileWriter端口关闭。 public void saveMembers() throws IOException String username=userName;/将外部类的username赋值给内部类username Tetrisblok tb=new Tetrisblok();/这是存数据 File file=new File(d:username.txt); if(!file.exists() file.createNewFile(); / int map=tb.map; fw=new FileWriter(d:username.txt,true); bw=new BufferedWriter(fw);/ for(int i=0;imap.length;i+)/ for(int j=0;jmap0.length;j+)/ bw.write(mapij+t);/ / bw.write(rn);/ bw.write(username+:+tb.score+rn); bw.close(); System.out.println(username+分数是+tb.score); /显示读取出的数组getMembers()方法:创建file对象获取txt文件,如果txt文件并不存在的话,就弹出一个窗口并且显示并没有任何用户否则的话就获得bufferedwriter对象。并且读取每一行的数据,readline是一次读取一行,并且每次以字符串的形式返回这一行的数据。知道读取到null为止。得到的每一行数据用split方法进行分割,分割后的数据前面一个放在temp数组的第一个位置,第二个放在第二个位置中。然后将得到的数据分别存到NameScore对象中。NameScore每次while循环都会创建一次。public void getMembers() throws IOException File file=new File(d:username.txt); if(!file.exists() JOptionPane.showMessageDialog(null, 尚未有任何用户); vip=false;/如果没有的话就返回false else String line=null; fr=new FileReader(d:username.txt); br=new BufferedReader(fr);/ System.out.println(运行到这里2);while(line = br.readLine()!= null)/每次读取一行 同时以字符串的形式返回这一行的数据回这一直到null停止NameScore ns=new NameScore();String temp=line.split(:);ns.setUsername(temp0);/System.out.println(temp0);ns.setScore(temp1);al.add(ns);/System.out.println(line + row + : + line); br.close(); Getpaint()方法Getpaint()方法功能得到jtable对象并且将其显示在一个新的jpanel中public void getpaint() throws IOException JPanel jp=new JPanel(); Vector col=new Vector(); col.add(用户名); col.add(得分); Vector row=new Vector(); ScorePanel sp=new ScorePanel(al); JTable jt=new JTable(sp); jp.add(jt); this.add(jp); this.setVisible(true); this.setSize(300,400); 4.ScorePanel类Vector col=null;Vector rol=null;JTable jt;ScorePanel类实现的功能这是一个带参的构造函数主要功能是将members类传递过来的arraylist集合进行处理,将集合用迭代器获取里面的每一个对象,并将每一个对象中的username属性和score属性放置在vector中public ScorePanel(ArrayList al) throws IOExceptioncol=new Vector();col.add(用户名);col.add(分数);rol=new Vector();ArrayList all=al; Iterator it=all.iterator();while(it.hasNext()Vector user=new Vector();NameScore userInfo=it.next();/System.out.println(userInfo.getScore()+dasda);/System.out.println(userInfo.getUsername()+dasda);user.add(userInfo.getUsername();user.add(userInfo.getScore();/到这个步骤都是对的 it.next()都有值rol.add(user);jt=new JTable(rol,col);5.nameScore()类这个类主要就是储存用户的姓名和对应的得分,每一个nameScore()类就封装一个用户对象private String username; private String score;和这些变量的set和get方法public String getUsername() public void setUsername(String username) public String getScore() public void setScore(String score) 4、 测试数据及结果分析测试项目1游戏的运行,是否会出现弹窗,初始界面。2点击“开始新游戏”,游戏是否刷新。3点击“暂停”,游戏是否暂停。4点击“加速”,游戏速度是否加快。5点击“减速”,游戏速度是否降低。6分别按键盘上的“左”、“右”、“下”、“上”,方块是否左移、右移、下移、变形。7当一层满了以后,是否消掉此层,是否会记录分数。8当方块累积到最高点时,游戏是否会自动结束。9点击“退出游戏”,游戏是否关闭。10.点击”保存并退出游戏”,游戏用户信息是否会保存,游戏是否关闭11.点击”查看分数”,是否会出现新的jpanel框,并且里面是否会显示已经存入的信息。游戏运行情况 点击运行程序之后,游戏开始,上面两幅图就是游戏运行的画面 超过边界游戏结束 加速减速点击之后时间计时器重新工作即实现继续功能 点击暂停时间计时器停止计时即实现暂停功能保存并退出然后d盘下面会有一个username.txt文件得到成员的姓名和分数点击”查看分数”会弹出来分数面板里面显示已经保存过的用户的名字和得分经过调试和修改,程序完全实现设计要求,成功模拟了俄罗斯方块的运行过程和游戏效果,只是界面略微简陋,但已从程序层面上实现了游戏,达到了这次实训的要求和目的。程序正常生成方块,根据速度值每隔一定时间自动下落,如有操作按键按下,根据按键实现位移和变形。当方块满一行后,可以消除该行,同时记录分数和等级。五、调试过程中的问题1.刚开始的时候在障碍物的问题上总是出现数组越界错误2.俄罗斯方块的变形问题,不是顺时针变形,原来是方块数组的排序出现错误2.在添加事件的时候点击新游戏分数不刷新,后来在tetris类中的newgame中添加了score=0之后解决了问题4.在实现加速和减速的问题上,一开始speed控制的是在时间间隔不变的情况下,变化方块每次跳动的距离,发现比较麻烦后来改用在每次跳动距离不变的情况下,改变事件发生的间隔,间隔越短就越快,但是只能大于0并且小于15005.在点击暂停按钮之后然后点击新游戏会出现错误6.在内部类调用外部类的变量的时候出现错误;7.在程序刚开始运行的时候,弹出来的Input框,如果我没有进行任何处理的话,会报空指针异常虽然我在下面加上了如果username=null但是并没有运行,后来知道原来在if选项中我的username.equal(“”)|username=null写颠倒过来了导致。8.在实现用户信息管理的时候用的是io流储存,将每次输入的用户名存在username的txt文件下面,如果没有这个文件的话要先创建。9.在对txt文本中的内容进行分割处理的时候,spilt写了但没作用到网上一查,我当时用的是:进行分割,所以split应该写成split(“/:”)而且返回的是一个数组;第一个数temp0,第二个数temp1;10.在实现将用户信息返回到新的jpanel上面的时候,ScorePanel总是得不到从Tetris传过来的值,显示一个异常,根据断点找到是在迭代器中it.next返回的是一个对象,而且最好的实在实例化一个迭代器的时候对其进行泛型。在将迭代器改成泛型之后顺利解决六、AI设计思路

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论