java实现俄罗斯方块小程序
这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。
发在这里跟大家交流学习一下。
如需要完整工程文件、说明文档以及可运行jar文件,下载地址:点击打开链接
RussianBlocksGame.java
packageRussiaBlocksGame; importjava.awt.*; importjava.awt.event.*; importjavax.swing.*; importjavax.swing.border.Border; importjavax.swing.border.EtchedBorder; /** *游戏主类,继承自JFrame类,负责游戏的全局控制。内含:1.一个GameCanvas画布类的实例对象, *2.一个保存当前活动块(RussiaBlock)实例的对象;3.一个保存当前控制面板(ControlPanel)实例的对象; */ publicclassRussiaBlocksGameextendsJFrame{ privatestaticfinallongserialVersionUID=-7332245439279674749L; /** *每填满一行计多少分 */ publicfinalstaticintPER_LINE_SCORE=100; /** *积多少分以后能升级 */ publicfinalstaticintPER_LEVEL_SCORE=PER_LINE_SCORE*20; /** *最大级数是10级 */ publicfinalstaticintMAX_LEVEL=10; /** *默认级数是2 */ publicfinalstaticintDEFAULT_LEVEL=2; privateGameCanvascanvas; privateErsBlockblock; privatebooleanplaying=false; privateControlPanelctrlPanel; //初始化菜单栏 privateJMenuBarbar=newJMenuBar(); privateJMenumGame=newJMenu("游戏"), mControl=newJMenu("控制"), mInfo=newJMenu("帮助"); privateJMenuItemmiNewGame=newJMenuItem("新游戏"), miSetBlockColor=newJMenuItem("设置方块颜色..."), miSetBackColor=newJMenuItem("设置背景颜色..."), miTurnHarder=newJMenuItem("升高游戏难度"), miTurnEasier=newJMenuItem("降低游戏难度"), miExit=newJMenuItem("退出"), miPlay=newJMenuItem("开始"), miPause=newJMenuItem("暂停"), miResume=newJMenuItem("恢复"), miStop=newJMenuItem("终止游戏"), miRule=newJMenuItem("游戏规则"), miAuthor=newJMenuItem("关于本游戏"); /** *建立并设置窗口菜单 */ privatevoidcreatMenu(){ bar.add(mGame); bar.add(mControl); bar.add(mInfo); mGame.add(miNewGame); mGame.addSeparator();//在菜单中加水平分割线 mGame.add(miSetBlockColor); mGame.add(miSetBackColor); mGame.addSeparator();//在菜单中加水平分割线 mGame.add(miTurnHarder); mGame.add(miTurnEasier); mGame.addSeparator();//在菜单中加水平分割线 mGame.add(miExit); mControl.add(miPlay); miPlay.setEnabled(true); mControl.add(miPause); miPause.setEnabled(false); mControl.add(miResume); miResume.setEnabled(false); mControl.add(miStop); miStop.setEnabled(false); mInfo.add(miRule); mInfo.add(miAuthor); setJMenuBar(bar); miNewGame.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ stopGame(); reset(); setLevel(DEFAULT_LEVEL); } }); //设置方块颜色 miSetBlockColor.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ ColornewFrontColor= JColorChooser.showDialog(RussiaBlocksGame.this,"设置方块颜色",canvas.getBlockColor()); if(newFrontColor!=null){ canvas.setBlockColor(newFrontColor); } } }); //设置背景颜色 miSetBackColor.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ ColornewBackColor= JColorChooser.showDialog(RussiaBlocksGame.this,"设置背景颜色",canvas.getBackgroundColor()); if(newBackColor!=null){ canvas.setBackgroundColor(newBackColor); } } }); //定义菜单栏"关于"的功能,弹出确认框。 miAuthor.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ JOptionPane.showMessageDialog(null,"软件工程(4)班\n3115005372\n杨宇杰\n©一切解释权归杨宇杰所有","关于俄罗斯方块-2016",1); } }); //游戏规则说明 miRule.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ JOptionPane.showMessageDialog(null,"由小方块组成的不同形状的板块陆续从屏幕上方落下来,\n玩家通过调整板块的位置和方向,使它们在屏幕底部拼\n出完整的一条或几条。这些完整的横条会随即消失,给新\n落下来的板块腾出空间,与此同时,玩家得到分数奖励。\n没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,\n玩家便告输,游戏结束。","游戏规则",1); } }); //增加难度 miTurnHarder.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ intcurLevel=getLevel(); if(!playing&&curLevel1){ setLevel(curLevel-1); } } }); //退出按钮动作响应 miExit.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){ System.exit(0); } }); } /** *主游戏类的构造方法 * *@paramtitleString,窗口标题 */ publicRussiaBlocksGame(Stringtitle){ super(title);//设置标题 setSize(500,600);//设置窗口大小 setLocationRelativeTo(null);//设置窗口居中 creatMenu(); Containercontainer=getContentPane();//创建菜单栏 container.setLayout(newBorderLayout(6,0));//设置窗口的布局管理器 canvas=newGameCanvas(20,15);//新建游戏画布 ctrlPanel=newControlPanel(this);//新建控制面板 container.add(canvas,BorderLayout.CENTER);//左边加上画布 container.add(ctrlPanel,BorderLayout.EAST);//右边加上控制面板 //注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。 addWindowListener(newWindowAdapter(){ @Override publicvoidwindowClosing(WindowEventwe){ stopGame(); System.exit(0); } }); //根据窗口大小,自动调节方格的尺寸 addComponentListener(newComponentAdapter(){ @Override publicvoidcomponentResized(ComponentEventce){ canvas.adjust(); } }); setVisible(true); canvas.adjust(); } /** *让游戏复位 */ publicvoidreset(){//画布复位,控制面板复位 ctrlPanel.setPlayButtonEnable(true); ctrlPanel.setPauseButtonEnable(false); ctrlPanel.setPauseButtonLabel(true); ctrlPanel.setStopButtonEnable(false); ctrlPanel.setTurnLevelDownButtonEnable(true); ctrlPanel.setTurnLevelUpButtonEnable(true); miPlay.setEnabled(true); miPause.setEnabled(false); miResume.setEnabled(false); miStop.setEnabled(false); ctrlPanel.reset(); canvas.reset(); } /** *判断游戏是否还在进行 * *@returnboolean,true-还在运行,false-已经停止 */ publicbooleanisPlaying(){ returnplaying; } /** *得到当前活动的块 * *@returnErsBlock,当前活动块的引用 */ publicErsBlockgetCurBlock(){ returnblock; } /** *得到当前画布 * *@returnGameCanvas,当前画布的引用 */ publicGameCanvasgetCanvas(){ returncanvas; } /** *开始游戏 */ publicvoidplayGame(){ play(); ctrlPanel.setPlayButtonEnable(false); ctrlPanel.setPauseButtonEnable(true); ctrlPanel.setPauseButtonLabel(true); ctrlPanel.setStopButtonEnable(true); ctrlPanel.setTurnLevelDownButtonEnable(false); ctrlPanel.setTurnLevelUpButtonEnable(false); miStop.setEnabled(true); miTurnHarder.setEnabled(false); miTurnEasier.setEnabled(false); ctrlPanel.requestFocus();//设置焦点在控制面板上 } /** *游戏暂停 */ publicvoidpauseGame(){ if(block!=null){ block.pauseMove(); } ctrlPanel.setPlayButtonEnable(false); ctrlPanel.setPauseButtonLabel(false); ctrlPanel.setStopButtonEnable(true); miPlay.setEnabled(false); miPause.setEnabled(false); miResume.setEnabled(true); miStop.setEnabled(true); } /** *让暂停中的游戏继续 */ publicvoidresumeGame(){ if(block!=null){ block.resumeMove(); } ctrlPanel.setPlayButtonEnable(false); ctrlPanel.setPauseButtonEnable(true); ctrlPanel.setPauseButtonLabel(true); miPause.setEnabled(true); miResume.setEnabled(false); ctrlPanel.requestFocus(); } /** *用户停止游戏 */ publicvoidstopGame(){ playing=false; if(block!=null){ block.stopMove(); } ctrlPanel.setPlayButtonEnable(true); ctrlPanel.setPauseButtonEnable(false); ctrlPanel.setPauseButtonLabel(true); ctrlPanel.setStopButtonEnable(false); ctrlPanel.setTurnLevelDownButtonEnable(true); ctrlPanel.setTurnLevelUpButtonEnable(true); miPlay.setEnabled(true); miPause.setEnabled(false); miResume.setEnabled(false); miStop.setEnabled(false); miTurnHarder.setEnabled(true); miTurnEasier.setEnabled(true); reset();//重置画布和控制面板 } /** *得到游戏者设置的难度 * *@returnint,游戏难度1-MAX_LEVEL */ publicintgetLevel(){ returnctrlPanel.getLevel(); } /** *用户设置游戏难度 * *@paramlevelint,游戏难度1-MAX_LEVEL */ publicvoidsetLevel(intlevel){ if(level<11&&level>0){ ctrlPanel.setLevel(level); } } /** *得到游戏积分 * *@returnint,积分 */ publicintgetScore(){ if(canvas!=null){ returncanvas.getScore(); } return0; } /** *得到自上次升级以来的游戏积分,升级以后,此积分清零 * *@returnint,积分 */ publicintgetScoreForLevelUpdate(){ if(canvas!=null){ returncanvas.getScoreForLevelUpdate(); } return0; } /** *当积分累积到一定数值时,升一次级 * *@returnBoolean,true-updatesucceed,false-updatefail */ publicbooleanlevelUpdate(){ intcurLevel=getLevel(); if(curLevel GameCanvas.java
packageRussiaBlocksGame; importjava.awt.Color; importjava.awt.Graphics; importjavax.swing.JPanel; importjavax.swing.border.EtchedBorder; /** *画布类,内有<行数>*<列数>个方格类实例。继承自JPanel类。ErsBlock线程类动态改变画布类的方格颜色,画布类通过 *检查方格颜色来体现ErsBlock块的移动情况。 */ publicclassGameCanvasextendsJPanel{ privatestaticfinallongserialVersionUID=6732901391026089276L; privateColorbackColor=Color.darkGray,frontColor=Color.WHITE; privateintrows,cols,score=0,scoreForLevelUpdate=0; privateErsBox[][]boxes; privateintboxWidth,boxHeight; /** *画布类的构造函数 * *@paramrowsint,画布的行数 *@paramcolsint,画布的列数行数和列数决定着画布拥有方格的数目 */ publicGameCanvas(introws,intcols){ this.rows=rows; this.cols=cols; boxes=newErsBox[rows][cols]; for(inti=0;iboxes.length-1||col<0||col>boxes[0].length-1){ returnnull; } return(boxes[row][col]); } /** *覆盖JComponent类的函数,画组件。 * *@paramg图形设备环境 */ @Override publicvoidpaintComponent(Graphicsg){ super.paintComponent(g); g.setColor(frontColor); for(inti=0;i 0;i--){ for(intj=0;j ControlPanel.java
packageRussiaBlocksGame; importjava.awt.BorderLayout; importjava.awt.Color; importjava.awt.Graphics; importjava.awt.GridLayout; importjava.awt.event.ActionEvent; importjava.awt.event.ActionListener; importjava.awt.event.ComponentAdapter; importjava.awt.event.ComponentEvent; importjava.awt.event.KeyAdapter; importjava.awt.event.KeyEvent; importjava.text.DateFormat; importjava.text.SimpleDateFormat; importjava.util.Date; importjavax.swing.JButton; importjavax.swing.JLabel; importjavax.swing.JPanel; importjavax.swing.JTextField; importjavax.swing.Timer; importjavax.swing.border.Border; importjavax.swing.border.EtchedBorder; /** *控制面板类,继承自JPanel。上边安放预显窗口,等级,得分,控制按钮主要用来控制游戏进程。 */ classControlPanelextendsJPanel{ privatestaticfinallongserialVersionUID=3900659640646175724L; privateJTextFieldtfLevel=newJTextField(""+RussiaBlocksGame.DEFAULT_LEVEL), tfScore=newJTextField("0"), tfTime=newJTextField(""); privateJButtonbtPlay=newJButton("开始"), btPause=newJButton("暂停"), btStop=newJButton("终止游戏"), btTurnLevelUp=newJButton("增加难度"), btTurnLevelDown=newJButton("降低难度"); privateJPanelplTip=newJPanel(newBorderLayout()); privateTipPanelplTipBlock=newTipPanel(); privateJPanelplInfo=newJPanel(newGridLayout(4,1)); privateJPanelplButton=newJPanel(newGridLayout(6,1)); privateTimertimer; privateBorderborder=newEtchedBorder(EtchedBorder.RAISED,Color.white,newColor(148,145,140)); /** *控制面板类的构造函数 * *@paramgameErsBlocksGame,ErsBlocksGame类的一个实例引用方便直接控制ErsBlocksGame类的行为。 */ publicControlPanel(finalRussiaBlocksGamegame){ setLayout(newGridLayout(3,1,0,2)); plTip.add(newJLabel("下一个方块"),BorderLayout.NORTH);//添加组件 plTip.add(plTipBlock); plTip.setBorder(border); plInfo.add(newJLabel("难度系数")); plInfo.add(tfLevel); plInfo.add(newJLabel("得分")); plInfo.add(tfScore); plInfo.setBorder(border); plButton.add(btPlay); btPlay.setEnabled(true); plButton.add(btPause); btPause.setEnabled(false); plButton.add(btStop); btStop.setEnabled(false); plButton.add(btTurnLevelUp); plButton.add(btTurnLevelDown); plButton.add(tfTime); plButton.setBorder(border); tfLevel.setEditable(false); tfScore.setEditable(false); tfTime.setEditable(false); add(plTip); add(plInfo); add(plButton); addKeyListener(newKeyAdapter(){ @Override publicvoidkeyPressed(KeyEventke){ if(!game.isPlaying()){ return; } ErsBlockblock=game.getCurBlock(); switch(ke.getKeyCode()){ caseKeyEvent.VK_DOWN: block.moveDown(); break; caseKeyEvent.VK_LEFT: block.moveLeft(); break; caseKeyEvent.VK_RIGHT: block.moveRight(); break; caseKeyEvent.VK_UP: block.turnNext(); break; default: break; } } }); btPlay.addActionListener(newActionListener(){//开始游戏 @Override publicvoidactionPerformed(ActionEventae){ game.playGame(); } }); btPause.addActionListener(newActionListener(){//暂停游戏 @Override publicvoidactionPerformed(ActionEventae){ if(btPause.getText().equals("暂停")){ game.pauseGame(); }else{ game.resumeGame(); } } }); btStop.addActionListener(newActionListener(){//停止游戏 @Override publicvoidactionPerformed(ActionEventae){ game.stopGame(); } }); btTurnLevelUp.addActionListener(newActionListener(){//升高难度 @Override publicvoidactionPerformed(ActionEventae){ try{ intlevel=Integer.parseInt(tfLevel.getText()); if(level1){ tfLevel.setText(""+(level-1)); } }catch(NumberFormatExceptione){ } requestFocus(); } }); addComponentListener(newComponentAdapter(){ @Override publicvoidcomponentResized(ComponentEventce){ plTipBlock.adjust(); } }); timer=newTimer(1000,newActionListener(){ @Override publicvoidactionPerformed(ActionEventae){ DateFormatformat=newSimpleDateFormat("时间:HH:mm:ss");//系统获得时间 Datedate=newDate(); tfTime.setText(format.format(date)); tfScore.setText(""+game.getScore()); intScoreForLevelUpdate=//判断当前分数是否能升级 game.getScoreForLevelUpdate(); if(ScoreForLevelUpdate>=RussiaBlocksGame.PER_LEVEL_SCORE &&ScoreForLevelUpdate>0){ game.levelUpdate(); } } }); timer.start(); } /** *设置预显窗口的样式 * *@paramstyleint,对应ErsBlock类的STYLES中的28个值 */ publicvoidsetTipStyle(intstyle){ plTipBlock.setStyle(style); } /** *取得用户设置的游戏等级。 * *@returnint,难度等级,1-ErsBlocksGame.MAX_LEVEL */ publicintgetLevel(){ intlevel=0; try{ level=Integer.parseInt(tfLevel.getText()); }catch(NumberFormatExceptione){ } returnlevel; } /** *让用户修改游戏难度等级。 * *@paramlevel修改后的游戏难度等级 */ publicvoidsetLevel(intlevel){ if(level>0&&level<11){ tfLevel.setText(""+level); } } /** *设置“开始”按钮的状态。 */ publicvoidsetPlayButtonEnable(booleanenable){ btPlay.setEnabled(enable); } publicvoidsetPauseButtonEnable(booleanenable){ btPause.setEnabled(enable); } publicvoidsetPauseButtonLabel(booleanpause){ btPause.setText(pause?"暂停":"继续"); } publicvoidsetStopButtonEnable(booleanenable){ btStop.setEnabled(enable); } publicvoidsetTurnLevelUpButtonEnable(booleanenable){ btTurnLevelUp.setEnabled(enable); } publicvoidsetTurnLevelDownButtonEnable(booleanenable){ btTurnLevelDown.setEnabled(enable); } /** *重置控制面板 */ publicvoidreset(){ tfScore.setText("0"); plTipBlock.setStyle(0); } /** *重新计算TipPanel里的boxes[][]里的小框的大小 */ publicvoidadjust(){ plTipBlock.adjust(); } /** *预显窗口的实现细节类 */ publicclassTipPanelextendsJPanel{//TipPanel用来显示下一个将要出现方块的形状 privatestaticfinallongserialVersionUID=5160553671436997616L; privateColorbackColor=Color.darkGray,frontColor=Color.WHITE; privateErsBox[][]boxes=newErsBox[ErsBlock.BOXES_ROWS][ErsBlock.BOXES_COLS]; privateintstyle,boxWidth,boxHeight; privatebooleanisTiled=false; /** *预显示窗口类构造函数 */ publicTipPanel(){ for(inti=0;i >=1; } } } /** *g根据窗口的大小,自动调整方格的尺寸 */ publicvoidadjust(){ boxWidth=getSize().width/ErsBlock.BOXES_COLS; boxHeight=getSize().height/ErsBlock.BOXES_ROWS; isTiled=true; } } } ErsBox.java
packageRussiaBlocksGame; importjava.awt.Dimension; /** *方格类,是组成块的基本元素,用自己的颜色来表示块的外观 */ publicclassErsBoximplementsCloneable{ privatebooleanisColor; privateDimensionsize=newDimension(); /** *方格类的构造函数, * *@paramisColor是不是用前景色来为此方格着色true前景色,false用背景色 */ publicErsBox(booleanisColor){ this.isColor=isColor; } /** *此方格是不是用前景色表现 * *@returnboolean,true用前景色表现,false用背景色表现 */ publicbooleanisColorBox(){ returnisColor; } /** *设置方格的颜色, * *@paramisColorboolean,true用前景色表现,false用背景色表现 */ publicvoidsetColor(booleanisColor){ this.isColor=isColor; } /** *得到此方格的尺寸 * *@returnDimension,方格的尺寸 */ publicDimensiongetSize(){ returnsize; } /** *设置方格的尺寸, * *@paramsizeDimension,方格的尺寸 */ publicvoidsetSize(Dimensionsize){ this.size=size; } /** *覆盖Object的Objectclone(),实现克隆 * *@returnObject,克隆的结果 */ @Override publicObjectclone(){ Objectcloned=null; try{ cloned=super.clone(); }catch(Exceptionex){ ex.printStackTrace(); } returncloned; } }ErsBlock.java
packageRussiaBlocksGame; /** *块类,继承自线程类(Thread)由4×4个方块(ErsBox)构成一个方块,控制块的移动·下落·变形等 */ classErsBlockextendsThread{ /** *一个块占的行数是4行 */ publicfinalstaticintBOXES_ROWS=4; /** *一个块占的列数是4列 */ publicfinalstaticintBOXES_COLS=4; /** *让升级变化平滑的因子,避免最后几级之间的速度相差近一倍 */ publicfinalstaticintLEVEL_FLATNESS_GENE=3; /** *相近的两级之间,块每下落一行的时间差别为多少(毫秒) */ publicfinalstaticintBETWEEN_LEVELS_DEGRESS_TIME=50; /** *方块的样式数目为7 */ publicfinalstaticintBLOCK_KIND_NUMBER=7; /** *每一个样式的方块的反转状态种类为4 */ publicfinalstaticintBLOCK_STATUS_NUMBER=4; /** *分别对应7种模型的28种状态 */ publicfinalstaticint[][]STYLES={//共28种状态 {0x0f00,0x4444,0x0f00,0x4444},//长条型的四种状态 {0x04e0,0x0464,0x00e4,0x04c4},//T型的四种状态 {0x4620,0x6c00,0x4620,0x6c00},//反Z型的四种状态 {0x2640,0xc600,0x2640,0xc600},//Z型的四种状态 {0x6220,0x1700,0x2230,0x0740},//7型的四种状态 {0x6440,0x0e20,0x44c0,0x8e00},//反7型的四种状态 {0x0660,0x0660,0x0660,0x0660},//方块的四种状态 }; privateGameCanvascanvas; privateErsBox[][]boxes=newErsBox[BOXES_ROWS][BOXES_COLS]; privateintstyle,y,x,level; privatebooleanpausing=false,moving=true; /** *构造函数,产生一个特定的块 * *@paramstyle块的样式,对应STYLES的28个值中的一个 *@paramy起始位置,左上角在canvas中的坐标行 *@paramx起始位置,左上角在canvas中的坐标列 *@paramlevel游戏等级,控制块的下落速度 *@paramcanvas画板 */ publicErsBlock(intstyle,inty,intx,intlevel,GameCanvascanvas){ this.style=style; this.y=y; this.x=x; this.level=level; this.canvas=canvas; intkey=0x8000; for(inti=0;i>=1; } } display(); } /** *线程类的run()函数覆盖,下落块,直到块不能再下落 */ @Override publicvoidrun(){ while(moving){ try{ sleep(BETWEEN_LEVELS_DEGRESS_TIME *(RussiaBlocksGame.MAX_LEVEL-level+LEVEL_FLATNESS_GENE)); }catch(InterruptedExceptionie){ ie.printStackTrace(); } //后边的moving是表示在等待的100毫秒间,moving没有被改变 if(!pausing){ moving=(moveTo(y+1,x)&&moving); } } } /** *块向左移动一格 */ publicvoidmoveLeft(){ moveTo(y,x-1); } /** *块向右移动一格 */ publicvoidmoveRight(){ moveTo(y,x+1); } /** *块向下移动一格 */ publicvoidmoveDown(){ moveTo(y+1,x); } /** *块变型 */ publicvoidturnNext(){ for(inti=0;i >=1; } } display(); returntrue; } /** *将当前块变成newStyle所指定的块样式 * *@paramnewStyleint,希望改变的块样式,对应STYLES的28个值中的一个 *@returntrue-改变成功,false-改变失败 */ privatebooleanturnTo(intnewStyle){ if(!isTurnAble(newStyle)||!moving){ returnfalse; } erase(); intkey=0x8000; for(inti=0;i >=1; } } style=newStyle; display(); canvas.repaint(); returntrue; } } Main.java
packageRussiaBlocksGame; /** *程序入口函数 * *@paramargsString[],附带的命令行参数 */ publicclassMain{ publicstaticvoidmain(String[]args){ newRussiaBlocksGame("俄罗斯方块:杨宇杰"); } }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。