贪吃蛇小游戏 - 在线玩经典蛇类游戏
package game;
import javax.sound.sampled.; import javax.swing.; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Random;
public class SnakeGame extends JFrame implements KeyListener, ActionListener {
// 游戏界面大小
private final int WIDTH = 800;
private final int HEIGHT = 840;
// 网格大小
private static final int GRID_SIZE = 40;
// 贪吃蛇移动速度
private static final int SNAKE_SPEED = GRID_SIZE;
// 贪吃蛇的区块
private final ArrayList
//把图片jlabel一下
JLabel j=new JLabel(icon);
JLabel jdead=new JLabel(deadicon);
JLabel jeat=new JLabel(eaticon);
//开始游戏按钮
JButton startButton = new JButton('开始游戏');
//排行榜按钮
JButton rankButton = new JButton('排行榜');
//游戏状态
private boolean gameStarted = false;
public SnakeGame() {
// 设置窗口大小和标题
setSize(WIDTH, HEIGHT);
setTitle('贪吃蛇小游戏');
// 设置窗口居中
setLocationRelativeTo(null);
// 添加键盘监听器
addKeyListener(this);
//初始化按钮
initButton();
// 初始化贪吃蛇和食物
initSnake();
initFood();
//打印蛇头
this.add(j);
// 显示窗口
setVisible(true);
}
// 初始化贪吃蛇
private void initSnake() {
// 初始长度为3
snake.add(new Point(4, 2));
snake.add(new Point(3, 2));
snake.add(new Point(2, 2));
}
// 初始化食物
private void initFood() {
Random random = new Random();
int x = random.nextInt((WIDTH-2*GRID_SIZE) / GRID_SIZE);
int y = random.nextInt((HEIGHT-2*GRID_SIZE) / GRID_SIZE);
food = new Point(x+1, y+1);
}
// 初始化按钮
private void initButton() {
startButton.addActionListener(this);
rankButton.addActionListener(this);
startButton.setBounds(WIDTH / 2 - 100, HEIGHT / 2 - 50, 200, 50);
rankButton.setBounds(WIDTH / 2 - 100, HEIGHT / 2 + 50, 200, 50);
add(startButton);
add(rankButton);
}
// 绘制游戏界面
@Override
public void paint(Graphics g) {
// 清空画布
g.clearRect(0, 0, WIDTH, HEIGHT);
if (gameStarted) {
// 绘制贪吃蛇
g.setColor(Color.red);
for (Point p : snake) {
g.fillOval(p.x * GRID_SIZE, p.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
}
// 绘制蛇头
j.setBounds(snake.get(0).x*GRID_SIZE-7,snake.get(0).y*GRID_SIZE-30,40,40);
// 绘制网格
g.setColor(Color.blue);
for (int i = 0; i < WIDTH / GRID_SIZE; i++) {
g.drawLine(i * GRID_SIZE, 0, i * GRID_SIZE, HEIGHT);
}
for (int i = 0; i < HEIGHT / GRID_SIZE; i++) {
g.drawLine(0, i * GRID_SIZE, WIDTH, i * GRID_SIZE);
}
// 绘制食物
g.setColor(Color.PINK);
g.fillOval(food.x * GRID_SIZE, food.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
// 显示得分
g.setColor(Color.darkGray);
g.setFont(new Font('微软雅黑', Font.PLAIN, 20));
g.drawString('得分:' + score, 650, 100);
//绘制黑色方格边框
g.setColor(Color.black);
for (int i = 0; i <WIDTH/GRID_SIZE ; i++) {
g.fillRect(i*GRID_SIZE,0,40,40);
g.fillRect(i*GRID_SIZE,800,40,40);
g.fillRect(0,i*GRID_SIZE,40,40);
g.fillRect(760,i*GRID_SIZE,40,40);
}
} else {
// 显示开始游戏提示
g.setFont(new Font('微软雅黑', Font.PLAIN, 40));
g.drawString('按下开始游戏按钮开始游戏', WIDTH / 2 - 200, HEIGHT / 2);
}
}
// 重写 update() 方法,调用 paint() 方法
@Override
public void update(Graphics g) {
paint(g);
}
// 贪吃蛇移动
private void moveSnake() {
// 计算新的蛇头位置
Point head = new Point(snake.get(0).x + direction.x, snake.get(0).y + direction.y);
// 判断是否撞墙
if (head.x < 1 || head.x >= (WIDTH / GRID_SIZE)-1 || head.y < 1 || head.y >= (HEIGHT / GRID_SIZE)-1) {
String filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\FQ!(魔男)_1.WAV';
playSnakeMusic(filePath,2F);
JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
System.exit(0);
}
// 判断蛇头是否与蛇身相撞
for (int i = 1; i < snake.size(); i++) {
if (head.equals(snake.get(i))) {
String filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\你干嘛哎哟_1.WAV';
playSnakeMusic(filePath,2F);
JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
System.exit(0);
}
}
// 判断是否吃到食物
if (head.equals(food)) {
// 如果音效未正在播放,则播放音效
if (!hasPlayed) {
//13个音效随机播放
Random random = new Random();
int index = random.nextInt(18);
String filePath = '';
switch (index) {
case 0:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\emmmm__(van)_1.WAV';
break;
case 1:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\I love that_ (van)_1.WAV';
break;
case 2:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\oh!夜色!_1.WAV';
break;
case 3:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\务必让螳螂乱摸_(van)_1.WAV';
break;
case 4:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\啊_this good_(van)_1.WAV';
break;
case 5:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\啊?快哉!(王)_1.WAV';
break;
case 6:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\来!_1.WAV';
break;
case 7:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\洞子大(van)_1.WAV';
break;
case 8:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\van的销魂叫声__1.WAV';
break;
case 9:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Is so F K D(van)_1.WAV';
break;
case 10:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\That turns me on(van)_1.WAV';
break;
case 11:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Do you like van 游戏?_1.WAV';
break;
case 12:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\偷袭_1.WAV';
break;
case 13:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Yeees(van)_1.WAV';
break;
case 14:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\厉不厉害 你坤哥_1.WAV';
break;
case 15:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\及你太美_1.WAV';
break;
case 16:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\其实我平时很厉害的 你知道吗_1.WAV';
break;
case 17:
filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\个人练习生_1.WAV';
break;
}
playSnakeMusic(filePath, 2F);
hasPlayed = true;
}
// 更新贪吃蛇和食物
snake.add(0, head);
initFood();
// 如果吃到食物,则将 score 的值加上 10
score += 10;
} else {
hasPlayed = false; // 如果未吃到食物,则重置 hasPlayed 为 false
snake.add(0, head);
snake.remove(snake.size() - 1);
}
// 刷新游戏界面 repaint();
}
// 按键处理
@Override
public void keyPressed(KeyEvent e) {
if (!gameStarted) {
return; // 游戏未开始,不响应按键
}
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
if (direction.y != 1) {
direction.x = 0;
direction.y = -1;
}
break;
case KeyEvent.VK_DOWN:
if (direction.y != -1) {
direction.x = 0;
direction.y = 1;
}
break;
case KeyEvent.VK_LEFT:
if (direction.x != 1) {
direction.x = -1;
direction.y = 0;
}
break;
case KeyEvent.VK_RIGHT:
if (direction.x != -1) {
direction.x = 1;
direction.y = 0;
}
break;
}
}
// 必须实现的方法
@Override
public void keyTyped(KeyEvent e) {
}
// 必须实现的方法
@Override
public void keyReleased(KeyEvent e) {
}
// 播放音乐
private void playMusic(String filePath) {
File musicFile = new File(filePath);
try {
AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
e.printStackTrace();
}
}
//播放音效,音效只播放一次(这里因为我找的音效声音太小了便传进一个volume增大音量)
private void playSnakeMusic(String filePath, float volume) {
File musicFile = new File(filePath);
try {
AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
// 获取FloatControl控制类型
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
// 设置音量大小
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
gainControl.setValue(dB);
// 添加LineListener
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
clip.close(); // 关闭Clip
try {
audioStream.close(); // 关闭音频输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
clip.start(); // 播放音乐
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
e.printStackTrace();
}
}
//按钮点击事件
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
gameStarted = true;
remove(startButton); // 移除开始按钮
remove(rankButton); // 移除排行榜按钮
repaint();
// 开始游戏循环
new Thread(() -> {
while (gameStarted) {
moveSnake();
try {
Thread.sleep(8000 / SNAKE_SPEED);
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}).start();
} else if (e.getSource() == rankButton) {
// 显示排行榜
JOptionPane.showMessageDialog(this, '排行榜功能暂未实现', '提示', JOptionPane.INFORMATION_MESSAGE);
}
}
public static void main(String[] args) {
SnakeGame game = new SnakeGame();
// 游戏循环
// 关闭旧的界面
}
}
原文地址: https://www.cveoy.top/t/topic/oC4b 著作权归作者所有。请勿转载和采集!