Java奔跑吧小恐龙游戏

java项目开发大致过程

List item
游戏运行图片:

在这里插入图片描述
在这里插入图片描述

目录:

一、com.mr.main(入口包)

入口包主要定义了程序运行的入口

①、Start.java

package com.mr.main;
import com.mr.view.MainFrame;

/*
 * 入口类
 * @author mingrisoft
 */
public class Start {

    public static void main(String[] args) {
        MainFrame frame = new MainFrame();// 创建主窗体
        frame.setVisible(true);// 显示主窗体
    }
}

二、com.mr.modle(模型包)

模型包中定义了Dinosaur(恐龙类)和Obstacle(障碍类)

①、Dinosaur.java

Dinosaur 类的成员属性大多数都是私有属性,只有少数共有属性用于游戏画板绘图使用,例如主图片和横纵坐标

在这里插入图片描述

package com.mr.modle;

/*
恐龙类
 */

import com.mr.service.FreshThread;
import com.mr.service.Sound;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Dinosaur {
    public BufferedImage image;// 主图片
    /*
    BufferedImage是缓冲图像

    image是一个抽象类,BufferedImage是其实现类,是一个带缓冲区图像类,
    主要作用是将一幅图片加载到内存中(BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便地操作这个图片),
    提供获得绘图对象、图像缩放、选择图像平滑度等功能,通常用来做图片大小变换、图片变灰、设置透明不透明等。
     */
    private BufferedImage image1, image2, image3;// 跑步图片

    public int x, y;// 坐标

    private int jumpValue = 0;// 跳跃的增变量
    private boolean jumpState = false;// 跳跃状态
    private int stepTimer = 0;// 踏步计时器
    private final int JUMP_HIGHT = 100;// 跳起最大高度
    private final int LOWEST_Y = 120;// 落地最低坐标
    private final int FREASH = FreshThread.FREASH;// 刷新时间

/*
在Dinosaur类的构造方法中将恐龙横坐标固定在50像素的地方,纵坐标采用落地时的坐标,
构造方法的具体代码如下
 */
    public Dinosaur() {
        x = 50;
        y = LOWEST_Y;
        try {
            image1 = ImageIO.read(new File("image/恐龙1.png"));
            image2 = ImageIO.read(new File("image/恐龙2.png"));
            image3 = ImageIO.read(new File("image/恐龙3.png"));
            /*
            Java ImageIO.read() 方法是用来读取图像文件的方法。
            它可以读取多种格式的图像文件,包括 JPEG、PNG、GIF、BMP 等。
            使用该方法需要传入一个 File 或 InputStream 对象作为参数,然后返回一个 BufferedImage 对象。
            在读取图像文件时,需要注意文件路径或输入流的正确性,否则会抛出异常。
             */
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /*
     * 移动
     */
    public void move() {
        step();// 不断踏步
        if (jumpState) {// 如果正在跳跃
            if (y >= LOWEST_Y) {// 如果纵坐标大于等于最低点
                jumpValue = -4;// 增变量为负值
            }
            if (y <= LOWEST_Y - JUMP_HIGHT) {// 如果跳过最高点
                jumpValue = 4;// 增变量为正值
            }
            y += jumpValue;// 纵坐标发生变化
            if (y >= LOWEST_Y) {// 如果再次落地
                jumpState = false;// 停止跳跃
            }
        }
    }

    /*
     * 跳跃
     */
    public void jump() {
        if (!jumpState) {// 如果没处于跳跃状态
            Sound.jump();// 播放跳跃音效
        }
        jumpState = true;// 处于跳跃状态
    }



    /*
     * 踏步
     */
    private void step() {
        // 每过250毫秒,更换一张图片。因为共有3图片,所以除以3取余,轮流展示这三张
        int tmp = stepTimer / 250 % 3;
        switch (tmp) {
            case 1 :
                image = image1;
                break;
            case 2 :
                image = image2;
                break;
            default :
                image = image3;
        }
        stepTimer += FREASH;// 计时器递增
    }

    /*
     * 足部边界区域
     *
     * @return
     */
    public Rectangle getFootBounds() {
        return new Rectangle(x + 30, y + 59, 29, 18);
    }

    /*
     * 头部边界区域
     *
     * @return
     */
    public Rectangle getHeadBounds() {
        return new Rectangle(x + 66, y + 25, 32, 22);
    }



}

②、Obstacle

障碍类

package com.mr.modle;
/*
障碍类
 */

import com.mr.view.BackgroundImage;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class Obstacle {
    public int x, y;// 横纵坐标
    public BufferedImage image;
    private BufferedImage stone;// 石头图片
    private BufferedImage cacti;// 仙人掌图片
    private int speed;// 移动速度
/*
在Obstacle类的构造方法中,Obstacle对象会随机成为石头或仙人掌
 */
    public Obstacle() {
        try {
            stone = ImageIO.read(new File("image/石头.png"));
            cacti = ImageIO.read(new File("image/仙人掌.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Random r = new Random();// 创建随机对象
        if (r.nextInt(2) == 0) {// public int nextInt(2)返回大于等于0且小于2的随机整数,即随机返回 0或者1
            image = cacti;// 采用仙人掌图片
        } else {
            image = stone;// 采用石头图片
        }
        x = 800;// 初始横坐标
        y = 200 - image.getHeight();// 纵坐标,因使用不同的障碍图片采用不同的纵坐标
        speed = BackgroundImage.SPEED;// 移动速度与背景同步
    }

    /*
     * 移动
     */
    public void move() {
        x -= speed;// 横坐标递减
    }

    /*
     * 获取边界
     *
     * @return
     */
    public Rectangle getBounds() {
        if (image == cacti) {// 如果使用仙人掌图片
            // 返回仙人掌的边界
            return new Rectangle(x + 7, y, 15, image.getHeight());
        }
        // 返回石头的边界
        return new Rectangle(x + 5, y + 4, 23, 21);
    }


    /* 消除
     *
     * 是否存活
     *
     * @return
     */
    public boolean isLive() {
        // 如果移出了游戏界面
        if (x <= -image.getWidth()) {
            return false;// 消亡
        }
        return true;// 存活
    }

}

三、com.mr.service(服务包)

服务包中包含 (FreshThread)刷新帧线程类、(MusicPlayer)音乐播放器类、(ScoreRecorder)分数记录器类和(Sound)音效类

①、FreshThread.java

package com.mr.service;
/*
刷新帧
 */

import java.awt.Container;
import com.mr.view.GamePanel;
import com.mr.view.MainFrame;
import com.mr.view.ScoreDialog;

/*
 * 刷新帧线程
 *
 * @author mingrisoft
 *
 */
public class FreshThread extends Thread {
    public static final int FREASH = 20;// 刷新时间
    GamePanel p;// 游戏面板

    public FreshThread(GamePanel p) {
        this.p = p;
    }

    public void run() {
        while (!p.isFinish()) {// 如果游戏未结束
            p.repaint();// 重绘游戏面板
            try {
                Thread.sleep(FREASH);// 按照刷新时间休眠
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Container c = p.getParent();// 获取面板父容器
        while (!(c instanceof MainFrame)) {// 如果父容器不是主窗体类
            c = c.getParent();// 继续获取父容器的父容器
        }
        MainFrame frame = (MainFrame) c;// 将容器强制转换为主窗体类
        new ScoreDialog(frame);// 弹出得分记录对话框
        frame.restart();// 主窗体重载开始游戏
    }
}

②、MusicPlayer.java

package com.mr.service;

/*
音乐播放器
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * 音乐播放器
 *
 * @author mingrisoft
 */

/*
MusicPlayer类实现了Runnable接口,并在成员属性中定义了一个线程对象,该线程对象用于启动混音器数据行的读写服务
 */
public class MusicPlayer implements Runnable {
    File soundFile; // 音乐文件
    Thread thread;// 父线程
    boolean circulate;// 是否循环播放

    /*
     * 构造方法,默认不循环播放
     *
     * @param filepath
     *            音乐文件完整名称
     * @throws FileNotFoundException
     */
    public MusicPlayer(String filepath) throws FileNotFoundException {
        this(filepath, false);
    }

    /*
     * 构造方法
     *
     * @param filepath
     *            音乐文件完整名称
     * @param circulate
     *            是否循环播放
     * @throws FileNotFoundException
     */
    public MusicPlayer(String filepath, boolean circulate)
            throws FileNotFoundException {
        this.circulate = circulate;
        soundFile = new File(filepath);
        if (!soundFile.exists()) {// 如果文件不存在
            throw new FileNotFoundException(filepath + "未找到");
        }
    }

    /*
     * 播放
     */
    public void play() {
        thread = new Thread(this);// 创建线程对象
        thread.start();// 开启线程
    }

    /*
     * 停止播放
     */
    public void stop() {
        thread.stop();// 强制关闭线程
    }

    /*
     * 重写线程执行方法
     */
    public void run() {
        byte[] auBuffer = new byte[1024 * 128];// 创建128k缓冲区
        do {
            AudioInputStream audioInputStream = null; // 创建音频输入流对象
            SourceDataLine auline = null; // 混频器源数据行
            try {
                // 从音乐文件中获取音频输入流
                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
                AudioFormat format = audioInputStream.getFormat(); // 获取音频格式

                // 按照源数据行类型和指定音频格式创建数据行对象
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

                // 利用音频系统类获得与指定 Line.Info 对象中的描述匹配的行,并转换为源数据行对象
                auline = (SourceDataLine) AudioSystem.getLine(info);

                auline.open(format);// 按照指定格式打开源数据行
                auline.start();// 源数据行开启读写活动
                int byteCount = 0;// 记录音频输入流读出的字节数
                while (byteCount != -1) {// 如果音频输入流中读取的字节数不为-1
                    // 从音频数据流中读出128K的数据
                    byteCount = audioInputStream.read(auBuffer, 0,
                            auBuffer.length);
                    if (byteCount >= 0) {// 如果读出有效数据
                        auline.write(auBuffer, 0, byteCount);// 将有效数据写入数据行中
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (UnsupportedAudioFileException e) {
                e.printStackTrace();
            } catch (LineUnavailableException e) {
                e.printStackTrace();
            } finally {
                auline.drain();// 清空数据行
                auline.close();// 关闭数据行
            }
        } while (circulate);// 根据循环标志判断是否循环播放
    }
}

③、ScoreRecorder.java

package com.mr.service;
/*
计分器模块设计
 */


import java.io.*;
import java.util.Arrays;

/*
 * 分数记录器
 *
 * @author mingrisoft
 *
 */
public class ScoreRecorder {
    private static final String SCOREFILE = "data/soure";// 得分记录文件
    private static int scores[] = new int[3];// 当前得分最高前三名

    /*
     * 分数初始化
     */
    public static void init() {
        File f = new File(SCOREFILE);// 创建记录文件
        if (!f.exists()) {// 如果文件不存在
            try {
                f.createNewFile();// 创建新文件
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;// 停止方法
        }
        FileInputStream fis = null;//文件字节
        InputStreamReader isr = null;//字符流
        BufferedReader br = null;//缓冲字符流
        try {
            fis = new FileInputStream(f);// 文件字节输入流
            isr = new InputStreamReader(fis);// 字节流转字符流
            br = new BufferedReader(isr);// 缓冲字符流
            String value = br.readLine();// 读取一行
            if (!(value == null || "".equals(value))) {// 如果不为空值
                String vs[] = value.split(",");// 分割字符串
                if (vs.length < 3) {// 如果分割结果小于3
                    Arrays.fill(scores, 0);// 数组填充0
                } else {
                    for (int i = 0; i < 3; i++) {
                        // 将记录文件中的值赋给当前分数数组
                        scores[i] = Integer.parseInt(vs[i]);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {// 依次关闭流
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /*
     * 保存分数
     */
    public static void saveScore() {
        // 拼接得分数组
        String value = scores[0] + "," + scores[1] + "," + scores[2];
        FileOutputStream fos = null;// 文件字节
        OutputStreamWriter osw = null;//字符流
        BufferedWriter bw = null;//缓冲字符流
        try {
            fos = new FileOutputStream(SCOREFILE);// 文件字节输出流
            osw = new OutputStreamWriter(fos);// 字节流转字符流
            bw = new BufferedWriter(osw);// 缓冲字符流
            bw.write(value);// 写入拼接后的字符串
            bw.flush();// 字符流刷新
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {// 依次关闭流
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
     * 添加分数。如果新添加的分数比排行榜分数高,则会将新分数记入排行榜。
     *
     * @param score
     *            新分数
     */
    static public void addNewScore(int score) {
        // 在得分组数基础上创建一个长度为4的临时数组
        int tmp[] = Arrays.copyOf(scores, 4);
        tmp[3] = score;// 将新分数赋值给第四个元素
        Arrays.sort(tmp);// 临时数组降序排列
        scores = Arrays.copyOfRange(tmp, 1, 4);// 将后三个元素赋值给得分数组
    }

    /*
     * 获取分数
     *
     * @return
     */
    static public int[] getScores() {
        return scores;
    }

}


④、Sound.java

package com.mr.service;
/*
音效工具类
 */

import java.io.FileNotFoundException;

/*
 * 音效类
 *
 * @author mingrisoft
 *
 */
public class Sound {
    static final String DIR = "music/";// 音乐文件夹
    static final String BACKGROUD = "background.wav";// 背景音乐
    static final String JUMP = "jump.wav";// 跳跃音效
    static final String HIT = "hit.wav";// 撞击音效

    /*
     * 播放跳跃音效
     */
    static public void jump() {
        play(DIR + JUMP, false);// 播放一次跳跃音效
    }

    /*
     * 播放撞击音效
     */
    static public void hit() {
        play(DIR + HIT, false);// 播放一次撞击音效
    }

    /*
     * 播放背景音乐
     */
    static public void backgroud() {
        play(DIR + BACKGROUD, true);// 循环播放背景音乐
    }

    /*
     * 播放
     *
     * @param file
     *            音乐文件完整名称
     * @param circulate
     *            是否循环播放
     */
    private static void play(String file, boolean circulate) {
        try {
            MusicPlayer player = new MusicPlayer(file, circulate);// 创建播放器
            player.play();// 播放器开始播放
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}


四、com.mr.view(视图包)

视图包类包含了BackgroundIamge(滚动背景类)、GamePanel(游戏画板类)、MainFrame(主窗体类)和ScoreDialog(成绩对话框类)

①、BackgroundImage.java

package com.mr.view;

/*
滚动背景
 */

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
/*
 * 滚动背景
 *
 * @author mingrisoft
 *
 */
public class BackgroundImage {
    public BufferedImage image;// 背景图片
    private BufferedImage image1, image2;// 滚动的两个图片
    private Graphics2D g;// 背景图片的绘图对象
    public int x1, x2;// 两个滚动图片的坐标
    public static final int SPEED = 4;// 滚动速度

    public BackgroundImage() {
        try {
            image1 = ImageIO.read(new File("image/背景.png"));
            image2 = ImageIO.read(new File("image/背景.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 主图片采用宽800高300的彩色图片
        image = new BufferedImage(800, 300, BufferedImage.TYPE_INT_RGB);
        g = image.createGraphics();// 获取主图片绘图对象
        x1 = 0;// 第一幅图片初始坐标为0
        x2 = 800;// 第二幅图片初始横坐标为800
        g.drawImage(image1, x1, 0, null);
    }
    /*
     * 滚动
     */
    public void roll() {
        x1 -= SPEED;// 第一幅图片左移
        x2 -= SPEED;// 第二幅图片左移
        if (x1 <= -800) {// 如果第一幅图片移出屏幕
            x1 = 800;// 回到屏幕右侧
        }
        if (x2 <= -800) {// 如果第二幅图片移出屏幕
            x2 = 800;// 回到屏幕右侧
        }
        g.drawImage(image1, x1, 0, null); // 在主图片中绘制两幅图片
        g.drawImage(image2, x2, 0, null);
    }
}


②、GamePanel.java

package com.mr.view;

/*
游戏面板
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import com.mr.modle.*;
import com.mr.service.*;
/*
 * 游戏面板
 *
 * @author mingrisoft
 *
 */
public class GamePanel extends JPanel implements KeyListener {
    private BufferedImage image;// 主图片
    private BackgroundImage background;// 背景图片
    private Dinosaur golden;// 恐龙
    private Graphics2D g2;// 主图片绘图对象
    private int addObstacleTimer = 0;// 添加障碍计时器
    private boolean finish = false;// 游戏结束标志
    private List<Obstacle> list = new ArrayList<Obstacle>();// 障碍集合
    private final int FREASH = FreshThread.FREASH;// 刷新时间

    int score = 0;// 得分
    int scoreTimer = 0;// 分数计时器

    public GamePanel() {
        // 主图片采用宽800高300的彩色图片
        image = new BufferedImage(800, 300, BufferedImage.TYPE_INT_BGR);
        g2 = image.createGraphics();// 获取主图片绘图对象
        background = new BackgroundImage();// 初始化滚动背景
        golden = new Dinosaur();// 初始化小恐龙
        list.add(new Obstacle());// 添加第一个障碍
        FreshThread t = new FreshThread(this);// 刷新帧线程
        t.start();// 启动线程
    }

    /*
     * 绘制主图片
     */
    private void paintImage() {
        background.roll();// 背景图片开始滚动
        golden.move();// 恐龙开始移动
        g2.drawImage(background.image, 0, 0, this);// 绘制滚动背景
        if (addObstacleTimer == 1300) {// 每过1300毫秒
            if (Math.random() * 100 > 40) {// 60%概率出现障碍
                list.add(new Obstacle());
            }
            addObstacleTimer = 0;// 重新计时
        }

        for (int i = 0; i < list.size(); i++) {// 遍历障碍集合
            Obstacle o = list.get(i);// 获取障碍对象
            if (o.isLive()) {// 如果是有效障碍
                o.move();// 障碍移动
                g2.drawImage(o.image, o.x, o.y, this);// 绘制障碍
                // 如果恐龙头脚碰到障碍
                if (o.getBounds().intersects(golden.getFootBounds())
                        || o.getBounds().intersects(golden.getHeadBounds())) {
                    Sound.hit();// 播放撞击声音
                    gameOver();// 游戏结束
                }
            } else {// 如果不是有效障碍
                list.remove(i);// 删除此障碍
                i--;// 循环变量前移
            }
        }
        g2.drawImage(golden.image, golden.x, golden.y, this);// 绘制恐龙
        if (scoreTimer >= 500) {// 每过500毫秒
            score += 10;// 加十分
            scoreTimer = 0;// 重新计时
        }

        g2.setColor(Color.BLACK);// 使用黑色
        g2.setFont(new Font("黑体", Font.BOLD, 24));// 设置字体
        g2.drawString(String.format("%06d", score), 700, 30);// 绘制分数

        addObstacleTimer += FREASH;// 障碍计时器递增
        scoreTimer += FREASH;// 分数计时器递增
    }

    /*
     * 重写绘制组件方法
     */
    public void paint(Graphics g) {
        paintImage();// 绘制主图片内容
        g.drawImage(image, 0, 0, this);
    }

    /*
     * 游戏是否结束
     *
     * @return
     */
    public boolean isFinish() {
        return finish;
    }

    /*
     * 使游戏结束
     */
    public void gameOver() {
        ScoreRecorder.addNewScore(score);// 记录当前分数
        finish = true;
    }

    /*
     * 实现按下键盘按键方法
     */
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();// 获取按下的按键值
        if (code == KeyEvent.VK_SPACE) {// 如果是空格
            golden.jump();// 恐龙跳跃
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
}

③、MainFrame.java

package com.mr.view;
/*
主窗体
 */

import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import com.mr.service.ScoreRecorder;
import com.mr.service.Sound;
/**
 * 主窗体
 * @author mingrisoft
 *
 */
public class MainFrame extends JFrame {

    public MainFrame() {
        restart();// 开始
        setBounds(340, 150, 821, 260);// 设置横纵坐标和宽高
        setTitle("奔跑吧!小恐龙!");// 标题
        Sound.backgroud();// 播放背景音乐
        ScoreRecorder.init();// 读取得分记录
        addListener();// 添加监听
        setDefaultCloseOperation(EXIT_ON_CLOSE);// 关闭窗体则停止程序
    }

    /*
     * 重新开始
     */
    public void restart() {
        Container c = getContentPane();// 获取主容器对象
        c.removeAll();// 删除容器中所有组件
        GamePanel panel = new GamePanel();// 创建新的游戏面板
        c.add(panel);
        addKeyListener(panel);// 添加键盘事件
        c.validate();// 容器重新验证所有组件,validate是一个容器类的方法,用于重新验证所有组件。在容器中添加或删除组件后,可能需要重新验证以确保它们的状态正确。
    }

    /*
     * 添加监听
     */
    private void addListener() {
        addWindowListener(new WindowAdapter() {// 添加窗体监听
            public void windowClosing(WindowEvent e) {// 窗体关闭前
                ScoreRecorder.saveScore();// 保存比分
            }
        });
    }
}


④、ScoreDialog.java

package com.mr.view;


/*
成绩对话框
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.mr.service.ScoreRecorder;
/*
 * 成绩对话框
 *
 * @author mingrisoft
 *
 */

public class ScoreDialog extends JDialog {

    /**
     * 构造方法
     *
     * @param frame
     *            父窗体
     */
    public ScoreDialog(JFrame frame) {
        super(frame, true);// 调用父类构造方法,阻塞父窗体
        int scores[] = ScoreRecorder.getScores();// 获取当前前三名成绩
        JPanel scoreP = new JPanel(new GridLayout(4, 1));// 成绩面板,4行1列
        scoreP.setBackground(Color.WHITE);// 白色背景
        JLabel title = new JLabel("得分排行榜", JLabel.CENTER);// 标题标签,居中
        title.setFont(new Font("黑体", Font.BOLD, 20));// 设置字体
        title.setForeground(Color.RED);// 红色体字
        JLabel first = new JLabel("第一名:" + scores[2], JLabel.CENTER);// 第一名标签
        JLabel second = new JLabel("第二名:" + scores[1], JLabel.CENTER);// 第二名标签
        JLabel third = new JLabel("第三名:" + scores[0], JLabel.CENTER);// 第三名标签
        JButton restart = new JButton("重新开始");// 重新开始按钮
        restart.addActionListener(new ActionListener() {// 按钮添加事件监听
            @Override
            public void actionPerformed(ActionEvent e) {// 当点击时
                dispose();// 销毁对话框
            }
        });

        scoreP.add(title);// 成绩面板添加标签
        scoreP.add(first);
        scoreP.add(second);
        scoreP.add(third);

        Container c = getContentPane();// 获取主容器
        c.setLayout(new BorderLayout());// 使用边界布局
        c.add(scoreP, BorderLayout.CENTER);// 成绩面板放中间
        c.add(restart, BorderLayout.SOUTH);// 按钮放底部

        setTitle("游戏结束");// 对话框标题

        int width, height;// 对话框宽高
        width = height = 200;// 对话框宽高均为200
        // 获得主窗体中居中位置的横坐标
        int x = frame.getX() + (frame.getWidth() - width) / 2;
        // 获得主窗体中居中位置的纵坐标
        int y = frame.getY() + (frame.getHeight() - height) / 2;
        setBounds(x, y, width, height);// 设置坐标和宽高
        setVisible(true);// 显示对话框
    }
}


五、详细文件压缩包

链接:https://pan.baidu.com/s/1T3pzn_8phHB9bPZCElVS5Q 提取码:jctb

				成                                 磨
				长                                 难						
				,                                 ,
				从                                 从
				来                                 未
				不                                 打
				是                                 倒               
				一                                 有 
				蹴                                 志      
				而                                 之
				就                                 士   

共勉!

总结:今天的分享到此接收,希望对大家有所帮助,谢谢!

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

细谈人生一载

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值