使用Java实现天天酷跑(附源码)

首先,写一个需求文档:

一、项目名称:《天天酷跑》(RunDay)

二、功能介绍:
闯关类游戏,玩家登录后,选择进入游戏,通过键盘控制玩家的上下左右移动,来躲避
障碍物和吃金币,玩家躲避的障碍物越多跑酷距离越远,玩家吃的金币越多,得分越高。

三、功能模块:
1、登录界面
用户名(输入框,明文) 密码(输入框,密文) 登录、取消按钮
2、菜单选择界面
开始游戏按钮(图片按钮) 帮助按钮 退出按钮
3、缓冲加载界面
自动加载进度条,加载完毕之后,跳转到下一界面
4、游戏主界面
移动的背景图片、动态的玩家、五种障碍物持续出现、玩家和障碍物的碰撞、
暂停、继续功能、玩家的移动功能
5、结束界面
获取玩家的得分、跑酷距离。继续游戏、返回主菜单的功能。

四、开发者:Huey
五、版本号:1.0
六、开发时间:2020.11.16

开发模式:MVC模式

M:Model(数据层),存储的是实体类。
V:View(显示层),存储的是关于界面的类。
C:Controller(控制层),存储的是相关的逻辑层代码。

企业级项目命名规范:

cn.sqc.runday.view

一、登录界面

界面功能需求图如下:

接下来我们再做一些准备工作:导入相关图片素材。

将天天酷跑的图片(Image)资源解压到桌面后,(Image文件如下图所示:)

复制到Eclipse中,单击src,直接Ctrl+V。

本文将实现cn.sqc.runday.view这一界面内容。

相关代码如下:

package cn.sqc.runday.view;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
/**
 *
 * @author Huey
 * @date 2020-11-16
 * 登录界面:用户名输入框 密码输入框 登录取消按钮 功能
 *
 */
public class LoginFrame extends JFrame{
//用户名变量(文本)
 JLabel userLabel;
//用户名输入框(文本输入框)
 JTextField userField;
//密码变量(文本)
 JLabel userLabel2;
//密码输入框(文本输入框)
 JPasswordField userField2;
//登录按钮、取消按钮(按钮)
 JButton Login,Cancel;
public LoginFrame() {//直接 alt / (无参构造)
 userLabel = new JLabel("用户名");
//设置字体
 userLabel.setFont(new Font("微软雅黑",Font.BOLD,18));
 userLabel2 = new JLabel("密 码");
 userLabel2.setFont(new Font("微软雅黑",Font.BOLD,18));
//布局方式:绝对布局
 userLabel.setBounds(20, 220, 100, 30);//x位置,y位置,所占显示空间的大小
this.add(userLabel);//将用户名这三个字添加到登录界面上,以下同理
 userLabel2.setBounds(20, 280, 100, 30);
this.add(userLabel2);
//用户名输入框
 userField = new JTextField();
 userField.setBounds(80, 220, 100, 30);
//设置输入框凹陷效果
 userField.setBorder(BorderFactory.createLoweredBevelBorder());
//设置输入框背景透明
 userField.setOpaque(false);
this.add(userField);
 userField2 = new JPasswordField();
 userField2.setBounds(80, 280, 100, 30);
 userField2.setBorder(BorderFactory.createLoweredBevelBorder());
 userField2.setOpaque(false);
this.add(userField2);
//登录按钮
 Login = new JButton("登录");
 Login.setBounds(45,350,60,36);
//Login.setBackground(new Color(44,22,44));//背景色
//Login.setForeground(Color.BLUE);//前景色
//绑定登录按钮的事件监听
 Login.addActionListener(new ActionListener() {//ActionListener alt /
@Override
public void actionPerformed(ActionEvent e) {
//System.out.println("点击登录按钮");
//获取用户名输入框的内容
 String userName = userField.getText();
 String passWord = userField2.getText();//横杠原因:方法太老了,不推荐用
if("Huey".equals(userName) && "123".equals(passWord)){
//登录成功
  JOptionPane.showMessageDialog(null, "欢迎"+userName+"来到天天酷跑游戏");
//跳转到下一界面
//关闭当前界面
  dispose();
 }else if("".equals(userName) || "".equals(passWord)){
//不能为空
  JOptionPane.showMessageDialog(null, "用户名 / 密码不能为空,请重新输入!");
 }else{
  JOptionPane.showMessageDialog(null, "用户名 / 密码输入错误,请重新输入!");
 }
 }
 });
this.add(Login);
//取消按钮
 Cancel = new JButton("取消");
 Cancel.setBounds(135,350,60,36);
this.add(Cancel);
 Cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
 dispose();
 }
 });
//创建背景面板,并添加到窗体上去
 LoginPanel panel = new LoginPanel();
this.add(panel);
//设置登录界面的基本属性
this.setSize(900,530);
this.setLocationRelativeTo(null);//位置居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setUndecorated(true);
//设置窗体的Logo图标
this.setIconImage(new ImageIcon("Image/115.png").getImage());//存储图片
this.setVisible(true);
 }
//测试用的main方法 main + Alt /
public static void main(String[] args) {
new LoginFrame();
 }
class LoginPanel extends JPanel{//画板
//背景图片变量
 Image background;//------ctr shift + o 导包
public LoginPanel() {//-----alt / 回车 构造方法 在{后双击,显示作用域
//读取图片文件,赋值给background变量
try {//-----虽然不大可能,但也做好吃饭噎死的准备
 background = ImageIO.read(new File("Image/login.jpg"));//----read参数为File类型
 } catch (IOException e) {//-------捕获异常信息
// 打印异常日志信息
 e.printStackTrace();
 }
 }
//绘制方法
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制背景图片
 g.drawImage(background, 0, 0,900,530, null);//900,530为宽高
 }
 }
}
//throws ......抛异常,将下面的异常向上抛,交给上级:不建议

为了更清楚地看出代码结构,这里给出部分代码的作用域。

LoginFrame作用域一直到最后一个}

LoginPanel的代码块:

运行结果截图:

1.界面

2.登录

2.1、用户名及密码输入为空的情况:

2.2、用户名或密码输入错误的情况:


2.3、用户名及密码输入正确的情况:


单击弹窗中的“确定”,直接退出。

3.退出

点“取消”即可

二、开始游戏界面

前文,我们完成了登录界面的搭建。接下来将完成开始游戏界面的搭建,并建立起登录界面与开始游戏界面的桥梁。
实现在输对用户名和密码后即可进入开始游戏界面的功能。

界面功能需求图:

具体要求:

当鼠标移入开始游戏按钮后,按钮将由暗变亮,鼠标移开后,按钮又由亮变暗。

帮助、离开按钮同理。

另外,当点击离开时,需要实现关闭当前界面的效果。

上代码:

package cn.sqc.runday.view;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import cn.sqc.runday.controller.WindowFrame;

public class MainFrame extends JFrame implements MouseListener {
 //设置窗体的基本属性 大小
 /**
 * 1.1、设置窗体基本属性大小 居中 边框隐藏 默认关闭按钮 logo图标
 1.2、创建背景面板MainPanel,实现背景图片功能

 2.图片按钮功能
 */
 //2.1创建开始按钮 帮助按钮 离开按钮 组件
 JLabel start,help,exit;

 JPanel MainPanel;

 public MainFrame() {//无参构造,创建对象。并在main函数中调用
 //2.2
 start = new JLabel(new ImageIcon("Image/hh1.png"));//ImageIcon:图标
 start.setBounds(350,320,150,40);
 start.setEnabled(false);//false按钮为灰色
 start.addMouseListener(this);
 this.add(start);

 help = new JLabel(new ImageIcon("Image/hh2.png"));
 help.setBounds(350,420,150,40);
 help.setEnabled(false);
 help.addMouseListener(this);
 this.add(help);

 exit = new JLabel(new ImageIcon("Image/hh3.png"));
 exit.setBounds(350, 520, 150, 40);
 exit.setEnabled(false);
 exit.addMouseListener(this);
 this.add(exit);

 /**1.实现背景图片及窗体属性*/
 MainPanel panel = new MainPanel();
 this.add(panel);

 //设置窗体基本属性大小 居中 边框隐藏 默认关闭按钮 logo图标
 this.setSize(1200,730);//大小
 this.setLocationRelativeTo(null);//居中
 this.setUndecorated(true);//边框隐藏
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//默认关闭
 this.setIconImage(new ImageIcon("Image/115.png").getImage());//logo
 this.setVisible(true);
 }

 public static void main(String[] args) {
 new MainFrame();
 }

 //2、创建背景面板MainPanel,实现背景图片功能
 class MainPanel extends JPanel{//创建的MainPanel类,在MainFrame中调用
 Image background;
 public MainPanel() {
 try {
 background = ImageIO.read(new File("Image/main.png"));
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 @Override
 public void paint(Graphics g) {
 super.paint(g);
 g.drawImage(background, 0, 0,1200,730, null);
 }
 }

//以下五个方法均为添加 implements MouseListener 后,快捷出来的
 @Override
 public void mouseClicked(MouseEvent e) {
 //鼠标点击
 if(e.getSource().equals(start)){
 //跳转到下一界面
 new WindowFrame().Start();
 //关闭当前界面
 //dispose();
 }else if(e.getSource().equals(exit)){
 dispose();
 }else if(e.getSource().equals(help)){
 JOptionPane.showMessageDialog(null, "有疑问请联系开发者:Huey");
 }

 }
 @Override
 public void mousePressed(MouseEvent e) {
 // TODO Auto-generated method stub

 }
 @Override
 public void mouseReleased(MouseEvent e) {
 // TODO Auto-generated method stub

 }
 @Override
 public void mouseEntered(MouseEvent e) {
 // 鼠标移入
 if(e.getSource().equals(start)){//e指一个事件。e.getSource()获取事件
 //如果鼠标移入到(start)组件(图片按钮)
 start.setEnabled(true);
 }else if(e.getSource().equals(help)){
 help.setEnabled(true);
 }else if(e.getSource().equals(exit)){
 exit.setEnabled(true);
 }
 }
 @Override
 public void mouseExited(MouseEvent e) {
 //鼠标移出
 if(e.getSource().equals(start)){
 start.setEnabled(false);
 }else if(e.getSource().equals(help)){
 help.setEnabled(false);
 }else if(e.getSource().equals(exit)){
 exit.setEnabled(false);
 }
 }
}

测试:

先填补上文的缺憾,加上new MainFrame();语句。调用我们刚刚写好的开始游戏界面。

登录界面:

单击确定

完美进入我们写好的登录游戏界面:

现在看开始游戏按钮:

帮助按钮:

点击帮助按钮:

退出按钮:

点击:

大功告成!

三、缓冲加载游戏界面

前文,我们完成了开始游戏界面的搭建。接下来将实现缓冲加载界面的搭建。并搭建与前面俩界面间的桥梁。
实现输入正确用户名密码后,进入开始游戏界面,点击开始游戏按钮后,进入缓冲加载界面的功能。

界面示意图:

具体要求:

  • 缓存加载界面:背景图片、进度条
  • 动态加载过程。(线程)

我们想要实现动态的缓冲加载过程,让进度条动起来,就需要引入线程的概念了。 线程:

Thread类中这样定义:

线程是程序中执行的线程,Java虚拟机允许程序同时运行多个执行线程。

举个例子,你用百度网盘下载一部电影,这就是一个线程。而如果你同时下载多部电影,这就是多线程了。

1.线程有6种状态:新建,运行,阻塞,等待,计时等待和终止。

新建:当使用new操作符创建新线程时,线程处于“新建”状态。
运行(可运行):调用start()方法。

阻塞:当线程需要获得对象的内置锁,而该锁正在被其他线程拥有。
等待:当线程等待其他线程通知调度表可以运行时。
计时等待:对于一些含有时间参数的方法,如Thread类的sleep() 。
终止:当run()方法运行完毕或出现异常时。

2.创建线程的两种方式:

1、实现Runnable
2、实现Thread类

直接上代码:

package cn.sqc.runday.controller;

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

/**
 *
 * @author Huey
 * @date 2020-11-18
 * 缓存加载界面:背景图片、进度条
 * 动态加载过程。(线程)
 *
 */
public class WindowFrame extends JFrame implements Runnable{
 JLabel background;
 //进度条
 JProgressBar jdt;

 //创建一个线程并启动
 public void Start(){
 WindowFrame frame = new WindowFrame();
 Thread t = new Thread(frame);//t代表线程
 //启动线程
 t.start();
 dispose();
 }
 public WindowFrame() {
 background = new JLabel(new ImageIcon("Image/hbg.jpg"));
 this.add(BorderLayout.NORTH,background);//放在窗口上面
 jdt = new JProgressBar();
 jdt.setStringPainted(true);//加载以字符串形式呈现出来。0%
 jdt.setBackground(Color.ORANGE);
 this.add(BorderLayout.SOUTH,jdt);
 //大小 568 * 340
 this.setSize(568,340);
 this.setLocationRelativeTo(null);
 this.setDefaultCloseOperation(3);
 this.setUndecorated(true);
 this.setIconImage(new ImageIcon("Image/115.png").getImage());
 this.setVisible(true);
 }
 public static void main(String[] args) {
 new WindowFrame().Start();
 }
 @Override
 public void run() {
 //启动线程后,线程具体执行的内容
 int [] values = {0,1,3,10,23,32,40,47,55,66,76,86,89,95,99,99,99,100};
 for(int i=0; i<values.length; i++){//循环遍历赋值
 jdt.setValue(values[i]);
 //线程休眠
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }//200毫秒
 }
 }

}

加载界面代码敲完,现在开始造桥。

现在,我们从第一个登录界面开始测试。

点击开始游戏:

非静止画面……

成功实现!

四、游戏主界面

接上文,接下来将实现游戏主界面,功能如下:

移动的背景图片、动态的玩家、玩家的移动功能、
五种障碍物持续出现、玩家和障碍物的碰撞、
暂停、继续功能。

首先,看一下整体效果:

动图实在太大,几秒钟的 Gif 就十几兆了。无奈,图片展示效果。

跳跃、得分、下落、障碍物:

碰到障碍物后,玩家被推着走。

下面,分别解释一下每个功能的逻辑:

1、创建一个显示窗体,承载游戏的主面板类。

GameFrame.java

package cn.sqc.runday.view;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

import cn.sqc.runday.controller.GamePanel;

/**
 * @author Huey
 *2020-11-27 下午12:40:22
 * 游戏主界面:显示窗体,承载游戏的主面板类
 */

public class GameFrame extends JFrame {
 //设置窗体宽高属性
 public static final int WIDTH=1500;
 public static final int HEIGHT=900;
 public GameFrame() {
 //2.4创建游戏面板对象,并添加到窗体上去
 GamePanel panel = new GamePanel();
 panel.action();//程序启动的方法
 this.addKeyListener(panel);//谁实现就监听谁
 this.add(panel);

 /**1.设置窗体基本属性*/
 this.setSize(WIDTH,HEIGHT);
 this.setLocationRelativeTo(null);
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.setIconImage(new ImageIcon("Image/115.png").getImage());
 this.setUndecorated(true);
 this.setVisible(true);
 }

 public static void main(String[] args) {
 new GameFrame();
 }
}

2、游戏主面板类(核心逻辑类): 背景图片滚动效果

使用两张背景图片,实现背景图片滚动效果的逻辑如下:

下面用视频演示一下:

玩家动态效果

我国早期很有名的一部动画片《大闹天宫》,由于当时没有电脑,所以需要一帧一帧的画,随后快速播放图片,形成动态的画面(我愿称之:真·动画),并为之配音,短短10分钟的动画却要画7000到10000张原画!

而此处,我们的玩家的奔跑姿态,同理是由九张图片构成。

下面动图演示:

下面是实现玩家的(生成、移动、绘制)的基本代码,后面的障碍物的实现,也都遵循这一编写逻辑。

为更方便读懂代码,已尽力注释,若仍有不清楚的地方,欢迎留言交流。

Person.java

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 * @date 2020-11-23
 * 玩家的实体类
 */
public class Person {//1.声明属性
 private Image image;//1.1 玩家当前显示图片
 private Image[] images;//1.2 玩家所有图片

 public static final int WIDTH = 120;//1.3玩家宽高
 public static final int HEIGHT = 120;

 //1.4玩家初始位置坐标
 private int x,y;
 int index;//下面用作切换图片
 //玩家得分
 private int score;
 //玩家跑酷距离
 private int distance;

 public Person() {//2.赋值
 //给图片数组images赋值
 init();//2.1 先写,会提示要不要实现!自动生成方法
 //默认当前显示图片位第一张图片 2.6
 image = images[0];

 x = 90;//2.7
 y = 580;//脚踩地板
 index = 0;
 score = 0;
 distance = 0;
 }
 //玩家自由下落方法5.1
 public void drop() {
 y += 5;
 if(y>=580){// 下落归下落,也得温柔点,不能让小人儿踩破了地板
 y = 580;
 }
 }
 //玩家移动的方法
 public void step(){
 //玩家图片的切换
 image = images[index ++ /3%images.length];
 //玩家坐标改变(玩家坐标通过键盘控制,此次不做处理)
 }
 //绘制玩家的方法
 public void paintPerson(Graphics g){
 g.drawImage(image, x, y, WIDTH, HEIGHT, null);
 }

 //判断玩家是否越界的方法
 public boolean outOfBounds(){
 return this.x >= GameFrame.WIDTH || this.x <= -WIDTH;
 }
 private void init() {//2.2
 images = new Image[9];
 for(int i = 0; i<images.length; i++){//2.3
 try {//2.5
 images[i] = ImageIO.read(new File("Image/"+(i+1) + ".png"));//2.4
 } catch (IOException e) {//2.5
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 }
//2.8 右键,Source,GGAS
 public Image getImage() {
 return image;
 }

 public void setImage(Image image) {
 this.image = image;
 }

 public Image[] getImages() {
 return images;
 }

 public void setImages(Image[] images) {
 this.images = images;
 }

 public int getX() {
 return x;
 }

 public void setX(int x) {
 this.x = x;
 }

 public int getY() {
 return y;
 }

 public void setY(int y) {
 this.y = y;
 }

 public static int getWidth() {
 return WIDTH;
 }

 public static int getHeight() {
 return HEIGHT;
 }
 public int getIndex() {
 return index;
 }
 public void setIndex(int index) {
 this.index = index;
 }
 public int getScore() {
 return score;
 }
 public void setScore(int score) {
 this.score = score;
 }
 public int getDistance() {
 return distance;
 }
 public void setDistance(int distance) {
 this.distance = distance;
 }

}

3、几种障碍物的出现 障碍物一:螃蟹

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Paint;
import java.io.File;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_1 {
 private Image image;
 private Image [] images;
 public static final int WIDTH=100;
 public static final int HEIGHT=110;
 private int x,y;
 int index;
 private int speed;

 public Barrs_1() {// 螃蟹!
 images = new Image[2];
 try {
 images[0]=ImageIO.read(new File("image/a2.png"));
 images[1]=ImageIO.read(new File("image/a4.png"));
 } catch (Exception e) {
 // TODO: handle exception
 }
 image = images[0];
 x=GameFrame.WIDTH+100;
 y=580;
 speed =30;
 index = 0;
 }

 public void step() {//切换图片
 image =images[index++/5%images.length];
 x-=speed;//切换图片实现螃蟹爪子张合的动态效果的同时,使其向左移动
 }
 public void paintBarrs(Graphics g) {
 g.drawImage(image, x,y,WIDTH,HEIGHT, null);
}
 public boolean outofBounds(){
 return this.x <=-WIDTH;
 }
public Image getImage() {
 return image;
}
public void setImage(Image image) {
 this.image = image;
}
public Image[] getImages() {
 return images;
}
public void setImages(Image[] images) {
 this.images = images;
}
public int getX() {
 return x;
}
public void setX(int x) {
 this.x = x;
}
public int getY() {
 return y;
}
public void setY(int y) {
 this.y = y;
}
public int getIndex() {
 return index;
}
public void setIndex(int index) {
 this.index = index;
}
public int getSpeed() {
 return speed;
}
public void setSpeed(int speed) {
 this.speed = speed;
}
public static int getWidth() {
 return WIDTH;
}
public static int getHeight() {
 return HEIGHT;
}

}

需要注意的是,在创建后,记得添加set、get方法。以便在面板类中对其障碍物进行操作。

障碍物二:宠物

与其称之障碍物,不如说它是个跟着玩家的小跟班。


package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_2{ // 宠物!
 private Image image;
 private Image images [] ;
 public static final int WIDTH= 70;
 public static final int HEIGHT = 60;
 private int x,y;
 int index;
 public Barrs_2() {
 init();
 image = images[0];
 x=300;
 y=460;
 }
 public void drop() {
 y ++;
 if(y>=460){
 y = 460;
 }
 }
 public void step(){
 image = images[index++/2%images.length];
 }
 public void paintBarrs(Graphics g) {
 g.drawImage(image, x,y,WIDTH,HEIGHT, null);
 }
 public boolean outofBounds() {
 return this.x<=-WIDTH;
 }
public void init(){
 images = new Image[6];
 for( int i=0;i<6;i++){
 try {
 images[i]=ImageIO.read(new File ("Image/"+"d"+(i+1)+".png"));
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
}
public Image getImage() {
 return image;
}
public void setImage(Image image) {
 this.image = image;
}
public Image[] getImages() {
 return images;
}
public void setImages(Image[] images) {
 this.images = images;
}
public int getX() {
 return x;
}
public void setX(int x) {
 this.x = x;
}
public int getY() {
 return y;
}
public void setY(int y) {
 this.y = y;
}
public int getIndex() {
 return index;
}
public void setIndex(int index) {
 this.index = index;
}
public static int getWidht() {
 return WIDTH;
}
public static int getHeight() {
 return HEIGHT;
}

}

障碍物三、导弹

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_3 {// 导弹!
 private Image image;
 private int x,y;
 public static final int WIDTH = 150;
 public static final int HEIGHT=70;
 private int speed;
 public Barrs_3() {
 try {
 image = ImageIO.read(new File("image/daodan.png"));
 } catch (Exception e) {
 // TODO: handle exception
 }
 x=GameFrame.WIDTH+1000;
 y=450;
 speed = 25 ;
 }
 public void step(){
 x-=speed;
 }
 public void paintBarrs(Graphics g) {
 g.drawImage(image, x, y, WIDTH, HEIGHT, null);

 }
 public boolean outofBounds(){
 return this.x<=-WIDTH;
 }
 public Image getImage() {
 return image;
 }
 public void setImage(Image image) {
 this.image = image;
 }
 public int getX() {
 return x;
 }
 public void setX(int x) {
 this.x = x;
 }
 public int getY() {
 return y;
 }
 public void setY(int y) {
 this.y = y;
 }
 public int getSpeed() {
 return speed;
 }
 public void setSpeed(int speed) {
 this.speed = speed;
 }
 public static int getWidth() {
 return WIDTH;
 }
 public static int getHeight() {
 return HEIGHT;
 }
}

障碍物四:鱼叉等障碍物

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.util.Random;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

public class Barrs_4 {// 鱼叉障碍物!
 private Image image;
 private Image images[];
 public static final int WIDTH =150;
 public static final int HEIGHT =350;
 private int x,y;

 public Barrs_4() {//构造方法
 Random random = new Random();
 images = new Image[4] ;
 try {
 images[0] = ImageIO.read(new File("image/11.png"));
 images[1]= ImageIO.read(new File("image/12.png"));
 images[2]= ImageIO.read(new File("image/13.png"));
 images[3]= ImageIO.read(new File("image/14.png"));
 } catch (Exception e) {
 // TODO: handle exception
 }
 image= images[random.nextInt(4)];
 x=GameFrame.WIDTH+1500;
 y=0;
 }
 public void step(){
 x-=20;
 }
 public void paintBarrs(Graphics g){
 g.drawImage(image, x, y, WIDTH, HEIGHT, null);
 }
 public boolean outofBounds(){
 return this.x<=-WIDTH;
 }
 public Image getImage() {
 return image;
 }
 public void setImage(Image image) {
 this.image = image;
 }
 public Image[] getImages() {
 return images;
 }
 public void setImages(Image[] images) {
 this.images = images;
 }
 public int getX() {
 return x;
 }
 public void setX(int x) {
 this.x = x;
 }
 public int getY() {
 return y;
 }
 public void setY(int y) {
 this.y = y;
 }
 public static int getWidth() {
 return WIDTH;
 }
 public static int getHeight() {
 return HEIGHT;
 }

}

障碍物五、金币

在此,暂且先不写金币的动态效果。

package cn.sqc.runday.model;

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 *2020-11-30 下午03:44:51
 *金币障碍物类
 *
 */
public class Barrs_5 {
 private Image image;//当前显示图片
 public static final int WIDTH = 30;
 public static final int HEIGHT = 30;
 private int x,y;
 private int speed;
 Random random = new Random();
 public Barrs_5() {
 try {
 image = ImageIO.read(new File("Image/"+(random.nextInt(6) + 21) + ".png"));
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 x = GameFrame.WIDTH + 10;
 y = random.nextInt(600);
 speed = 20;
 }

 public void step(){
 x -= speed;
 }

 public void paintBarrs(Graphics g){
 g.drawImage(image, x, y, WIDTH, HEIGHT, null);
 }
 public boolean outofBounds() {
 return this.x<=-WIDTH;
 }

 public Image getImage() {
 return image;
 }

 public void setImage(Image image) {
 this.image = image;
 }

 public int getX() {
 return x;
 }

 public void setX(int x) {
 this.x = x;
 }

 public int getY() {
 return y;
 }

 public void setY(int y) {
 this.y = y;
 }

 public int getSpeed() {
 return speed;
 }

 public void setSpeed(int speed) {
 this.speed = speed;
 }

 public Random getRandom() {
 return random;
 }

 public void setRandom(Random random) {
 this.random = random;
 }

 public static int getWidth() {
 return WIDTH;
 }

 public static int getHeight() {
 return HEIGHT;
 }

}

4、玩家和障碍物的碰撞逻辑

以玩家与导弹的碰撞举例:

for(int i = 0;i<barrs3.length;i++){
 if(person.getX() + Person.WIDTH >= barrs3[i].getX() &&
 person.getX() <= barrs3[i].getX() + Barrs_3.WIDTH &&
 person .getY() +Person.getHeight() >= barrs3[i].getY() &&
 person.getY() <= barrs3[i].getY () + Barrs_3.HEIGHT){
 if(person.getX() + Person.WIDTH <= barrs3[i].getX() + Barrs_3.WIDTH){//玩家的宽度(120px)是比障碍物小的
 //左碰撞
 person.setX(barrs3[i].getX() - Barrs_3.WIDTH);
 }else{
 //右碰撞
 person.setX(barrs3[i].getX()+ Barrs_3.WIDTH );
 }
 }
 }

以下动图演示了玩家从右边与障碍物b发生碰撞和从左边碰撞的逻辑,上下碰撞同理。

上下左右碰撞的逻辑代码,在动图下方:

5、暂停、继续逻辑

在监听键盘按键的方法中。

代码如下:

此处的 flag 来源于上面程序启动的方法中,不难看出只要按了空格键,就能实现生成、移动、绘制方法的暂停,也就相当于画面的静止、游戏的暂停!

6、结束逻辑

游戏主界面代码如下:

package cn.sqc.runday.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import cn.sqc.runday.model.Barrs_1;
import cn.sqc.runday.model.Barrs_2;
import cn.sqc.runday.model.Barrs_3;
import cn.sqc.runday.model.Barrs_4;
import cn.sqc.runday.model.Barrs_5;
import cn.sqc.runday.model.Person;
import cn.sqc.runday.view.EndFrame;
import cn.sqc.runday.view.GameFrame;

/**
 * @author Huey
 *2020-11-27 下午12:28:44
 * 游戏主面板类,核心逻辑类
 *  1、背景图片滚动效果
 *  2、玩家动态效果
 *  3、五种障碍物的出现
 *  4、玩家和障碍物的碰撞逻辑
 *  5、暂停、继续逻辑
 *  6、结束逻辑
 */

public class GamePanel extends JPanel implements KeyListener{
 /**2、生成动态的背景图片***/
 //2.1声明背景图片对象
 Image background;
 Image score;
 Image pause;//暂停
 Image proceed;//继续.

 /***3.实现玩家的动态效果和移动功能***/
 //3.1创建玩家对象(类的实例化)
 Person person;
 Barrs_2 barrs_2;//宠物
 Barrs_4 barrs_4;//鱼钩等障碍物
 Barrs_5 barrs_5;//金币
 /**4.实现螃蟹障碍物*/
 //4.1
 Barrs_1[]barrs1 = {};//存储螃蟹数组(没有元素,可以扩容)
 Barrs_3[]barrs3 ={};//导弹
 Barrs_4[]barrs4={};//鱼钩
 Barrs_5[]barrs5 = {};//金币

 public GamePanel() {
 //3.2
 person = new Person();//调用Person类的构造方法,创建对象并赋值
 barrs_2 = new Barrs_2();
 //2.2读取图片文件
 try{
 background =ImageIO.read(new File("Image/cc.png"));//跑酷背景
 score =ImageIO.read(new File("Image/a12.png"));//得分背景
 pause = ImageIO.read(new File("Image/b2.png"));
 proceed = ImageIO.read(new File("Image/b1.png"));
 }catch(IOException e){
 e.printStackTrace();
 }
 }
 //2.5
 int x=0;//背景图片初始位置
@Override
public void paint(Graphics g) {
 super.paint(g);
 //2.7
 if(flag){
 x-=20;//图片滚动的速度
 }
 //2.3绘制背景图片(动态切换很流畅)
 g.drawImage(background, x, 0, GameFrame.WIDTH, GameFrame.HEIGHT, null);
 g.drawImage(background, x+GameFrame.WIDTH, 0, GameFrame.WIDTH, GameFrame.HEIGHT,null);
 if(x<=-GameFrame.WIDTH){//实现两张图片之间的切换
 x = 0;
 }

 //3.3绘制 玩家
 person.paintPerson(g);
 //绘制螃蟹
 for(int i =0;i<barrs1.length;i++){
 barrs1[i].paintBarrs(g);
 }
 //绘制宠物
 barrs_2.paintBarrs(g);
 //绘制导弹
 for(int i =0;i<barrs3.length;i++){
 barrs3[i].paintBarrs(g);
 }
 //随机绘制鱼钩障碍物
 for(int i =0;i<barrs4.length;i++){
 barrs4[i].paintBarrs(g);
 }
 //随机绘制金币
 for(int i = 0;i<barrs5.length;i++){
 barrs5[i].paintBarrs(g);
 }

//位置越往下,图层越往上
 //绘制玩家分数
 g.drawImage(score, 120, 50,null);
 g.setColor(Color.ORANGE);
 g.setFont(new Font("宋体",Font.BOLD,30 ));
 g.drawString("玩家得分:"+person.getScore()+"分", 133, 95);

 //绘制暂停、继续标识图片
 if(flag){
  g.drawImage(proceed, 200, 800, 90,90,null);
 }else{
 g.drawImage(pause, 200, 800, 90, 90, null);
 }

}

//生 成 障 碍 物 的 方 法
int index =0;
public void enteredAction(){//实现源源 不 断 生成障碍物的效果
 index++;
 //生成螃蟹障碍物
 if(index%100==0){
 //生成一个螃蟹
 Barrs_1 b1 = new Barrs_1();
 Barrs_3 b3 = new Barrs_3();
 Barrs_4 b4 = new Barrs_4();

 barrs1 =Arrays.copyOf(barrs1,barrs1.length+1);//数组扩容
 barrs1[barrs1.length-1]= b1;//放到数组最后一个元素的位置
 //System.out.println("测试"+barrs1.length);
 barrs3 =Arrays.copyOf(barrs3,barrs3.length+1);
 barrs3[barrs3.length-1]= b3;
 barrs4 =Arrays.copyOf(barrs4,barrs4.length+1);
 barrs4[barrs4.length-1]= b4;
 }
 if(index%15==0){
 Barrs_5 b5 = new Barrs_5();
 barrs5 = Arrays.copyOf(barrs5, barrs5.length +1);
 barrs5[barrs5.length-1] = b5;
 }
}

//移 动 方 法
public void stepAction(){
 //3..4
 person.step();//切换玩家的图片—>动起来
 person.drop();//不断下坠
 barrs_2.drop();
 //螃蟹障碍物移动
 for(int i =0;i<barrs1.length;i++){
 barrs1[i].step();
 //判断当前障碍物是否 越界,并做越界处理
 if(barrs1[i].outofBounds()){
 //删除越界的螃蟹障碍物
 barrs1[i] = barrs1[barrs1.length - 1];//将螃蟹数组最后一个元素,赋给越界的螃蟹,覆盖了,相当于间接删除了。
 barrs1= Arrays.copyOf(barrs1, barrs1.length - 1);//数组缩容
 }
 }

 barrs_2.step();

 for(int i =0;i<barrs3.length;i++){
 barrs3[i].step();
 //删除越界的导弹障碍物
 if(barrs3[i].outofBounds()){
 barrs3[i] = barrs3[barrs3.length - 1];
 barrs3 = Arrays.copyOf(barrs3, barrs3.length - 1);
 }
 }

 for(int i =0;i<barrs4.length;i++){
 barrs4[i].step();
 //删除越界的鱼叉障碍物
 if(barrs4[i].outofBounds()){
 barrs4[i] = barrs4[barrs4.length - 1 ];
 barrs4 = Arrays.copyOf(barrs4, barrs4.length - 1);
 }
 }
 for(int i = 0;i<barrs5.length;i++){
 barrs5[i].step();
 if(barrs5[i].outofBounds()){
 //删除越界的金币
 barrs5[i] = barrs5[barrs5.length - 1];
 barrs5 = Arrays.copyOf(barrs5, barrs5.length - 1);
 }
 }
}

//玩家和障碍物碰撞的处理方法
public void pengAction(){
 //判断玩家是否和螃蟹障碍物进行碰撞
 for(int i = 0;i<barrs1.length;i++){//上下左右都写了,下是用不到的
 if(person.getX() + Person.WIDTH >= barrs1[i].getX() &&
 person.getX() <= barrs1[i].getX() + Barrs_1.WIDTH &&
 person .getY() +Person.getHeight() >= barrs1[i].getY() &&
 person.getY() <= barrs1[i].getY () + Barrs_1.HEIGHT){
 //碰撞后的处理(遮挡类障碍物)
 if(person.getX() + Person.WIDTH <= barrs1[i].getX() + Barrs_1.WIDTH){//防止人在右边,碰撞后可以穿过障碍物
 //左碰撞
 person.setX(barrs1[i].getX() - Barrs_1.WIDTH);
 }else{
 //右碰撞
 person.setX(barrs1[i].getX()+ Barrs_1.WIDTH );
 }
 }
 }
 //判断玩家是否和导弹障碍物进行碰撞
 for(int i = 0;i<barrs3.length;i++){
 if(person.getX() + Person.WIDTH >= barrs3[i].getX() &&
 person.getX() <= barrs3[i].getX() + Barrs_3.WIDTH &&
 person .getY() +Person.getHeight() >= barrs3[i].getY() &&
 person.getY() <= barrs3[i].getY () + Barrs_3.HEIGHT){
 if(person.getX() + Person.WIDTH <= barrs3[i].getX() + Barrs_3.WIDTH){//玩家的宽度(120px)是比障碍物小的
 //左碰撞
 person.setX(barrs3[i].getX() - Barrs_3.WIDTH);
 }else{
 //右碰撞
 person.setX(barrs3[i].getX()+ Barrs_3.WIDTH );
 }
 }
 }
 //判断玩家是否和鱼叉障碍物进行碰撞
 for(int i = 0;i<=barrs4.length -1;i++){//小心数组越界!
 if(person.getX() + Person.WIDTH >= barrs4[i].getX() &&
 person.getX() <= barrs4[i].getX() + Barrs_4.WIDTH &&
 person.getY() + Person.HEIGHT >= barrs4[i].getY() &&
 person.getY() <= barrs4[i].getY() + Barrs_4.HEIGHT ){
 if(person.getX() + Person.WIDTH <= barrs4[i].getX() + Barrs_4.WIDTH ){
 //左碰撞
 person.setX(barrs4[i].getX() - Barrs_4.WIDTH);
 }else{
 //右碰撞
 person.setX(barrs4[i].getX()+ Barrs_4.WIDTH );
 }
 }
 }
 //玩家和金币的碰撞
 for(int i = 0;i<barrs5.length;i++){
 if(person.getX() + Person.WIDTH >= barrs5[i].getX() &&
 person.getX() <= barrs5[i].getX() + Barrs_5.WIDTH &&
 person .getY() +Person.getHeight() >= barrs5[i].getY() &&
 person.getY() <= barrs5[i].getY () + Barrs_5.HEIGHT){//判断玩家与金币的碰撞
 if(person.getX() + Person.WIDTH <= barrs5[i].getX() + Barrs_5.WIDTH){
 //删除当前金币
 barrs5[i] = barrs5[barrs5.length - 1];
 barrs5 = Arrays.copyOf(barrs5, barrs5.length - 1);

 //玩家加分
 int score = person.getScore();
 person.setScore(score + 10);
 }
 }
 }

}
//结束逻辑
 public void gameOverAction(){
 if(person.outOfBounds()){
 //程序结束
 isGameOver = true;
 //传递数据(创建结束界面)
 new EndFrame(person);//面向对象思想
 //数据清空
 person = new Person();
 barrs1 = new Barrs_1[]{};
 barrs3 = new Barrs_3[]{};
 }

 }
 public static boolean isGameOver = false;
 boolean flag = true;
//2.8 创 建 一 个 程 序 启 动 的 方 法
public void action(){
 new Thread(){//匿名内部类
 //重写run方法
 public void run() {
 while(!isGameOver){
 //3.4
 if(flag){
  enteredAction();//细节:只有先生成了障碍物后,下面才能调用移动障碍物的方法
  stepAction();
  pengAction();//玩家和障碍物碰撞
  gameOverAction();

 }
 //重绘方法
 repaint();
 //线程休眠
 try {
  Thread.sleep(60);
 } catch (Exception e) {
  // TODO: handle exception
  e.printStackTrace();
 }
 }

 };
 }.start();//创建一个线程并启动

 }

@Override
public void keyTyped(KeyEvent e) {
 // TODO Auto-generated method stub

}

@Override
public void keyPressed(KeyEvent e) {
 //获取玩家当前位置坐标
 int x = person.getX();
 int y = person.getY();
 int x1 = barrs_2.getX();
 int y1 = barrs_2.getY();

 //上
 if(e.getKeyCode() == KeyEvent.VK_UP && y > 10 && y1 > 10){
 person.setY(y-25);
 barrs_2.setY(y-25);
 }
 //下
 if(e.getKeyCode()== KeyEvent.VK_DOWN && y<=560 && y1<560){
 person.setY(y+30);
 barrs_2.setY(y-30);
 }
 //左
 if(e.getKeyCode()==KeyEvent.VK_LEFT && x>=0 ){
 person.setX(x-30);
 barrs_2.setX(x1-30);

 }
 //右
 if(e.getKeyCode()==KeyEvent.VK_RIGHT){
 person.setX(x+22);
 barrs_2.setX(x1+22);
 if(x>=GameFrame.WIDTH-Person.WIDTH){//如果人物到了右边界
 person.setX(GameFrame.WIDTH-Person.WIDTH);
 }
 if(x1>=GameFrame.WIDTH-barrs_2.WIDTH){//如果宠物到了右边界
 barrs_2.setX(GameFrame.WIDTH - barrs_2.WIDTH);
 }
 }
 //暂停 继续功能
 if(e.getKeyCode() == KeyEvent.VK_SPACE){
 flag = !flag;
 }

 }

@Override
public void keyReleased(KeyEvent e) {
 // TODO Auto-generated method stub
}
}

五、结束界面

接上文,接下来将实现天天酷跑游戏的结束界面,功能如下:

跑酷距离、获取玩家的得分。
再来一次、返回主菜单、直接退出。

具体啥样子,先睹为快!

点击再来一次按钮,进入加载状态,加载结束,直接进入游戏。

点击主菜单按钮,进入主菜单界面:

1、跑酷距离

我是在Person类的玩家移动方法中,添加了一个自增的diatance,只要玩家的图片还在切换,也就是游戏还没有结束,这个distance都在自增,也算是一种间接的实现计算跑酷距离的方法。

通过在Person类中添加get、set方法,获取数据。

2、获取玩家的得分

玩家与金币碰撞的得分即为图中的表现分,在GamePanel 获取。

而总分,我在Person类中,设定了一个简单的计分规则:

3、再来一次

在鼠标点击事件内,new一个新的加载界面,加载完成后自动进入游戏。

4、返回主界面

同理。

5、直接退出

同理。

上代码

EndFrame.java

package cn.sqc.runday.view;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import cn.sqc.runday.controller.GamePanel;
import cn.sqc.runday.model.Person;

public class EndFrame extends JFrame implements MouseListener {
 //创建继续游戏按钮、返回主菜单按钮、退出按钮 组件
 JLabel again,back,exit;

 public EndFrame(Person person) {
 again = new JLabel(new ImageIcon("Image/hh5.png"));
 again.setBounds(520, 622, 60, 25);
 again.addMouseListener(this);
 this.add(again);
 back = new JLabel(new ImageIcon("Image/hh6.png"));
 back.setBounds(520, 722, 60, 25);
 back.addMouseListener(this);
 this.add(back);
 exit = new JLabel(new ImageIcon("Image/hh3.png"));
 exit.setBounds(520, 822, 60, 25);
 exit.addMouseListener(this);
 this.add(exit);

 EndPanel end = new EndPanel(person);
 this.add(end);//将结束面板组件添加到结束窗口上

 this.setSize(1500, 900);
 this.setLocationRelativeTo(null);
 this.setUndecorated(true);
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.setIconImage(new ImageIcon("Image/115.png").getImage());
 this.setVisible(true);
 }

 public static void main(String[] args) {
 //new EndFrame();
 }
 class EndPanel extends JPanel{
 Image background;
 Person p;
 public EndPanel(Person person) {//类比int a
 this.p = person;//创建对象、传值
 try {
 background = ImageIO.read(new File("Image/chou.png"));
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 @Override
 public void paint(Graphics g) {
 // TODO Auto-generated method stub
 super.paint(g);
 g.drawImage(background, 0, 0,1500,900 ,null);
 g.setColor(Color.CYAN);
 g.setFont(new Font("宋体",Font.BOLD,30));
 g.drawString(p.getScore()+"",1110,705);// + ” “ 属实妙
 g.drawString(p.getDistance() + " ", 1110, 622);

 g.setFont(new Font("宋体",Font.BOLD,50));
 g.setColor(Color.ORANGE);
 g.drawString(p.getTotalScore() + "", 1075, 500);
 }
 }
 @Override
 public void mouseClicked(MouseEvent e) {
 if(e.getSource().equals(again)){
 //跳转到下一界面
 new WindowFrame().Start();
 //关闭当前界面
 dispose();
 } else if(e.getSource().equals(back)){
 new MainFrame();
 dispose();
 }else if(e.getSource().equals(exit)){
 System.exit(0);
 }
 }

 @Override
 public void mousePressed(MouseEvent e) {
 // TODO Auto-generated method stub

 }

 @Override
 public void mouseReleased(MouseEvent e) {
 // TODO Auto-generated method stub

 }

 @Override
 public void mouseEntered(MouseEvent e) {
 // TODO Auto-generated method stub

 }

 @Override
 public void mouseExited(MouseEvent e) {
 // TODO Auto-generated method stub

 }

}

到此这篇关于使用Java实现天天酷跑(附源码)的文章就介绍到这了,更多相关Java实现天天酷跑内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java实现人机猜拳小游戏

    本文实例完成人机猜拳互动游戏的开发,供大家参考,具体内容如下 阶段一:实验--分析业务,创建用户类 1.分析业务,抽象出类.类的特征和行为 2.创建出用户类 阶段二:实验--创建出计算机类 1.创建计算机类Computer.实现计算机出拳 2.产生一个1-3的随机数,模拟计算机的出拳结果 阶段三:实验--创建游戏类,选择对战对手 1.创建游戏类Game 2.编写游戏类的初始化方法initial() 3.编写游戏类的开始游戏方法startGame() 阶段四:实验--实现一局对战 分别调用用户类和

  • javafx实现五子棋游戏

    需求描述 一个五子棋游戏,能实现双方黑白对决,当一方获胜时给出提示信息,利用GUI界面实现 项目结构如下图 一.实体 FiveChess类 提供五子棋实体包含的所有信息 判断游戏是否结束 play方法改变chess[][]棋盘中的数据 package entity; import javafx.scene.control.Alert; public class FiveChess{ public double getWidth() { return width; } public void se

  • java实现简单控制台五子棋游戏

    本文实例为大家分享了java实现简单控制台五子棋的具体代码,供大家参考,具体内容如下 GobangMain这个类是游戏的主方法,主要用于控制游戏的执行,值得注意的是输入的坐标的格式是3,4的样式,不能是其他的格式,也不能出现空格. package com.qf.Gobang; import java.util.Scanner; import org.omg.CORBA.PUBLIC_MEMBER; public class GobangMain { public static String wh

  • java实现桌球小游戏

    本文实例为大家分享了java实现桌球小游戏的具体代码,供大家参考,具体内容如下 桌球小游戏 两张图片放在src的同级目录下 版本一.出现窗口 package cn.xjion.game; /** * 出现窗口 * @author xjion * */ import java.awt.*; import javax.swing.*; //继承窗口类 public class BallGame extends JFrame{ // 窗口加载的方法 void launchFrame(){ // 窗口的

  • 使用Java实现天天酷跑(附源码)

    首先,写一个需求文档: 一.项目名称:<天天酷跑>(RunDay) 二.功能介绍: 闯关类游戏,玩家登录后,选择进入游戏,通过键盘控制玩家的上下左右移动,来躲避 障碍物和吃金币,玩家躲避的障碍物越多跑酷距离越远,玩家吃的金币越多,得分越高. 三.功能模块: 1.登录界面 用户名(输入框,明文) 密码(输入框,密文) 登录.取消按钮 2.菜单选择界面 开始游戏按钮(图片按钮) 帮助按钮 退出按钮 3.缓冲加载界面 自动加载进度条,加载完毕之后,跳转到下一界面 4.游戏主界面 移动的背景图片.动态

  • Java实现天天酷跑小游戏完整代码(附源码)

    目录 首先,写一个需求文档: 一.登录界面 1.界面 2.登录 3.退出 二.开始游戏界面 三.缓冲加载游戏界面 四.游戏主界面 五.结束界面 上代码 首先,写一个需求文档: 一.项目名称:<天天酷跑>(RunDay) 二.功能介绍: 闯关类游戏,玩家登录后,选择进入游戏,通过键盘控制玩家的上下左右移动,来躲避 障碍物和吃金币,玩家躲避的障碍物越多跑酷距离越远,玩家吃的金币越多,得分越高. 三.功能模块: 1.登录界面 用户名(输入框,明文) 密码(输入框,密文) 登录.取消按钮 2.菜单选择

  • java实现简易超市管理系统 附源码下载

    java超市管理系统 1.0(含源文件,后续会继续优化~) 前言 一个月零零散散的时间学习了java,通过这次"超市管理系统"的练习,希望可以给一同开始学习java的朋友一些参考,更希望大佬们多多指点和批评~ 一.确定需求 程序概述: 小型超市商品销售管理系统选择小型超市的四类商品进行管理. 这四类商品是:食品.化妆品.生活用品和饮料(四个类). 每类商品都包含有商品名和商品利润 (其中包括商品的售价.进价.库存量).(五个属性) 每类不同的商品还有区别于其他商品的特殊信息(子类特有属

  • 基于Java实现互联网实时聊天系统(附源码)

    目录 0. 前言 1.技术准备 2. 整体说明 2.1 设计思想 2.2 系统结构 2.3 项目结构 2.4 系统功能模块 2.5 系统界面 3. 核心编码 3.1 Netty服务器启动与关闭 4. 效果及操作演示 4.1 登录操作 4.2 聊天演示 5. 源码下载 0. 前言 决定以Netty为核心,以WebSocket为应用层通信协议做一个互联网聊天系统,整体而言就像微信网页版一样,但考虑到这个聊天系统的功能非常多,因此只打算实现核心的聊天功能,包括单发.群发.文件发送,然后把项目与Spri

  • 基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)

    这是一款基于jQuery的弹出对话框插件,这个jQuery对话框插件的最大特点是弹出和关闭都带有非常炫酷的动画特效,比如旋转飞入.上下抖动飞入等.效果图如下: 效果演示    源码下载 html代码: <div class="container"> <h1>jQuery gDialog Plugin Exampels</h1> <button class="btn demo-1">Alert Dialog Box<

  • Java中的使用及连接Redis数据库(附源码)

    引言: 本文主要分享了Redis如何在IDEA中部署,运行:模拟加入Redis的操作: 目录结构 1. 在IDEA中搭建Redis 1.1 创建项目 新建含有web的SpringBoot项目: 搭建项目参考:SpringBoot超详细笔记:https://blog.csdn.net/weixin_42601136/article/details/108396511 1.2 添加依赖(不够手动添加) <dependencies> <!-- 1. Jedis--> <depend

  • 基于Python实现天天酷跑功能

    感觉上次写的植物大战僵尸与俄罗斯方块的反应还不错,这次这个文章就更有动力了 这次就写一个天天酷跑吧 写出来的效果图就是这样了 下面就更新一下全部的代码吧 还是老样子先定义 import pygame,sys import random 写一下游戏配置 width = 1200 #窗口宽度 height = 508 #窗口高度 size = width, height score=None #分数 myFont=myFont1=None #字体 surObject=None #障碍物图片 surG

  • 最优雅地整合 Spring & Spring MVC & MyBatis 搭建 Java 企业级应用(附源码)

    这里使用 Maven 项目管理工具构建项目 初始化项目 打开 Intellij IDEA,点击 Create New Project 选择 Maven 构建项目 选择 JDK 版本 选择 maven-archetype-webapp 模板(Java Web 项目) 填写项目在 Maven 仓库中的坐标(在 Maven 仓库中根据这个坐标才能找到该项目) 选择 Maven 路径 选择 Maven 配置文件路径 选择 Maven 本地仓库路径 填写项目名 选择工作目录 创建目录 在 src > ma

  • Java 3D入门之基本图形功能 附源码

    目录 坐标系 基本体组合的显示实例 三角面图形 三角扇图形 四边面图形 坐标系 1.原点O在显示器的中间. 2.Z轴是指向屏幕之外的,也就是观察者. 3.由于观察者眼睛,即观察方向是指向Z轴的反方向,所以当定义好图形之后,光源的方向一定不能是指向Z轴的正方向,否则无法观察到图形.(根据光的反射) 基本体组合的显示实例 import java.applet.Applet; import java.awt.BorderLayout; import java.awt.GraphicsConfigura

  • Java实现贪吃蛇大作战小游戏(附源码)

    目录 1.开发环境及游戏展示 1.1 游戏主界面 1.2 移动界面 1.3 奖励界面 1.4 F加速功能界面 1.5 死亡界面 2.需求分析 3.系统设计 3.1 系统总体功能设计 3.2 系统总体流程设计 4.功能设计 4.1 贪吃蛇移动及加速功能设计 4.2 贪吃蛇吃食物加速及死亡判定功能的设计 4.3 贪吃蛇主动加速功能的设计 4.4 贪吃蛇奖励机制功能的设计 5.项目结构与项目实现 5.1 项目结构及类间关系 5.2 项目完整源码 1.开发环境及游戏展示 贪吃蛇大作战在设计与实验的过程中

随机推荐