package com.yc.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import com.yc.utils.PlayMusicUtil;
import com.yc.utils.PropertiesUtils;
/**
* 游戏主界面
* @author wwwch
*
*/
public class SnakeFrame extends JFrame{
private static final long serialVersionUID = 8866826595307493727L;
private static final int WIDTH = 800; // 这是游戏面板的宽度 而不是窗体的宽度
private static final int HEIGHT = 600; //游戏面板的高度
private static final int CELL = 20; //每个单元格的大小 或者说蛇头、水果的大小
private JLabel snakeHeader; //蛇头
private JLabel fruit; //水果
private Random random = new Random(); //这是用来生成随机数的工具类 以便于随机生成一个点
private int dir = 1; // 用来标识蛇头运动的方向 1:向右 -1:向左 2:向上 -2:向下
private LinkedList<JLabel> bodies = new LinkedList<JLabel>();
//存储水果图片名称的数组
private String[] fruits = {"pineapple.png","apple.png","cherry.png","grape.png","orange.png","peach.png","strawberry.png","tomato.png"};
//存储蛇身体图片的数组
private String[] snakeBody = {"green.png","red.png","yellow.png","purple.png"};
private JLabel highestLabel; // 显示最高记录
private JLabel currentLabel; // 显示当前得分
private int highestScore; //最高得分
private int currentScore;// 当前得分
private PropertiesUtils prop = PropertiesUtils.getInstance();
private Timer timer; // 定时器
private boolean status = true;// 标识运行还是餐厅 true: 运行 false :暂停
public SnakeFrame(){
//图标
ImageIcon icon = new ImageIcon("./src/com/yc/images/snake.jpg");
this.setIconImage(icon.getImage());
this.setTitle("贪吃蛇——终极炼狱难度");
this.setSize(WIDTH+4, HEIGHT+34);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setLayout(null);
//将游戏面板添加到窗体中
SnakePanel snakePanel = new SnakePanel();
snakePanel.setBounds(0, 0, WIDTH, HEIGHT);
this.add(snakePanel);
//给窗体添加键盘监听
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//获取到按键对应的码值
int keyCode = e.getKeyCode();
//根据keyCode改变蛇头移动的方向
switch (keyCode) {
case KeyEvent.VK_LEFT: //左键
if(dir != SnakeDirection.RIGHT){ //只有当前方向不是向右时才可以改变运动方向向左
dir = SnakeDirection.LEFT;
//将蛇头的图片改变一下
setBackgrounImage(snakeHeader, "header_l.png");
}
break;
case KeyEvent.VK_RIGHT: //右键
if(dir != SnakeDirection.LEFT){ //只有当前方向不是向右时才可以改变运动方向向左
dir = SnakeDirection.RIGHT;
setBackgrounImage(snakeHeader, "header_r.png");
}
break;
case KeyEvent.VK_UP: //上键
if(dir != SnakeDirection.BOTTOM){ //只有当前方向不是向右时才可以改变运动方向向左
dir = SnakeDirection.TOP;
setBackgrounImage(snakeHeader, "header_t.png");
}
break;
case KeyEvent.VK_DOWN: //左键
if(dir != SnakeDirection.TOP){ //只有当前方向不是向右时才可以改变运动方向向左
dir = SnakeDirection.BOTTOM;
setBackgrounImage(snakeHeader, "header_b.png");
}
break;
case KeyEvent.VK_SPACE: //暂停或运行
// if(status){ // 如果是运行状态则暂停
// status = !status;
// }else{
// status = !status;
// timer.notify();
// }
}
}
});
this.setVisible(true);
//先调用一次
PlayMusicUtil.playBGM();
//设置一个定时器 循环播放背景音乐
new Timer(98000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PlayMusicUtil.playBGM();
}
}).start();
}
/**
* 给一个JLabel设置背景图片
* @param label 需要设置背景图的组件
* @param fileName 图片的文件名称
*/
private void setBackgrounImage(JLabel label,String fileName){
ImageIcon icon = new ImageIcon("./src/com/yc/images/"+fileName);
//设置图片按照组件大小进行缩放
icon.setImage( icon.getImage().
getScaledInstance(label.getWidth(),label.getHeight(),Image.SCALE_DEFAULT));
label.setIcon(icon);
}
/**
* 游戏的主面板
* 我们等会只需要将这个面板添加到窗体中即可
* 用内部类的原因是因为内部类可以直接使用外部类的所有成员
*
* @author wwwch
*
*/
class SnakePanel extends JPanel{
private static final long serialVersionUID = 1L;
public SnakePanel(){
init();
}
private void init() {
this.setSize(SnakeFrame.WIDTH, SnakeFrame.HEIGHT);
this.setLayout(null);
//添加最高记录的标签
highestLabel = new JLabel();
//获取score.properties文件中最高记录的值
highestScore = Integer.parseInt(prop.getProperty("highest"));
highestLabel.setText("最高记录:"+highestScore);
highestLabel.setBounds(20, 20, 300, 30);
this.add(highestLabel);
//添加当前得分
currentLabel = new JLabel("当前得分:"+currentScore);
currentLabel.setBounds(20, 60, 300, 30);
this.add(currentLabel);
//随机创建出一个蛇头并且将蛇头添加到面板中
createHeader();
//创建一个水果
new Thread(new Runnable() {
@Override
public void run() {
createFruit();
}
}).start();
//使用 定时器让蛇头运动起来 delay: 每隔100毫秒运动一次
timer = new Timer(30, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//先获取到蛇头当前的位置
Point oldPoint = snakeHeader.getLocation();
//计算下一个蛇头的位置
Point newPoint = null;
//根据dir决定蛇头运动的方向 以计算出蛇头下一个位置的点
switch (dir) {
case SnakeDirection.RIGHT: //向右
newPoint = new Point(oldPoint.x+CELL, oldPoint.y);
break;
case SnakeDirection.LEFT: //向左
newPoint = new Point(oldPoint.x-CELL, oldPoint.y);
break;
case SnakeDirection.BOTTOM: //向下
newPoint = new Point(oldPoint.x, oldPoint.y+CELL);
break;
case SnakeDirection.TOP: //向上
newPoint = new Point(oldPoint.x, oldPoint.y-CELL);
break;
}
//将蛇头的位置移动到新的点
snakeHeader.setLocation(newPoint);
//每次蛇头移动之后,其他身体节点也必须跟着移动,都可能出现一些可能: 撞墙 或者 吃到豆子
isHeatWall();
//如果没有撞墙 判断一下是否可以吃豆子
if(snakeHeader.getLocation().equals( fruit.getLocation())){
eatBean();
}
//不管吃没吃到豆子 蛇的身体部分必须跟着蛇头移动 需要将蛇头原来的位置传过去
move(oldPoint);
}
});
timer.start();
}
/**
* 让蛇的身体跟随蛇头移动的方法
*
* @param oldPoint 蛇头原来的位置
*/
private void move(Point oldPoint) {
Point p = new Point();
//从蛇的第二节开始 每一节都要跟随前一节移动
for(int i=1;i<bodies.size();i++){
//先记录下前一节身体的位置
p = bodies.get(i).getLocation()
没有合适的资源?快使用搜索试试~ 我知道了~
Java贪吃蛇小游戏.zip
共28个文件
png:17个
java:5个
wav:3个
需积分: 5 0 下载量 35 浏览量
2023-08-04
21:38:05
上传
评论
收藏 4.61MB ZIP 举报
温馨提示
用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。用java写的项目,源码都经测试过,真实可靠,欢迎自行下载学习。
资源推荐
资源详情
资源评论
收起资源包目录
Java贪吃蛇小游戏.zip (28个子文件)
222
.idea
vcs.xml 180B
score.properties 41B
com
yc
music
gameover.wav 313KB
bgm.wav 4.16MB
life.wav 68KB
utils
PlayMusicUtil.java 1KB
PropertiesUtils.java 718B
images
header_r.png 5KB
yellow.png 3KB
purple.png 3KB
green.png 3KB
grape.png 71KB
header_l.png 5KB
pineapple.png 64KB
orange.png 52KB
tomato.png 55KB
apple.png 51KB
header_t.png 4KB
bg.png 313KB
peach.png 54KB
snake.jpg 13KB
cherry.png 58KB
strawberry.png 57KB
red.png 3KB
header_b.png 4KB
ui
StartGame.java 117B
SnakeDirection.java 192B
SnakeFrame.java 13KB
共 28 条
- 1
资源评论
c++服务器开发
- 粉丝: 3046
- 资源: 4463
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- nginx配置文件,注意其中需要对应宿主机的路径
- 自用数据集自用数据集自用数据集
- HTML5小游戏【堆雪人-优秀H5小游戏合集】游戏源码分享下载 - epicsnowman.zip
- SNMP Client 是SNMP测试工具
- Android Camera内存统计脚本
- AD9220高速数据芯片硬件参考设计原理图+STM32F103单片机驱动程序代码+芯片技术手册资料.zip
- 常用爆破用户名字典top500
- meta-llama-3-8b-instruct 的 model-00003-of-00004.safetensors 的2/3
- bootstrap-select.js bootstrap-select.css
- EasyPoi Excel和 Word简易工具类
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功