⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tetrics.java

📁 java游戏编程导学系列二 使用说明 所有范例
💻 JAVA
字号:
package tetrics;

import java.awt.*;
import javax.swing.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;



public class Tetrics
    extends JPanel
    implements Runnable, KeyListener {
  Thread m_theThread = null;

  BorderLayout borderLayout1 = new BorderLayout();

  final int XOFFSET = 200; //信息区大小
  static int m_nCols;
  static int m_nRows;

  int m_nSqLength; //每个方块的大小

  boolean m_bGameInPlay; // 判断当前游戏是不是正在玩
  boolean m_bNeedNewPiece; // 判断当前是不是需要一个新的方块组

  int m_nPlayLevel; // 游戏当前的级别
  int m_nPieceValue = 0; // 当前方块组的分值
  int m_nTheScore = 0; // 当前游戏的分数
  Color m_colors[]; //定义一组颜色,为每个不同的方块组赋不同的颜色
  int m_nDelayMap[] = {
      600, 600, 600, 600, 500, 400, 300, 250, 200, 150, 100}; //定义一个数组,来定义每个级别的方块组移动的速度(每次移动之间的时间)

  public static int NOSQUARE = 0; // 表征当前位置没有方块存在

  Square m_curPiece[] = new Square[4]; // 游戏正在玩的方块组。我们将4个小方块组成的各种不同的方块组合叫做方块组
  Square m_prePiece[] = new Square[4]; // 正在预览的方块组
  int m_nField[][]; //表述整个游戏的当前状态的数组
  int m_nOldField[][]; //表述整个游戏的状态刚刚改变之前的状态数组
  int m_nTotalPieces; // 当前游戏已经玩过的方块组的个数

  boolean m_bPaused = false; // 当前游戏是否已经暂停

  TetricsFrame m_tFrame;

  //private String m_nTheScore;
  private boolean m_bJustupdating = false;
  public Tetrics() {
    super();
    try {
      jbInit();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public Tetrics(TetricsFrame tFrame) {
    super();
    m_tFrame = tFrame;
    try {
      jbInit();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  void jbInit() throws Exception {
    this.addKeyListener(this);
    //设置初始参数
    m_nSqLength = 20;
    m_nCols = 10;
    m_nRows = 20;
    m_nField = new int[m_nCols][m_nRows + 4];
    m_nOldField = new int[m_nCols][m_nRows + 4];

    m_nPlayLevel = 5;
    //定义8种颜色
    m_colors = new Color[8];
    m_colors[0] = new Color(40, 40, 40);
    m_colors[1] = new Color(255, 0, 0);
    m_colors[2] = new Color(0, 200, 0);
    m_colors[3] = new Color(0, 200, 255);

    m_colors[4] = new Color(255, 255, 0);
    m_colors[5] = new Color(255, 150, 0);
    m_colors[6] = new Color(210, 0, 240);
    m_colors[7] = new Color(40, 0, 240);
    //to initialize the m_prePiece;

    this.setFont(new java.awt.Font("Dialog", 0, 18));

    this.setLayout(borderLayout1);
    this.setVisible(true);
  }

  public synchronized void paint(Graphics g) {

    g.setFont(new Font("宋体", 0, 18));
    int gx = m_nSqLength;
    int gy = m_nSqLength * m_nRows / 4;
    //打印Score和Level的位置
    //g.clearRect(gx, gy - 25, XOFFSET - gx, 25);
    g.drawString("Score:" + m_nTheScore, gx, gy);
    gy += 30;
    //g.clearRect(gx, gy - 25, XOFFSET - gx, 25);
    g.drawString("Level:5", gx, gy);
    //画预览的方块
    int middle = m_nCols / 2;
    int top = m_nRows;
    gy += 30;
    g.setColor(Color.black);
    g.fillRect(gx, gy, m_nSqLength * 4, m_nSqLength * 4);
    //画游戏区
    if (m_bGameInPlay) {
      for (int i = 0; i < 4; i++) {
        g.setColor(m_colors[m_prePiece[i].m_nColor]);
        g.fill3DRect( (m_prePiece[i].m_nColumn - middle + 2) * m_nSqLength + gx,
                     gy - (m_prePiece[i].m_nRow - top) * m_nSqLength,
                     m_nSqLength, m_nSqLength, true);
      }
    }

    for (int i = 0; i < m_nCols; i++) {
      for (int j = 0; j < m_nRows; j++) {
        //-1代表没有刚刚开始
        if (!m_bJustupdating || m_nOldField[i][m_nRows - 1 - j] == -1 ||
            m_nOldField[i][m_nRows - 1 - j] != m_nField[i][m_nRows - 1 - j]) {
          g.setColor(m_colors[m_nField[i][m_nRows - 1 - j]]);
          g.fill3DRect(XOFFSET + m_nSqLength * i, m_nSqLength + m_nSqLength * j,
                       m_nSqLength, m_nSqLength, true);
        }
        m_nOldField[i][m_nRows - 1 - j] = m_nField[i][m_nRows - 1 - j];
      }
    }
    m_bJustupdating = false;

  }
  public void update(Graphics g)
  {
              m_bJustupdating=true;
              paint(g);
  }



  private void newPrePiece() {
    int middle = m_nCols / 2;
    int top = m_nRows;

    switch ( (int) (Math.random() * 7)) {
      case 0:

        //红色方块组
        m_nPieceValue = 100;
        m_prePiece[0] = new Square(middle - 1, top - 1, 1);
        m_prePiece[1] = new Square(middle - 2, top - 1, 1);
        m_prePiece[2] = new Square(middle, top - 1, 1);
        m_prePiece[3] = new Square(middle + 1, top - 1, 1);
        break;

      case 1:

        //桔红色方块组
        m_nPieceValue = 200;
        m_prePiece[0] = new Square(middle, top - 2, 5);
        m_prePiece[1] = new Square(middle, top - 1, 5);
        m_prePiece[2] = new Square(middle - 1, top - 2, 5);
        m_prePiece[3] = new Square(middle + 1, top - 2, 5);
        break;

      case 2:

        //绿色方块组
        m_nPieceValue = 180;
        m_prePiece[0] = new Square(middle, top - 2, 2);
        m_prePiece[1] = new Square(middle - 1, top - 1, 2);
        m_prePiece[2] = new Square(middle, top - 1, 2);
        m_prePiece[3] = new Square(middle + 1, top - 2, 2);
        break;

      case 3:

        //蓝色方块组
        m_nPieceValue = 180;
        m_prePiece[0] = new Square(middle, top - 2, 7);
        m_prePiece[1] = new Square(middle + 1, top - 1, 7);
        m_prePiece[2] = new Square(middle, top - 1, 7);
        m_prePiece[3] = new Square(middle - 1, top - 2, 7);
        break;

      case 4:

        //浅蓝色方块组
        m_nPieceValue = 100;
        m_prePiece[0] = new Square(middle - 1, top - 1, 3);
        m_prePiece[1] = new Square(middle, top - 1, 3);
        m_prePiece[2] = new Square(middle - 1, top - 2, 3);
        m_prePiece[3] = new Square(middle, top - 2, 3);
        break;

      case 5:

        //洋红色方块组
        m_nPieceValue = 120;
        m_prePiece[0] = new Square(middle, top - 1, 6);
        m_prePiece[1] = new Square(middle - 1, top - 1, 6);
        m_prePiece[2] = new Square(middle + 1, top - 1, 6);
        m_prePiece[3] = new Square(middle + 1, top - 2, 6);
        break;

      case 6:

        //黄色方块组
        m_nPieceValue = 120;
        m_prePiece[0] = new Square(middle, top - 1, 4);
        m_prePiece[1] = new Square(middle + 1, top - 1, 4);
        m_prePiece[2] = new Square(middle - 1, top - 1, 4);
        m_prePiece[3] = new Square(middle - 1, top - 2, 4);
        break;
    }
  }

  /**
   * 将预览的方块转变成正在动的方块
   */
  private void transferPreToCur() {
    Square old[] = new Square[4];
    old[0] = old[1] = old[2] = old[3] = new Square( -1, -1, 0);

    for (int i = 0; i < 4; i++) {
      m_curPiece[i] = m_prePiece[i];
    }

    m_bGameInPlay = moveSquares(old, m_curPiece);
    if (!m_bGameInPlay && m_tFrame != null) {
      m_tFrame.insertScoreReport(m_nTheScore);
    }
  }


  /**
   * 移动方块,如果不能移动,则返回假
   */
  boolean moveSquares(Square from[], Square to[]) {
    //判断是否能移动
    outerlable:
        for (int i = 0; i < to.length; i++) {
      if (to[i].InBounds() == false)return false;

      //如果不在可玩区域,则返回假
      if (m_nField[to[i].m_nColumn][to[i].m_nRow] != 0) {
        for (int j = 0; j < from.length; j++)
          if (to[i].IsEqual(from[j]))continue outerlable;
        return false;
      }
    }

    //移动
    for (int i = 0; i < from.length; i++) {
      if (from[i].InBounds()) {
        m_nField[from[i].m_nColumn][from[i].m_nRow] = 0;
      }
    }
    for (int i = 0; i < to.length; i++) {
      m_nField[to[i].m_nColumn][to[i].m_nRow] = to[i].m_nColor;
    }
    return true;
  }

  /**
   *移动方块
   *@param nDx 左右移动,向左为-1
   *@param nDy 上下移动,向下为-1
   *@param bRotate 是否转动
   */
  private synchronized boolean moveCurPiece(int nDx, int nDy, boolean bRotate) {
    Square newpos[] = new Square[4];
    for (int i = 0; i < 4; i++) {
      //如果转动的话,则转动方块组
      if (bRotate) {
        int dx = m_curPiece[i].m_nColumn - m_curPiece[0].m_nColumn;
        int dy = m_curPiece[i].m_nRow - m_curPiece[0].m_nRow;
        newpos[i] = new
            Square(m_curPiece[0].m_nColumn - dy, m_curPiece[0].m_nRow + dx,
                   m_curPiece[i].m_nColor);
      }
      else {
        newpos[i] = new
            Square(m_curPiece[i].m_nColumn + nDx, m_curPiece[i].m_nRow + nDy,
                   m_curPiece[i].m_nColor);
      }
    }
    //调用上面提到的方法
    if (moveSquares(m_curPiece, newpos) == false) {
      return false;
    }
    m_curPiece = newpos;
    return true;
  }

//去掉可以消去的行
  private void removelines() {
    outerlabel:
        for (int j = 0; j < m_nRows; j++) {
      for (int i = 0; i < m_nCols; i++) {
        if (m_nField[i][j] == 0) {
          continue outerlabel;
        }
      }
      for (int k = j; k < m_nRows - 1; k++) {
        for (int i = 0; i < m_nCols; i++) {
          m_nField[i][k] = m_nField[i][k + 1];
        }
      }
      j -= 1;
    }
  }

  public void run() {

    while (m_bGameInPlay) {
      try {
        int t;
        //取得要暂停的时间,这个决定着游戏的速度
        if (m_nPlayLevel > 10) {
          t = 75;
        }else {
          t = m_nDelayMap[m_nPlayLevel];
        }
        Thread.sleep(t);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
      if (m_bNeedNewPiece){
        if (m_nPieceValue > 0) {
          //计算分数
          m_nTheScore += m_nPieceValue;
          m_nTotalPieces += 1;
          if (m_nTotalPieces % 30 == 0) {
            m_nPlayLevel++;
          }
        }
        //消去一行
        removelines();
        transferPreToCur();
        newPrePiece();
        m_bNeedNewPiece = false;
      }
      else {
        m_bNeedNewPiece = !moveCurPiece(0, -1, false);
        if (!m_bNeedNewPiece) {
          m_nPieceValue -= 5;
        }
      }
      this.update(this.getGraphics());
    }
    m_theThread = null;
  }

  public synchronized void start() {
    requestFocus();
    if (m_theThread != null)//游戏是被暂停,而不是重新开始
    {
      m_bPaused = false;
     // m_theThread.
      m_theThread.resume();
      this.repaint();
      return;
    }

    //重新开始赋上游戏的状态
    for (int i = 0; i < m_nCols; i++) {
      for (int j = 0; j < m_nRows + 4; j++) {
        m_nField[i][j] = 0;
        m_nOldField[i][j] = -1;
      }
    }
    m_nTheScore = 0;
    m_nTotalPieces = 0;
    m_bNeedNewPiece = true;
    m_bGameInPlay = true;

    m_theThread = new Thread(this);
    newPrePiece();
    m_theThread.start();
    this.repaint();
    //requestFocus();
  }

  public synchronized void pause() {
    if (m_theThread != null) {
      try {
        m_theThread.suspend();
        m_bPaused = true;
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public synchronized void stop() {
    if (m_theThread != null) {
      //m_theThread.destroy();
      m_theThread.stop();
    }
    m_theThread = null;
  }


  public void setPlayLevel(int nLevel) {
    m_nPlayLevel = nLevel;
//        System.out.println("m_nPlayLevel="+m_nPlayLevel);

    Graphics g = getGraphics();
    //g.setFont(new Font("宋体", 0, 18));
    int gx = m_nSqLength;
    int gy = m_nSqLength * m_nRows / 4 + 30;
    g.clearRect(gx, gy - 25, XOFFSET - gx, 25);
    g.drawString("Level:" + m_nPlayLevel, gx, gy);
//        System.out.println("paint m_nPlayLevel="+m_nPlayLevel);

  }

  public int getPlayLevel() {
    return m_nPlayLevel;

  }

  public void keyTyped(KeyEvent e) {
    int nKeyCode = e.getKeyChar();
    switch (nKeyCode) {
      case 97:
        moveCurPiece( -1, 0, false);
        m_bNeedNewPiece = false;
        this.update(this.getGraphics());
        break;

      case 115:
        while (moveCurPiece(0, -1, false)) {
          ;
        }
        this.update(this.getGraphics());
        break;

      case 100:
        moveCurPiece(1, 0, false);
        m_bNeedNewPiece = false;
        this.update(this.getGraphics());
        break;
      case 119:
        moveCurPiece(0, 0, true);
        this.update(this.getGraphics());
        break;

    }

  }

  public void keyPressed(KeyEvent e) {
  }

  public void keyReleased(KeyEvent e) {
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -