java实现俄罗斯方块小程序
程序员文章站
2024-02-13 23:26:22
这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。
发在这里跟大家交流学习一下。
如需要完整工程文件、说明文档以...
这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。
发在这里跟大家交流学习一下。
如需要完整工程文件、说明文档以及可运行jar文件,下载地址:点击打开链接
russianblocksgame.java
package russiablocksgame; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.border; import javax.swing.border.etchedborder; /** * 游戏主类,继承自jframe类,负责游戏的全局控制。 内含: 1.一个gamecanvas画布类的实例对象, * 2.一个保存当前活动块(russiablock)实例的对象; 3.一个保存当前控制面板(controlpanel)实例的对象; */ public class russiablocksgame extends jframe { private static final long serialversionuid = -7332245439279674749l; /** * 每填满一行计多少分 */ public final static int per_line_score = 100; /** * 积多少分以后能升级 */ public final static int per_level_score = per_line_score * 20; /** * 最大级数是10级 */ public final static int max_level = 10; /** * 默认级数是2 */ public final static int default_level = 2; private gamecanvas canvas; private ersblock block; private boolean playing = false; private controlpanel ctrlpanel; //初始化菜单栏 private jmenubar bar = new jmenubar(); private jmenu mgame = new jmenu(" 游戏"), mcontrol = new jmenu(" 控制"), minfo = new jmenu("帮助"); private jmenuitem minewgame = new jmenuitem("新游戏"), misetblockcolor = new jmenuitem("设置方块颜色..."), misetbackcolor = new jmenuitem("设置背景颜色..."), miturnharder = new jmenuitem("升高游戏难度"), miturneasier = new jmenuitem("降低游戏难度"), miexit = new jmenuitem("退出"), miplay = new jmenuitem("开始"), mipause = new jmenuitem("暂停"), miresume = new jmenuitem("恢复"), mistop = new jmenuitem("终止游戏"), mirule = new jmenuitem("游戏规则"), miauthor = new jmenuitem("关于本游戏"); /** * 建立并设置窗口菜单 */ private void creatmenu() { 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(new actionlistener() { @override public void actionperformed(actionevent e) { stopgame(); reset(); setlevel(default_level); } }); //设置方块颜色 misetblockcolor.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { color newfrontcolor = jcolorchooser.showdialog(russiablocksgame.this, "设置方块颜色", canvas.getblockcolor()); if (newfrontcolor != null) { canvas.setblockcolor(newfrontcolor); } } }); //设置背景颜色 misetbackcolor.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { color newbackcolor = jcolorchooser.showdialog(russiablocksgame.this, "设置背景颜色", canvas.getbackgroundcolor()); if (newbackcolor != null) { canvas.setbackgroundcolor(newbackcolor); } } }); //定义菜单栏"关于"的功能,弹出确认框。 miauthor.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { joptionpane.showmessagedialog(null, "软件工程(4)班\n3115005372\n杨宇杰\n©一切解释权归杨宇杰所有", "关于俄罗斯方块 - 2016", 1); } }); //游戏规则说明 mirule.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { joptionpane.showmessagedialog(null, "由小方块组成的不同形状的板块陆续从屏幕上方落下来,\n玩家通过调整板块的位置和方向,使它们在屏幕底部拼\n出完整的一条或几条。这些完整的横条会随即消失,给新\n落下来的板块腾出空间,与此同时,玩家得到分数奖励。\n没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,\n玩家便告输,游戏结束。", "游戏规则", 1); } }); //增加难度 miturnharder.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { int curlevel = getlevel(); if (!playing && curlevel < max_level) { setlevel(curlevel + 1); } } }); //减少难度 miturneasier.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { int curlevel = getlevel(); if (!playing && curlevel > 1) { setlevel(curlevel - 1); } } }); //退出按钮动作响应 miexit.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { system.exit(0); } }); } /** * 主游戏类的构造方法 * * @param title string ,窗口标题 */ public russiablocksgame(string title) { super(title); //设置标题 setsize(500, 600); //设置窗口大小 setlocationrelativeto(null); //设置窗口居中 creatmenu(); container container = getcontentpane(); //创建菜单栏 container.setlayout(new borderlayout(6, 0)); //设置窗口的布局管理器 canvas = new gamecanvas(20, 15); //新建游戏画布 ctrlpanel = new controlpanel(this); //新建控制面板 container.add(canvas, borderlayout.center); //左边加上画布 container.add(ctrlpanel, borderlayout.east); //右边加上控制面板 //注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。 addwindowlistener(new windowadapter() { @override public void windowclosing(windowevent we) { stopgame(); system.exit(0); } }); //根据窗口大小,自动调节方格的尺寸 addcomponentlistener(new componentadapter() { @override public void componentresized(componentevent ce) { canvas.adjust(); } }); setvisible(true); canvas.adjust(); } /** * 让游戏复位 */ public void reset() { //画布复位,控制面板复位 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(); } /** * 判断游戏是否还在进行 * * @return boolean,true -还在运行,false-已经停止 */ public boolean isplaying() { return playing; } /** * 得到当前活动的块 * * @return ersblock,当前活动块的引用 */ public ersblock getcurblock() { return block; } /** * 得到当前画布 * * @return gamecanvas,当前画布的引用 */ public gamecanvas getcanvas() { return canvas; } /** * 开始游戏 */ public void playgame() { 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(); //设置焦点在控制面板上 } /** * 游戏暂停 */ public void pausegame() { 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); } /** * 让暂停中的游戏继续 */ public void resumegame() { if (block != null) { block.resumemove(); } ctrlpanel.setplaybuttonenable(false); ctrlpanel.setpausebuttonenable(true); ctrlpanel.setpausebuttonlabel(true); mipause.setenabled(true); miresume.setenabled(false); ctrlpanel.requestfocus(); } /** * 用户停止游戏 */ public void stopgame() { 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();//重置画布和控制面板 } /** * 得到游戏者设置的难度 * * @return int ,游戏难度1-max_level */ public int getlevel() { return ctrlpanel.getlevel(); } /** * 用户设置游戏难度 * * @param level int ,游戏难度1-max_level */ public void setlevel(int level) { if (level < 11 && level > 0) { ctrlpanel.setlevel(level); } } /** * 得到游戏积分 * * @return int,积分 */ public int getscore() { if (canvas != null) { return canvas.getscore(); } return 0; } /** * 得到自上次升级以来的游戏积分,升级以后,此积分清零 * * @return int,积分 */ public int getscoreforlevelupdate() { if (canvas != null) { return canvas.getscoreforlevelupdate(); } return 0; } /** * 当积分累积到一定数值时,升一次级 * * @return boolean,true-update succeed,false-update fail */ public boolean levelupdate() { int curlevel = getlevel(); if (curlevel < max_level) { setlevel(curlevel + 1); canvas.resetscoreforlevelupdate(); return true; } return false; } /** * 游戏开始 */ private void play() { reset(); playing = true; thread thread = new thread(new game());//启动游戏线程 thread.start(); } /** * 报告游戏结束了 */ private void reportgameover() { new gameoverdialog(this, "俄罗斯方块", "游戏结束,您的得分为" + canvas.getscore()); } /** * 一轮游戏过程,实现了runnable接口 一轮游戏是一个大循环,在这个循环中,每隔100毫秒, 检查游戏中的当前块是否已经到底了,如果没有, * 就继续等待。如果到底了,就看有没有全填满的行, 如果有就删除它,并为游戏者加分,同时随机产生一个新的当前块并让它自动落下。 * 当新产生一个块时,先检查画布最顶上的一行是否已经被占了,如果是,可以判断game over 了。 */ private class game implements runnable { @override public void run() { int col = (int) (math.random() * (canvas.getcols() - 3));//随机生成方块出现的位置 int style = ersblock.styles[ (int) (math.random() * 7)][(int) (math.random() * 4)];//随机生成一种形状的方块 while (playing) { if (block != null) { //第一次循环时,block为空 if (block.isalive()) { try { thread.currentthread(); thread.sleep(500); } catch (interruptedexception ie) { ie.printstacktrace(); } continue; } } checkfullline(); //检查是否有全填满的行 if (isgameover()) { reportgameover(); miplay.setenabled(true); mipause.setenabled(false); miresume.setenabled(false); mistop.setenabled(false); ctrlpanel.setplaybuttonenable(true); ctrlpanel.setpausebuttonlabel(false); ctrlpanel.setstopbuttonenable(false); return; } block = new ersblock(style, -1, col, getlevel(), canvas); block.start(); col = (int) (math.random() * (canvas.getcols() - 3)); style = ersblock.styles[ (int) (math.random() * 7)][(int) (math.random() * 4)]; ctrlpanel.settipstyle(style); } } //检查画布中是否有全填满的行,如果有就删之 public void checkfullline() { for (int i = 0; i < canvas.getrows(); i++) { int row = -1; boolean fulllinecolorbox = true; for (int j = 0; j < canvas.getcols(); j++) { if (!canvas.getbox(i, j).iscolorbox()) { fulllinecolorbox = false; break; } } if (fulllinecolorbox) { row = i--; canvas.removeline(row); } } } //根据最顶行是否被占,判断游戏是否已经结束了 //@return boolean ,true-游戏结束了,false-游戏未结束 private boolean isgameover() { for (int i = 0; i < canvas.getcols(); i++) { ersbox box = canvas.getbox(0, i); if (box.iscolorbox()) { return true; } } return false; } } /** * 定义gameover对话框。 */ @suppresswarnings("serial") private class gameoverdialog extends jdialog implements actionlistener { private jbutton againbutton, exitbutton; private border border = new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140)); public gameoverdialog(jframe parent, string title, string message) { super(parent, title, true); if (parent != null) { setsize(240, 120); this.setlocationrelativeto(parent); jpanel messagepanel = new jpanel(); messagepanel.add(new jlabel(message)); messagepanel.setborder(border); container container = this.getcontentpane(); container.setlayout(new gridlayout(2, 0, 0, 10)); container.add(messagepanel); jpanel choosepanel = new jpanel(); choosepanel.setlayout(new gridlayout(0, 2, 4, 0)); container.add(choosepanel); againbutton = new jbutton("再玩一局"); exitbutton = new jbutton("退出游戏"); choosepanel.add(new jpanel().add(againbutton)); choosepanel.add(new jpanel().add(exitbutton)); choosepanel.setborder(border); } againbutton.addactionlistener(this); exitbutton.addactionlistener(this); this.setvisible(true); } @override public void actionperformed(actionevent e) { if (e.getsource() == againbutton) { this.setvisible(false); reset(); } else if (e.getsource() == exitbutton) { stopgame(); system.exit(0); } } } }
gamecanvas.java
package russiablocksgame; import java.awt.color; import java.awt.graphics; import javax.swing.jpanel; import javax.swing.border.etchedborder; /** * 画布类,内有<行数>*<列数> 个方格类实例。 继承自jpanel类。 ersblock线程类动态改变画布类的方格颜色,画布类通过 * 检查方格颜色来体现ersblock块的移动情况。 */ public class gamecanvas extends jpanel { private static final long serialversionuid = 6732901391026089276l; private color backcolor = color.darkgray, frontcolor = color.white; private int rows, cols, score = 0, scoreforlevelupdate = 0; private ersbox[][] boxes; private int boxwidth, boxheight; /** * 画布类的构造函数 * * @param rows int,画布的行数 * @param cols int,画布的列数 行数和列数决定着画布拥有方格的数目 */ public gamecanvas(int rows, int cols) { this.rows = rows; this.cols = cols; boxes = new ersbox[rows][cols]; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boxes[i][j] = new ersbox(false); } } setborder(new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140))); } /** * 画布类的构造函数 * * @param rows * @param cols * @param backcolor * @param frontcolor */ public gamecanvas(int rows, int cols, color backcolor, color frontcolor) { this(rows, cols); this.backcolor = backcolor; this.frontcolor = frontcolor; } /** * 设置游戏背景色彩 * * @param backcolor color,背景色彩 */ public void setbackgroundcolor(color backcolor) { this.backcolor = backcolor; } /** * 取得游戏背景色彩 * * @return color ,背景色彩 */ public color getbackgroundcolor() { return backcolor; } /** * 设置游戏方块颜色 * * @param frontcolor color,方块颜色 */ public void setblockcolor(color frontcolor) { this.frontcolor = frontcolor; } /** * 取得游戏方块色彩 * * @return color,方块颜色 */ public color getblockcolor() { return frontcolor; } /** * 取得画布中方格的行数 * * @return */ public int getrows() { return rows; } /** * 取得画布中方格的列数 * * @return int,方格的列数 */ public int getcols() { return cols; } /** * 取得游戏成绩 * * @return int, 分数 */ public int getscore() { return score; } /** * 取得自上一次升级后的积分 * * @return int ,上一次升级后的积分 */ public int getscoreforlevelupdate() { return scoreforlevelupdate; } /** * 升级后,将上一次升级以来的积分清零 */ public void resetscoreforlevelupdate() { scoreforlevelupdate -= russiablocksgame.per_level_score; } /** * 得到某一行某一列的方格引用 * * @return row int ,要引用的方格所在的行 * @param col int, 要引用的方格所在的行 * @return ersbox,在row行col列的方格的引用 */ public ersbox getbox(int row, int col) { if (row < 0 || row > boxes.length - 1 || col < 0 || col > boxes[0].length - 1) { return null; } return (boxes[row][col]); } /** * 覆盖jcomponent类的函数,画组件。 * * @param g 图形设备环境 */ @override public void paintcomponent(graphics g) { super.paintcomponent(g); g.setcolor(frontcolor); for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { g.setcolor(boxes[i][j].iscolorbox() ? frontcolor : backcolor); g.fill3drect(j * boxwidth, i * boxheight, boxwidth, boxheight, true); } } } /** * 根据窗口大小,自动调节方格的尺寸 */ public void adjust() { boxwidth = getsize().width / cols; boxheight = getsize().height / rows; } /** * 当一行被游戏者叠满后,将此行清除,并为游戏者加分 * * @param row int,要清除的行,是由ersboxesgame类计算的 */ public synchronized void removeline(int row) { for (int i = row; i > 0; i--) { for (int j = 0; j < cols; j++) { boxes[i][j] = (ersbox) boxes[i - 1][j].clone(); //将上一行的方块颜色克隆下来, } //即消去一行方块 } score += russiablocksgame.per_level_score; scoreforlevelupdate += russiablocksgame.per_level_score; repaint(); } /** * 重置画布,置积分为零 */ public void reset() { score = 0; scoreforlevelupdate = 0; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boxes[i][j].setcolor(false); } } repaint(); } }
controlpanel.java
package russiablocksgame; import java.awt.borderlayout; import java.awt.color; import java.awt.graphics; import java.awt.gridlayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.awt.event.componentadapter; import java.awt.event.componentevent; import java.awt.event.keyadapter; import java.awt.event.keyevent; import java.text.dateformat; import java.text.simpledateformat; import java.util.date; import javax.swing.jbutton; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jtextfield; import javax.swing.timer; import javax.swing.border.border; import javax.swing.border.etchedborder; /** * 控制面板类,继承自jpanel。 上边安放预显窗口,等级,得分,控制按钮 主要用来控制游戏进程。 */ class controlpanel extends jpanel { private static final long serialversionuid = 3900659640646175724l; private jtextfield tflevel = new jtextfield("" + russiablocksgame.default_level), tfscore = new jtextfield(" 0"), tftime = new jtextfield(" "); private jbutton btplay = new jbutton(" 开始"), btpause = new jbutton(" 暂停"), btstop = new jbutton("终止游戏"), btturnlevelup = new jbutton(" 增加难度"), btturnleveldown = new jbutton(" 降低难度"); private jpanel pltip = new jpanel(new borderlayout()); private tippanel pltipblock = new tippanel(); private jpanel plinfo = new jpanel(new gridlayout(4, 1)); private jpanel plbutton = new jpanel(new gridlayout(6, 1)); private timer timer; private border border = new etchedborder(etchedborder.raised, color.white, new color(148, 145, 140)); /** * 控制面板类的构造函数 * * @param game ersblocksgame,ersblocksgame 类的一个实例引用 方便直接控制ersblocksgame类的行为。 */ public controlpanel(final russiablocksgame game) { setlayout(new gridlayout(3, 1, 0, 2)); pltip.add(new jlabel(" 下一个方块"), borderlayout.north); //添加组件 pltip.add(pltipblock); pltip.setborder(border); plinfo.add(new jlabel(" 难度系数")); plinfo.add(tflevel); plinfo.add(new jlabel(" 得分")); 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(new keyadapter() { @override public void keypressed(keyevent ke) { if (!game.isplaying()) { return; } ersblock block = game.getcurblock(); switch (ke.getkeycode()) { case keyevent.vk_down: block.movedown(); break; case keyevent.vk_left: block.moveleft(); break; case keyevent.vk_right: block.moveright(); break; case keyevent.vk_up: block.turnnext(); break; default: break; } } }); btplay.addactionlistener(new actionlistener() { //开始游戏 @override public void actionperformed(actionevent ae) { game.playgame(); } }); btpause.addactionlistener(new actionlistener() { //暂停游戏 @override public void actionperformed(actionevent ae) { if (btpause.gettext().equals(" 暂停")) { game.pausegame(); } else { game.resumegame(); } } }); btstop.addactionlistener(new actionlistener() { //停止游戏 @override public void actionperformed(actionevent ae) { game.stopgame(); } }); btturnlevelup.addactionlistener(new actionlistener() { //升高难度 @override public void actionperformed(actionevent ae) { try { int level = integer.parseint(tflevel.gettext()); if (level < russiablocksgame.max_level) { tflevel.settext("" + (level + 1)); } } catch (numberformatexception e) { } requestfocus(); } }); btturnleveldown.addactionlistener(new actionlistener() { //降低游戏难度 @override public void actionperformed(actionevent ae) { try { int level = integer.parseint(tflevel.gettext()); if (level > 1) { tflevel.settext("" + (level - 1)); } } catch (numberformatexception e) { } requestfocus(); } }); addcomponentlistener(new componentadapter() { @override public void componentresized(componentevent ce) { pltipblock.adjust(); } }); timer = new timer(1000, new actionlistener() { @override public void actionperformed(actionevent ae) { dateformat format = new simpledateformat("时间:hh:mm:ss"); //系统获得时间 date date = new date(); tftime.settext(format.format(date)); tfscore.settext("" + game.getscore()); int scoreforlevelupdate = //判断当前分数是否能升级 game.getscoreforlevelupdate(); if (scoreforlevelupdate >= russiablocksgame.per_level_score && scoreforlevelupdate > 0) { game.levelupdate(); } } }); timer.start(); } /** * 设置预显窗口的样式 * * @param style int,对应ersblock类的styles中的28个值 */ public void settipstyle(int style) { pltipblock.setstyle(style); } /** * 取得用户设置的游戏等级。 * * @return int ,难度等级,1-ersblocksgame.max_level */ public int getlevel() { int level = 0; try { level = integer.parseint(tflevel.gettext()); } catch (numberformatexception e) { } return level; } /** * 让用户修改游戏难度等级。 * * @param level 修改后的游戏难度等级 */ public void setlevel(int level) { if (level > 0 && level < 11) { tflevel.settext("" + level); } } /** * 设置“开始”按钮的状态。 */ public void setplaybuttonenable(boolean enable) { btplay.setenabled(enable); } public void setpausebuttonenable(boolean enable) { btpause.setenabled(enable); } public void setpausebuttonlabel(boolean pause) { btpause.settext(pause ? " 暂停" : " 继续"); } public void setstopbuttonenable(boolean enable) { btstop.setenabled(enable); } public void setturnlevelupbuttonenable(boolean enable) { btturnlevelup.setenabled(enable); } public void setturnleveldownbuttonenable(boolean enable) { btturnleveldown.setenabled(enable); } /** * 重置控制面板 */ public void reset() { tfscore.settext(" 0"); pltipblock.setstyle(0); } /** * 重新计算tippanel里的boxes[][]里的小框的大小 */ public void adjust() { pltipblock.adjust(); } /** * 预显窗口的实现细节类 */ public class tippanel extends jpanel { //tippanel用来显示下一个将要出现方块的形状 private static final long serialversionuid = 5160553671436997616l; private color backcolor = color.darkgray, frontcolor = color.white; private ersbox[][] boxes = new ersbox[ersblock.boxes_rows][ersblock.boxes_cols]; private int style, boxwidth, boxheight; private boolean istiled = false; /** * 预显示窗口类构造函数 */ public tippanel() { for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boxes[i][j] = new ersbox(false); } } } /** * 设置预显示窗口的方块样式 * * @param style int,对应ersblock类的styles中的28个值 */ public void setstyle(int style) { this.style = style; repaint(); } /** * 覆盖jcomponent类的函数,画组件。 * * @param g 图形设备环境 */ @override public void paintcomponent(graphics g) { super.paintcomponent(g); if (!istiled) { adjust(); } int key = 0x8000; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { color color = ((key & style) != 0 ? frontcolor : backcolor); g.setcolor(color); g.fill3drect(j * boxwidth, i * boxheight, boxwidth, boxheight, true); key >>= 1; } } } /** * g根据窗口的大小,自动调整方格的尺寸 */ public void adjust() { boxwidth = getsize().width / ersblock.boxes_cols; boxheight = getsize().height / ersblock.boxes_rows; istiled = true; } } }
ersbox.java
package russiablocksgame; import java.awt.dimension; /** * 方格类,是组成块的基本元素,用自己的颜色来表示块的外观 */ public class ersbox implements cloneable { private boolean iscolor; private dimension size = new dimension(); /** * 方格类的构造函数, * * @param iscolor 是不是用前景色来为此方格着色 true前景色,false 用背景色 */ public ersbox(boolean iscolor) { this.iscolor = iscolor; } /** * 此方格是不是用前景色表现 * * @return boolean ,true用前景色表现,false 用背景色表现 */ public boolean iscolorbox() { return iscolor; } /** * 设置方格的颜色, * * @param iscolor boolean ,true用前景色表现,false 用背景色表现 */ public void setcolor(boolean iscolor) { this.iscolor = iscolor; } /** * 得到此方格的尺寸 * * @return dimension ,方格的尺寸 */ public dimension getsize() { return size; } /** * 设置方格的尺寸, * * @param size dimension ,方格的尺寸 */ public void setsize(dimension size) { this.size = size; } /** * 覆盖object的object clone(),实现克隆 * * @return object,克隆的结果 */ @override public object clone() { object cloned = null; try { cloned = super.clone(); } catch (exception ex) { ex.printstacktrace(); } return cloned; } }
ersblock.java
package russiablocksgame; /** * 块类,继承自线程类(thread) 由4 × 4个方块(ersbox)构成一个方块, 控制块的移动·下落·变形等 */ class ersblock extends thread { /** * 一个块占的行数是4行 */ public final static int boxes_rows = 4; /** * 一个块占的列数是4列 */ public final static int boxes_cols = 4; /** * 让升级变化平滑的因子,避免最后几级之间的速度相差近一倍 */ public final static int level_flatness_gene = 3; /** * 相近的两级之间,块每下落一行的时间差别为多少(毫秒) */ public final static int between_levels_degress_time = 50; /** * 方块的样式数目为7 */ public final static int block_kind_number = 7; /** * 每一个样式的方块的反转状态种类为4 */ public final static int block_status_number = 4; /** * 分别对应7种模型的28种状态 */ public final static int[][] 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}, //方块的四种状态 }; private gamecanvas canvas; private ersbox[][] boxes = new ersbox[boxes_rows][boxes_cols]; private int style, y, x, level; private boolean pausing = false, moving = true; /** * 构造函数,产生一个特定的块 * * @param style 块的样式,对应styles的28个值中的一个 * @param y 起始位置,左上角在canvas中的坐标行 * @param x 起始位置,左上角在canvas中的坐标列 * @param level 游戏等级,控制块的下落速度 * @param canvas 画板 */ public ersblock(int style, int y, int x, int level, gamecanvas canvas) { this.style = style; this.y = y; this.x = x; this.level = level; this.canvas = canvas; int key = 0x8000; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boolean iscolor = ((style & key) != 0); boxes[i][j] = new ersbox(iscolor); key >>= 1; } } display(); } /** * 线程类的run()函数覆盖,下落块,直到块不能再下落 */ @override public void run() { while (moving) { try { sleep(between_levels_degress_time * (russiablocksgame.max_level - level + level_flatness_gene)); } catch (interruptedexception ie) { ie.printstacktrace(); } //后边的moving是表示在等待的100毫秒间,moving没有被改变 if (!pausing) { moving = (moveto(y + 1, x) && moving); } } } /** * 块向左移动一格 */ public void moveleft() { moveto(y, x - 1); } /** * 块向右移动一格 */ public void moveright() { moveto(y, x + 1); } /** * 块向下移动一格 */ public void movedown() { moveto(y + 1, x); } /** * 块变型 */ public void turnnext() { for (int i = 0; i < block_kind_number; i++) { for (int j = 0; j < block_status_number; j++) { if (styles[i][j] == style) { int newstyle = styles[i][(j + 1) % block_status_number]; turnto(newstyle); return; } } } } public void startmove() { pausing = false; moving = true; } /** * 暂停块的下落,对应游戏暂停 */ public void pausemove() { pausing = true; // moving = false; } /** * 继续块的下落,对应游戏继续 */ public void resumemove() { pausing = false; moving = true; } /** * 停止块的下落,对应游戏停止 */ public void stopmove() { pausing = false; moving = false; } /** * 将当前块从画布的对应位置移除,要等到下次重画画布时才能反映出来 */ private void erase() { for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { if (boxes[i][j].iscolorbox()) { ersbox box = canvas.getbox(i + y, j + x); if (box == null) { continue; } box.setcolor(false); } } } } /** * 让当前块放置在画布的对因位置上,要等到下次重画画布时才能看见 */ private void display() { for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { if (boxes[i][j].iscolorbox()) { ersbox box = canvas.getbox(i + y, j + x); if (box == null) { continue; } box.setcolor(true); } } } } /** * 当前块能否移动到newrow/newcol 所指定的位置 * * @param newrow int,目的地所在行 * @param newcol int,目的地所在列 * @return boolean,true-能移动,false-不能移动 */ public boolean ismoveable(int newrow, int newcol) { erase(); for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { if (boxes[i][j].iscolorbox()) { ersbox box = canvas.getbox(i + newrow, j + newcol); if (box == null || (box.iscolorbox())) { display(); return false; } } } } display(); return true; } /** * 将当前块移动到newrow/newcol 所指定的位置 * * @param newrow int,目的地所在行 * @param newcol int,目的地所在列 * @return boolean,true-移动成功,false-移动失败 */ private synchronized boolean moveto(int newrow, int newcol) { if (!ismoveable(newrow, newcol) || !moving) { return false; } erase(); y = newrow; x = newcol; display(); canvas.repaint(); return true; } /** * 当前块能否变成newstyle所指定的块样式,主要是考虑 边界以及被其他块挡住,不能移动的情况 * * @param newsytle int,希望改变的块样式,对应styles的28个值中的一个 * @return boolean,true-能改变,false-不能改变 */ private boolean isturnable(int newstyle) { int key = 0x8000; erase(); for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { if ((newstyle & key) != 0) { ersbox box = canvas.getbox(i + y, j + x); if (box == null || (box.iscolorbox())) { display(); return false; } } key >>= 1; } } display(); return true; } /** * 将当前块变成newstyle所指定的块样式 * * @param newstyle int,希望改变的块样式,对应styles的28个值中的一个 * @return true-改变成功,false-改变失败 */ private boolean turnto(int newstyle) { if (!isturnable(newstyle) || !moving) { return false; } erase(); int key = 0x8000; for (int i = 0; i < boxes.length; i++) { for (int j = 0; j < boxes[i].length; j++) { boolean iscolor = ((newstyle & key) != 0); boxes[i][j].setcolor(iscolor); key >>= 1; } } style = newstyle; display(); canvas.repaint(); return true; } }
main.java
package russiablocksgame; /** * 程序入口函数 * * @param args string[],附带的命令行参数 */ public class main { public static void main(string[] args) { new russiablocksgame("俄罗斯方块:杨宇杰"); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。