j2me设计论文-俄罗斯方块.doc_第1页
j2me设计论文-俄罗斯方块.doc_第2页
j2me设计论文-俄罗斯方块.doc_第3页
j2me设计论文-俄罗斯方块.doc_第4页
j2me设计论文-俄罗斯方块.doc_第5页
免费预览已结束,剩余35页可下载查看

下载本文档

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

文档简介

面向对象程序设计II -J2ME课程设计论文题 目:俄罗斯方块学 院:计算机与信息工程学院专 业:计算机科学与技术班 级:计算机06-7班姓 名:曲春良学 号:09起止时间:2008.12.21-2008.12.31 成绩: 课程设计成绩评定表质量评价指标(在相应栏目打)评 价 项 目评 价 质 量优秀良好一般及格不及格工作量和态度实验、计算可靠性文字和图表质量程序完成情况总体评价评定成绩评定人员签名2008年12月31日IV课程设计任务书一、设计题目:俄罗斯方块二、设计内容:提起“俄罗斯方块”,在当今世界上,几乎无人不知它是一个经典的游戏。对于那些在机场等待飞机起飞或者每天需乘车上下班的人来说,俄罗斯方块游戏很容易让他们着迷,成了他们打发时间的一种消遣。俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事。这款游戏最初是由苏联的游戏制作人Alex Pajitnov制作的,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得茶饭不思的那个俄罗斯方块时代。三、设计要求:游戏有7种下坠物,如“田”字形,“L”字形等,每种下坠物可以左移、右移、下坠以及变形;当游戏区域(所谓的游戏区域是,把整个屏幕分为游戏区域和非游戏区域,游戏区域16个砖块高,12个砖块宽,而非游戏区域用来显示下一个下坠物、分数以及速度)中满行时系统就进行记分,并且消行,上面的砖块下移;如果方块不能再出现并往下移,就表明游戏结束。l 记分机制:1、2行就10、20分,3行40分,4行50分;行数越多分数越高;l 随机产生方块,每满100分就提高一个等级,最低0级,最高为9级;l 不能连续按键;l “左”按左键,“右”按右键,“下移”按下键,“变”按Fire键。l 用户设定等级。四、工作计划:时间完成内容提交文档备注第1天查找资料,确定题目,选择方案课程设计任务书设计准备阶段第2天第3天题目分析,设计算法算法描述设计阶段第4天功能模块的划分和设计结构流程图等第5天第6天实现具体数据结构和模块无第7天程序设计与调试无运行并验证程序功能第8天第9天检查程序第10天整理材料,撰写论文课程设计论文指导教师: 王艳涛 陈伟 高辉 教研室主任: 2008 年 12月31 日II 本科课程设计论文摘 要游戏中,充分利用J2ME的知识在手机上实现一个经典的俄罗斯方块。要求随机产生方块,可以左右移动、下移和变形,满行时可以消行并且记分,满100分时还要升级同时加速;同时还要求人机操作合理,让人一看就懂。手机游戏的设计不许秉承人性化的特点,在没有详细的用户说明的时候,用户仍然可以轻易的理解游戏的意图,并且很容易的从中得到快乐。 关键词:J2ME 面向对象 俄罗斯方块III目 录课程设计成绩评定表II课程设计任务书III摘 要III目 录IV1 设计内容22 设计过程22.1设计方案的论证22.2概要设计32.3界面设计图32.4代码实现73 设计总结8参考文献8附录:程序源代码91 设计内容游戏有7种下坠物,如“田”字形,“L”字形等,每种下坠物可以左移、右移、下坠以及变形;当游戏区域(所谓的游戏区域是,把整个屏幕分为游戏区域和非游戏区域,游戏区域16个砖块高,12个砖块宽,而非游戏区域用来显示下一个下坠物、分数以及速度)中满行时系统就进行记分,并且消行,上面的砖块下移;如果方块不能再出现并往下移,就表明游戏结束2 设计过程2.1设计方案的论证MIDP的游戏设计,本质上就是用一个线程或者定时器产生重绘事件,用线程和用户输入改变游戏状态。游戏也不例外,启动MIDlet后,就立即生成一个重绘线程,该线程每隔speed(程序中设置的变量,用来控制游戏的速度)ms绘制一次屏幕。当然,重绘时有一些优化措施,并不是屏幕上所有的像素都需要重绘,而是有所选择,比如游戏画布上那些已经固定下来的下坠物(下坠物一共有7种,由4个小砖块组成,每种下坠物颜色固定,可以上下左右旋转)就不需重绘。游戏画布是一个CommandListener,可以接受用户键盘命令,控制下坠物的左移,右移,下移,旋转动作。整个游戏的流程控制体现在游戏画布对象的paint()方法里。paint()根据当前的游戏状态,绘制出当时的游戏画面。欢迎画面和Game Over画面的绘制相当简单,就直接用背景颜色清屏,再用drawString方法画图就可以了。游戏暂停画面的绘制也相当容易,就是设立标志,让paint()执行的时候无需真正执行重绘动作。对于游戏处于运行状态的画面的绘制,则需要在下坠物的当前位置,绘制下坠物。在绘制下坠物之前,判断下坠物是否还能下坠,如果能下坠的话,就让它下落一格,再进行绘制,如果下坠物已无法下坠,则判断游戏是否处于Game Over状态,如果是处于Game Over状态的话,则设置游戏状态为Game over状态,这样画布在下一次重绘时就绘出Game Over的画面.如果游戏不是处于Game Over状态,则把下坠物固定下来,同时检查游戏画布上下坠物当前行下面的所有行,看是否需要进行行删除动作,如果需要行删除,则清除游戏地图上被删除行的数据,再把被删除行绘制成背景色。然后初始化一个新的下坠物,绘制这个新的下坠物。2.2概要设计根据初步的分析,项目分成四个部分:RussianBlock、RussianCanvas、RussianGame和RussianMap。RussianBlock负责画小砖块、画下移砖块、砖块下移、砖块左右移、砖块变形、根据随机数读取当前要下移的砖块以及下一个砖块。RussianCanvas接受用户的控制命令,调用RussianBlock里的方法。RussianGame是继承MIDlet的,有startApp()方法。RussianMap设置地图数据的,在特定的坐标取地图数据,在具体坐标下设置地图数据;以及画一些score,speed,control之类。RussianBlockRussianCanvasRussianGameRussianMap方块下坠、设置地图数据、读方块数据、画下坠物、画方块接受用户输入、重画线程、绘制帮助或者Game Over继承了MIDlet类,startApp(),pauseApp(),destoryApp()设置/读取指定地图的数据、消行等操作、绘制得分/速度如图所示:图 各模块的功能另外,游戏还分为5个状态:GAME_INIT,GAME_RUN,GAME_START_DEMO,GAME_SUPEND,GAME_OVER。游戏在GAME_INIT(游戏初始状态)状态下,系统会把游戏地图画出来;游戏在GAME_RUN(游戏正在运行状态)状态下,就是正常的游戏状态,接受用户输入、画方块等等;GAME_START_DEMO会打印欢迎画面;在GAME_SUPEND(游戏挂起状态)状态下,游戏就进入了挂起状态,不重画方块,一直等到进入GAME_RUN状态;GAME_OVER状态就是游戏的结束状态,这时会画出游戏结束画面。2.3界面设计图游戏的操作流程非常简单,用户启动MIDlet启动后,即进入游戏主画面,屏幕开始显示为欢迎画面。用户选择了【开始】按钮后,就可以开始玩游戏了,当用户想暂停时,再次按一下【开始】按钮,游戏就暂停了,在暂停的情况下再按【开始】按钮,游戏继续运行;当选择【帮助】时,屏幕会跳到帮助页面;任何时候按【退出】按钮,游戏MIDlet都会终止。游戏画面流程图如图所示:游戏运行画面MIDlet选择画面开始画面Game Over画面游戏暂停画面图 游戏画面流程图 开始欢迎界面 主场景界面游戏进入界面 菜单界面游戏暂停界面 游戏结束界面2.4代码实现2.RussianBlock 类是最主要的类,限于篇幅只给出RussianBlock类的代码:package bysj;import java.util.*;import javax.microedition.lcdui.*;public class RussianBlock /各种砖块,1-7为活动砖块颜色,8为墙砖颜色 public static final int BRICK_COLORS = 0x00FF0000, 0x0000FF00, 0x00FFFF00, 0x000000FF, 0x00FF00FF, 0x0000FFFF, 0x00C0DCC0, 0x00808080; /* * blockpattern的编码规则:blockpattern表示一个下坠物体的形状,一种下坠物的颜色是固定的。 * 对于一个下坠物,用一个三维数祖表示,第一维用rot表示(旋转值),第二维用x(也就是行),第三维用y表示(也就是列)。 * 所以 blockpattern1:田字及四种旋转形状 * blockpattern2:反L字及四种旋转形状 * blockpattern3:L字及四种旋转形状 * blockpattern4:1字及四种旋转形状 * . */3 设计总结通过此次两周的J2ME的课程设计,使我学到了很多,真正达到了学与用的结合,增强了对J2ME方面应用的理解,对自己今后参与开发手机游戏积累了不少经验,在实验过程中,对手机游戏设计理念及思想上有更高的认识,懂得了不少有关J2ME开发过程中的知识,在学习过程中,我也能过上网查了不少资料,也看了一些别人设计的俄罗斯方块的设计报告,学以致用,自我创新,完成了这份自己的报告,从中在学到用,从用又到学,不断修改,系统更新。虽然不能达到完善游戏,但也做到了尽善尽美,加强理论学习对完善系统会有很多帮助,不管怎么说,对这次做的课程设计自己觉得还算满意参考文献1 Timothy Budd. 三联四方工作室译,面向对象JAVA编程思想M. 清华大学出版社,2002.82 Mary Campione Kathy Walrath Alison Huml. 马朝晖 等译,Java语言导学M. 机械工业出版社,2002.13 王森. Java手机/PDA程序设计入门M. 电子工业出版社,2004.34 张小玮. J2ME无线平台应用开发M. 清华大学出版社, 20045 微型抓哇人. Java手机程序开发M. 中国铁道出版社, 2003.36 美Roger Riggs 芬 Jyri Huopaniemi Jim Van Peursem et al. 肖炜 郭晓刚 译,J2ME无线设备程序设计M. 电子工业出版社,2004.67 卢军. J2ME应用程序开发M. 中国铁道出版社,2002.98 飞思科技产品研发中心. 精通Jbuilder9M. 电子工业出版社,2003.89 闻怡洋. J2ME MIDP1.0/2.0无线设备编程指南M. 北京大学出版社,2004.710 John Wiley .Java 2 Micro Edition: Professional Developers GuideM. Sons,Inc附录:程序源代码package com.crackj2ee.j2me.game.russia;import javax.microedition.lcdui.*;import javax.microedition.midlet.MIDlet;/* * The app main midlet.*/public final class RussiaMIDlet extends MIDlet private static final String OPTIONS = NEW GAME, LOAD GAME, TOP 10, EXIT; private static RussiaMIDlet instance = null; private Display display = null; private List welcome = null; private MyCanvas canvas = null; public RussiaMIDlet() instance = this; display = Display.getDisplay(this); protected void startApp() if(welcome=null) welcome = new List(Welcome!, List.IMPLICIT, OPTIONS, null); welcome.setCommandListener(new WelcomeListener(welcome); display.setCurrent(welcome); protected void pauseApp() protected void destroyApp(boolean unconditional) public static void quitApp() if(instance!=null) instance.destroyApp(true); instance.notifyDestroyed(); public static void setDisplay(Displayable d) instance.dksplay.setCurrent(d); class WelcomeListener implements CommandLisener private List list; public WelcomeListener(List list) this.list = list; publicvoid commandAction(Command c, Displayable d) if(s=List.SELECT_COMMAND) switch(lit.getSelectedIndex() case 0: / new game RussiaMIDlet.setDisplay(new MyCanvas(false); break; case 1: / load game RussiaMIDlet.setDisplay(new MyCanvas(true); break; case 2: / top 10 break; case 3: / exit RussiaMIDlet.quitApp(); package com.crackj2ee.j2me.game.russia;import java.util.Random;import javax.microedition.lcdui.*;/* * ActiveShape represent the current falling shape. */public final class ActiveShape implements Storable private Shape currentShape; / current shape private int nextShapeIndex; / next shape private Shape previousShape; / previous shape private int colorIndex; / init location: private int init_left; / the location on background: private int left; private int top; / the last location: private int pre_left; private int pre_top; / random generator: private Random random = new Random(); public ActiveShape(int init_left) this.init_left = init_left; public void init() currentShape = Shape.SHAPES0; previousShape = currentShape; nextShapeIndex = 1; colorIndex = 0; public byte getRecordData() byte data = new byte3; / current shape index: data0 = (byte)Shape.indexOf(currentShape); / next shape index: data1 = (byte)nextShapeIndex; data2 = (byte)colorIndex; return data; public int setRecordData(byte data, int offset) if(data.length-offset3) return (-1); currentShape = Shape.SHAPESdataoffset; previousShape = currentShape; nextShapeIndex = dataoffset+1; colorIndex = dataoffset+2; this.left = init_left; this.top = Shape.getInitTop(Shape.indexOf(currentShape); return 3; /* * If false, that means GAME OVER! * * param shapeIndex The index of the shape. * param color The color of the shape. * return True if can reset to top. */ public boolean reset(Background bg) this.currentShape = Shape.SHAPESnextShapeIndex; this.previousShape = currentShape; this.left = init_left; this.top = Shape.getInitTop(nextShapeIndex); this.pre_left = left; this.pre_top = top; if(bg.collidesWith(this) return false; / set next shape: random.setSeed(System.currentTimeMillis(); int rnd = random.nextInt(); if(rnd0) rnd=0-rnd; colorIndex = rnd % Colors.ALL_COLORS.length; nextShapeIndex = rnd % Shape.SHAPES.length; return true; public Shape getCurrentShape() return this.currentShape; public int getColorIndex() return this.colorIndex; public int getLeft() return this.left; public int getTop() return this.top; private void lastLocationBeforeMove() pre_left = left; pre_top = top; public boolean moveLeft(Background bg) lastLocationBeforeMove(); / move left first: left-; / detect if overflow: int data = currentShape.getData(); for(int i=0; i0-left; i+) / col for(int j=0; j4; j+) / row if(datai+4*j=1) left+; return false; / detect if collides with boxes: if(bg.collidesWith(this) left+; return false; return true; public boolean moveRight(Background bg) lastLocationBeforeMove(); / move right first: left+; / detect if overflow: int width = bg.getWidth(); int data = currentShape.getData(); for(int i=width-left; i4; i+) / col for(int j=0; j4; j+) / row if(datai+4*j=1) left-; return false; / detect if collides with boxes: if(bg.collidesWith(this) left-; return false; return true; public boolean moveDown(Background bg) lastLocationBeforeMove(); / move down first: top+; / detect if fall on bottom: int height = bg.getHeight(); int data = currentShape.getData(); for(int i=height-top; i4; i+) / row for(int j=0; j4; j+) / col if(data4*i+j=1) top-; return false; / detect if collides with boxes: if(bg.collidesWith(this) top-; return false; return true; public void fallDown(Background bg) while(moveDown(bg); public boolean change(Background bg) Shape backup = currentShape; currentShape = currentShape.next(); / test if overflow: int width = bg.getWidth(); int data = currentShape.getData(); for(int i=width-left; i4; i+) / col for(int j=0; j4; j+) / row if(datai+4*j=1) this.currentShape = backup; return false; for(int i=0; i0-left; i+) / col for(int j=0; j4; j+) / row if(datai+4*j=1) this.currentShape = backup; return false; / test if collides with: if(bg.collidesWith(this) this.currentShape = backup; return false; previousShape = backup; return true; public void paint(Graphics g, int box_size) if(previousShape=currentShape) / just move, not change: g.translate(pre_left*box_size, pre_top*box_size); currentShape.erase(g, box_size); g.translate(left-pre_left)*box_size, (top-pre_top)*box_size); currentShape.paint(g, box_size, Colors.ALL_COLORScolorIndex); else / just changed: g.translate(left*box_size, top*box_size); previousShape.erase(g, box_size); / draw new position: currentShape.paint(g, box_size, Colors.ALL_COLORScolorIndex); / make prev=current until next change: previousShape=currentShape; public Shape getNextShape() return Shape.SHAPESnextShapeIndex; /*package com.crackj2ee.j2me.game.russia;import javax.microedition.lcdui.*;/* * To represent the container of all boxes.*/public final class Background implements Storable public static final int EMPTY = 99; / holds width & height: private int width; private int height; / holds boxes, EMPTY or color_index: private int boxes; / holds the rows that can be removed. private boolean removingRows; / make sure cannot instanciate from outside: public Background(int width, int height) this.width = width; this.height = height; this.removingRows = new booleanheight; this.boxes = new intwidthheight; public int getWidth() return this.width; public int getHeight() return this.height; /* * Clean all boxes and can start a new game. */ public void init() for(int i=0; iwidth; i+) for(int j=0; jheight; j+) boxesij = EMPTY; for(int i=0; iheight; i+) removingRowsi = false; public byte getRecordData() byte data = new bytewidth*height; int offset = 0; for(int r=0; rheight; r+) for(int c=0; cwidth; c+) dataoffset = (byte)boxescr; offset+; return data; public int setRecordData(byte data, int offset) if(data.length-offset)width*height) return (-1); for(int r=0; rheight; r+) for(int c=0; cwidth; c+) boxescr = dataoffset; offset+; return width*height; /* * Detect if there is a collition between two 4x4 area. * param active The ActiveShape object. * return True if there is a collition. */ public boolean collidesWith(ActiveShape active) int data = active.getCurrentShape().getData(); int left = active.getLeft(); int top = active.getTop(); for(int i1=top, i2=0; i1top+4; i1+, i2+) for(int j1=left, j2=0; j1=0 & i1=0 & j1width) if(data4*i2+j2=1 & boxesj1i1!=EMPTY) return true; return false; public int getBoxes() return boxes; /* * Merge the ActiveShape to the Background. * param active The ActiveShape object. */ public void merge(ActiveShape active) int left = active.getLeft(); int top = active.getTop(); int box; for(int i=0; i4; i+) for(int j=0; j4; j+) box = active.getCurrentShape().getData()i*4+j; if(box=1) this.boxesleft+jtop+i = active.getColorIndex(); /* * Mark all rows that can be removed. */ public boolean markRemovingRows() / mark all rows if it can be removed: for(int i=0; iheight; i+) removingRowsi = true; for(int j=0; j=0; i-) while(r=0 & removingRowsr) r-; if(r=(-1) b

温馨提示

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

评论

0/150

提交评论