📄 lovehui.java
字号:
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class lovehui extends JFrame {
public final static int PER_LINE_SCORE = 100; //每填满一行计多少分
public final static int PER_LEVEL_SCORE = PER_LINE_SCORE * 20;//积多少分以后能升级
public final static int MAX_LEVEL = 12; //最大级数是10级
public final static int DEFAULT_LEVEL = 0; //默认级数是0
private GameCanvas canvas;
private ErsBlock block;
private ControlPanel ctrlPanel;
private JMenuBar bar = new JMenuBar();
private boolean playing = false;
public lovehui(String title) {/* 主游戏类的构造函数* @param title String,窗口标题*/
super(title);
setSize(315, 392);
Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((scrSize.width - getSize().width) / 2,(scrSize.height - getSize().height) / 2);
Container container = getContentPane();
container.setLayout(new BorderLayout(6, 0));
canvas = new GameCanvas(20, 12);
ctrlPanel = new ControlPanel(this);
container.add(canvas, BorderLayout.CENTER);
container.add(ctrlPanel, BorderLayout.EAST);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
stopGame();
System.exit(0);
}
});
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {canvas.fanning();}
});
show();
canvas.fanning();
}
public void reset() {//让游戏“复位”
ctrlPanel.reset();
canvas.reset();
}
public boolean isPlaying(){return playing;} //判断游戏是否还在进行
public ErsBlock getCurBlock(){return block;}//得到当前活动的块 @return ErsBlock,当前活动块的引用
public GameCanvas getCanvas(){return canvas;}//得到当前画布 @return GameCanvas,当前画布的引用
public void playGame() { //开始游戏
play();
ctrlPanel.setPlayButtonEnable(false);;
ctrlPanel.requestFocus();
}
public void pauseGame() { //游戏暂停
if (block != null) block.pauseMove();
ctrlPanel.setPauseButtonLabel(false);
}
public void resumeGame() { //让暂停中的游戏继续
if (block != null) block.resumeMove();
ctrlPanel.setPauseButtonLabel(true);
ctrlPanel.requestFocus();
}
public void stopGame() { //用户停止游戏
playing = false;
if (block != null) block.stopMove();
ctrlPanel.setPlayButtonEnable(true);
ctrlPanel.setPauseButtonLabel(true);
}
public int getLevel(){return ctrlPanel.getLevel();}//得到当前游戏者设置的游戏难度
public void setLevel(int level){ //让用户设置游戏难度
if (level < 11 && level > 0) ctrlPanel.setLevel(level);
}
public int getScore(){ //得到游戏积分
if (canvas != null) return canvas.getScore();
return 0;
}
public int getScoreForLevelUpdate() { //得到自上次升级以来的游戏积分,升级以后,此积分清零 return int, 积分。
if (canvas != null) return canvas.getScoreForLevelUpdate();
return 0;
}
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() { //游戏结束了
JOptionPane.showMessageDialog(this, "慧青我爱你,所以我先睡了!");
}
private void setWindowStyle(String plaf) { //根据字串设置窗口外观
try {
UIManager.setLookAndFeel(plaf);
SwingUtilities.updateComponentTreeUI(this);
}
catch (Exception e) {}
}
private class Game implements Runnable{ // 一轮游戏过程,实现了Runnable接口
public void run() {
int col = (int) (Math.random() * (canvas.getCols() - 3)),
style = ErsBlock.STYLES[(int) (Math.random() * 7)][(int) (Math.random() * 4)];
while (playing) {
if (block != null) { //第一次循环时,block为空
if (block.isAlive()) {
try {
Thread.currentThread().sleep(100);
}
catch (InterruptedException ie) {ie.printStackTrace();}
continue;
}
}
checkFullLine(); //检查是否有全填满的行
if (isGameOver()) { //检查游戏是否应该结束了
ctrlPanel.setPlayButtonEnable(true);
ctrlPanel.setPauseButtonLabel(true);
reportGameOver();
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);
}
}
}
private boolean isGameOver() { //根据最顶行是否被占,判断游戏是否已经结束了。
for (int i = 0; i < canvas.getCols(); i++) {
ErsBox box = canvas.getBox(0, i);
if (box.isColorBox()) return true;
}
return false;
}
}
public static void main(String[] args) {// 程序入口函数
new lovehui("老天...保佑我...成功VS我没有放弃!");
}
}
class GameCanvas extends JPanel { //画布类,内有<行数> * <列数>个方格类实例。
private Color backColor = Color.black, frontColor = Color.orange; //ErsBlock线程类动态改变画布类的方格颜色,画布类通过
private int rows, cols, score = 0, scoreForLevelUpdate = 0; //检查方格颜色来体现ErsBlock块的移动情况。
private ErsBox[][] boxes;
private int boxWidth, boxHeight;
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)));
}
public GameCanvas(int rows, int cols,Color backColor, Color frontColor) { // 画布类的构造前景色,背景色函数
this(rows, cols);
this.backColor = backColor;
this.frontColor = frontColor;
}
public void setBackgroundColor(Color backColor) {this.backColor = backColor;}// 设置游戏背景色彩
public Color getBackgroundColor() {return backColor;}//取得游戏背景色彩
public void setBlockColor(Color frontColor){this.frontColor = frontColor;}//设置游戏方块色彩
public Color getBlockColor() {return frontColor;}//取得游戏方块色彩
public int getRows() {return rows;} //取得画布中方格的行数
public int getCols() {return cols;} //取得画布中方格的列数
public int getScore() {return score;}//取得游戏成绩
public int getScoreForLevelUpdate() {return scoreForLevelUpdate;}//取得自上一次升级后的积分
public void resetScoreForLevelUpdate() {//升级后,将上一次升级以来的积分清0
scoreForLevelUpdate -= lovehui.PER_LEVEL_SCORE;
}
public ErsBox getBox(int row, int col) { //得到某一行某一列的方格引用。
if (row < 0 || row > boxes.length - 1|| col < 0 || col > boxes[0].length - 1)
return null;
else return (boxes[row][col]);
}
public void paintComponent(Graphics g) { //覆盖JComponent类的函数,画组件。
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 fanning() { //根据窗口的大小,自动调整方格的尺寸
boxWidth = getSize().width / cols;
boxHeight = getSize().height / rows;
}
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();
}
//a++;
score +=100;
scoreForLevelUpdate +=100;
repaint();
}
public void reset()
{ //重置画布,置积分为0
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();
}
}
class ErsBox implements Cloneable{ //方格类,是组成块的基本元素,用自己的颜色来表示块的外观
private boolean isColor;
private Dimension size = new Dimension();
public ErsBox(boolean isColor) {this.isColor = isColor;}//方格类的构造函数
public boolean isColorBox() {return isColor;} //此方格是不是用前景色表现
public void setColor(boolean isColor) {this.isColor = isColor;}//设置方格的颜色
public Dimension getSize() {return size;} //得到此方格的尺寸
public void setSize(Dimension size) {this.size = size;}//设置方格的尺寸
public Object clone() {//覆盖Object的Object clone(),实现克隆
Object cloned = null;
try {
cloned = super.clone();
}
catch (Exception ex) {
ex.printStackTrace();
}
return cloned;
}
}
class ControlPanel extends JPanel{ //控制面板类,继承自JPanel.上边安放预显窗口、等级、得分、控制按钮主要用来控制游戏进程。
private JTextField
tfLevel = new JTextField("" + lovehui.DEFAULT_LEVEL),
tfScore = new JTextField("0");
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(5, 0));
private Timer timer;
private lovehui game;
private Border border = new EtchedBorder(
EtchedBorder.RAISED, Color.white, new Color(148, 145, 140));
public ControlPanel(final lovehui game) { // 控制面板类的构造函数
setLayout(new GridLayout(3, 15, 0, 10));
this.game = game;
plTip.add(new JLabel("Next block"), BorderLayout.NORTH);
plTip.add(plTipBlock);
plTip.setBorder(border);
plInfo.add(new JLabel("等级"));
plInfo.add(tfLevel);
plInfo.add(new JLabel("分数"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -