当前位置: 移动技术网 > IT编程>开发语言>Java > java实现俄罗斯方块小程序

java实现俄罗斯方块小程序

2019年07月19日  | 移动技术网IT编程  | 我要评论

这是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("俄罗斯方块:杨宇杰"); 
 } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网