Java版 贪吃蛇
程序员文章站
2023-12-23 20:28:51
...
Java版 贪吃蛇
写得有些蛋疼,还是C好,废话不多说,上图:
- 游戏中
代码:
- 食物Food
package SnakeGame.Data;
import java.util.Objects;
public class Food {
private int x;
private int y;
private boolean flay;
public Food(){ Init(); }
public void Init(){
x = (int)((Math.random() * 88) + 1) * 10;
y = (int)((Math.random() * 57) + 1) * 10;
this.flay = false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Food food = (Food) o;
return x == food.x && y == food.y;
}
public boolean equals(SnakeNode node){
return x == node.getX() && y == node.getY();
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
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 boolean isFlay() { return flay; }
public void setFlay(boolean flay) { this.flay = flay; }
}
- 蛇节点SnakeNode
package SnakeGame.Data;
import java.util.Objects;
public class SnakeNode {
private int x;
private int y;
public SnakeNode(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SnakeNode snakeNode = (SnakeNode) o;
return x == snakeNode.x && y == snakeNode.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
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;
}
}
- 蛇身SnakeBody
package SnakeGame.Data;
import java.util.LinkedList;
import java.util.Objects;
public class SnakeBody {
private LinkedList<SnakeNode> body = new LinkedList<>();
private Enumeration Status = Enumeration.G_INIT;
private Enumeration Direction;
private int Len;
public SnakeBody(){ Init(); }
public void Init() {
Len = 3;
Direction = Enumeration.DOWN;
Status = Enumeration.G_INIT;
body.clear();
for(int n = 0; n < 3; n++){
body.add(new SnakeNode(50, (n + 1) * 10));
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SnakeBody snakeBody = (SnakeBody) o;
return Len == snakeBody.Len && body.equals(snakeBody.body) && Direction == snakeBody.Direction && Status == snakeBody.Status;
}
@Override
public int hashCode() {
return Objects.hash(body, Direction, Len, Status);
}
public LinkedList<SnakeNode> getBody() { return body; }
public void setBody(LinkedList<SnakeNode> body) { this.body = body; }
public Enumeration getDirection() { return Direction; }
public void setDirection(Enumeration direction) { Direction = direction; }
public int getLen() { return Len; }
public void setLen(int len) { Len = len; }
public Enumeration getStatus() { return Status; }
public void setStatus(Enumeration status) { Status = status; }
}
- 枚举Enumeration
package SnakeGame.Data;
public enum Enumeration {
UP, DOWN, LEFT, RIGHT, G_PAUSE, G_OVER, G_INIT, G_IN, G_EXIT
}
- 结束窗体EndInter
package SnakeGame.Move;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.SnakeBody;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class EndInter extends JFrame implements KeyListener {
final Image image = new ImageIcon("src/SnakeGame/Image/GAMEOVER.jpg").getImage();
private SnakeBody snake;
public EndInter(SnakeBody snake) throws HeadlessException {
this.snake = snake;
this.setBounds(600, 300, 800, 400);
JLabel jLabel = new JLabel(){
public void paintComponent(Graphics g){
g.drawImage(image,0,0,getWidth(),getHeight(),this);
g.setFont(new Font("宋体",Font.BOLD + Font.ITALIC,30));
g.setColor(randColor());
g.drawString(String.valueOf(snake.getLen() - 3),390,190);
}
};
this.add(jLabel);
this.setUndecorated(true);
this.setOpacity(.8f);
this.addKeyListener(this);
this.setVisible(true);
}
private Color randColor(){
int r = (int)(Math.random() * 256);
int g = (int)(Math.random() * 256);
int b = (int)(Math.random() * 256);
return new Color( r, g, b);
}
@Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_ESCAPE: this.snake.setStatus(Enumeration.G_EXIT); break;
case KeyEvent.VK_ENTER: this.snake.Init(); this.snake.setStatus(Enumeration.G_IN); this.dispose(); break;
default: break;
}
}
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
- 主窗体HomeInter
package SnakeGame.Move;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.SnakeBody;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class HomeInter extends JFrame implements KeyListener{
final ImageIcon image = new ImageIcon("src/SnakeGame/Image/BackGround.png");
private SnakeBody snake;
public HomeInter(SnakeBody snake) {
this.snake = snake;
this.setBounds(400, 200, 1200, 600);
this.setLayout(null);
JLabel jLabel = new JLabel(image);
jLabel.setSize(image.getIconWidth(),image.getIconHeight());
this.getLayeredPane().add(jLabel,new Integer(Integer.MIN_VALUE));
((JPanel)this.getContentPane()).setOpaque(false);
this.addKeyListener(this);
this.setUndecorated(true);
this.setVisible(true);
}
@Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_SPACE: snake.setStatus(Enumeration.G_PAUSE); new PauseInter(snake); break;
case KeyEvent.VK_DOWN: if(snake.getDirection() != Enumeration.UP) snake.setDirection(Enumeration.DOWN); break;
case KeyEvent.VK_LEFT: if(snake.getDirection() != Enumeration.RIGHT) snake.setDirection(Enumeration.LEFT); break;
case KeyEvent.VK_RIGHT: if(snake.getDirection() != Enumeration.LEFT) snake.setDirection(Enumeration.RIGHT); break;
case KeyEvent.VK_UP: if(snake.getDirection() != Enumeration.DOWN) snake.setDirection(Enumeration.UP); break;
default: break;
}
}
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
- 初始窗体InitInter
package SnakeGame.Move;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.SnakeBody;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class InitInter extends JFrame implements KeyListener {
final ImageIcon image = new ImageIcon("src/SnakeGame/Image/StartGame.jpg");
private SnakeBody snake;
public InitInter(SnakeBody snake){
this.snake = snake;
JLabel label = new JLabel(image);
this.setBounds(400,200,image.getIconWidth(),image.getIconHeight());
this.add(label);
this.setUndecorated(true);
this.addKeyListener(this);
this.setOpacity(.97f);
this.setVisible(true);
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_ESCAPE: snake.setStatus(Enumeration.G_EXIT); break;
case KeyEvent.VK_ENTER: snake.setStatus(Enumeration.G_IN); this.dispose(); break;
default: break;
}
}
public void keyTyped(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
}
- 暂停窗体PauseInter
package SnakeGame.Move;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.SnakeBody;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class PauseInter extends JFrame implements KeyListener{
final ImageIcon image = new ImageIcon("src/SnakeGame/Image/PauseInter.jpg");
private SnakeBody snake;
public PauseInter(SnakeBody snake){
this.snake = snake;
JLabel jLabel = new JLabel(image);
this.setBounds(800,250,image.getIconWidth(),image.getIconHeight());
this.add(jLabel);
this.setUndecorated(true);
this.addKeyListener(this);
this.setOpacity(.8f);
this.setVisible(true);
}
@Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_ENTER: snake.Init(); snake.setStatus(Enumeration.G_IN); this.dispose(); break;
case KeyEvent.VK_ESCAPE: snake.setStatus(Enumeration.G_OVER); new EndInter(snake); this.dispose(); break;
case KeyEvent.VK_SPACE: snake.setStatus(Enumeration.G_IN); this.dispose(); break;
}
}
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
- 游戏绘制SnakeGameLabel
package SnakeGame.Move;
import SnakeGame.Data.Food;
import SnakeGame.Data.SnakeBody;
import SnakeGame.Data.SnakeNode;
import javax.swing.*;
import java.awt.*;
public class SnakeGameLabel extends JLabel implements Runnable{
private SnakeBody snake;
private Food food;
public SnakeGameLabel(SnakeBody snake, Food food) {
this.snake = snake;
this.food = food;
this.setBounds(0,0,1200,600);
}
@Override
public void run() {
this.repaint();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
drawFood(g);
drawSnake(g);
drawGrade(g);
}
private void drawSnake(Graphics g){
for(SnakeNode node : snake.getBody()){
g.setColor(randColor());
g.fillRect(node.getX(),node.getY(),10,10);
}
}
private void drawGrade(Graphics g){
g.setColor(randColor());
g.setFont(setFont());
g.drawString(String.valueOf(snake.getLen() - 3),1040,115);
}
private void drawFood(Graphics g){
if(food.isFlay()){
g.setColor(randColor());
g.fillRect(food.getX(),food.getY(),10,10);
}
}
private Font setFont(){
return new Font("宋体",Font.BOLD + Font.ITALIC,30);
}
private Color randColor(){
int r = (int)(Math.random() * 256);
int g = (int)(Math.random() * 256);
int b = (int)(Math.random() * 256);
return new Color( r, g, b);
}
}
- 游戏接口SnakeGameInter
package SnakeGame.TestInterface;
public interface SnakeGameInter {
boolean IsDie();
void EatFood();
void RandFood();
void Run();
}
- 接口实现类TestSnakeGameInter
package SnakeGame.TestInterface;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.Food;
import SnakeGame.Data.SnakeBody;
import SnakeGame.Data.SnakeNode;
import SnakeGame.Move.EndInter;
public class TestSnakeGameInter implements SnakeGameInter {
private SnakeBody snake = new SnakeBody();
private Food food = new Food();
public TestSnakeGameInter() { }
@Override
public boolean IsDie() {
int headX = snake.getBody().getLast().getX();
int headY = snake.getBody().getLast().getY();
if(snake.getBody().size() > 4){
for(int n = 0; n < snake.getBody().size() - 4; n++){
if(snake.getBody().get(n).equals(snake.getBody().getLast())){
snake.setStatus(Enumeration.G_OVER);
new EndInter(snake);
return true;
}
}
}
switch(snake.getDirection()){
case UP: if(headY < 20) { snake.setStatus(Enumeration.G_OVER); new EndInter(snake); return true;} break;
case LEFT: if(headX < 20) { snake.setStatus(Enumeration.G_OVER); new EndInter(snake); return true;} break;
case RIGHT: if(headX > 880) { snake.setStatus(Enumeration.G_OVER); new EndInter(snake); return true;} break;
case DOWN: if(headY > 570) { snake.setStatus(Enumeration.G_OVER); new EndInter(snake); return true;} break;
}
return false;
}
@Override
public void Run() {
int headX = snake.getBody().getLast().getX();
int headY = snake.getBody().getLast().getY();
switch(snake.getDirection()){
case UP: snake.getBody().removeFirst(); snake.getBody().add(new SnakeNode(headX, headY - 10)); break;
case DOWN: snake.getBody().removeFirst(); snake.getBody().add(new SnakeNode(headX, headY + 10)); break;
case LEFT: snake.getBody().removeFirst(); snake.getBody().add(new SnakeNode(headX - 10, headY)); break;
case RIGHT: snake.getBody().removeFirst(); snake.getBody().add(new SnakeNode(headX + 10, headY)); break;
}
}
@Override
public void EatFood() {
int headX = snake.getBody().getLast().getX();
int headY = snake.getBody().getLast().getY();
if(headX == food.getX() && headY == food.getY()){
switch(snake.getDirection()){
case UP: snake.getBody().add(new SnakeNode(headX, headY - 10)); break;
case DOWN: snake.getBody().add(new SnakeNode(headX, headY + 10)); break;
case LEFT: snake.getBody().add(new SnakeNode(headX - 10, headY)); break;
case RIGHT: snake.getBody().add(new SnakeNode(headX + 10, headY)); break;
}
food.setFlay(false);
snake.setLen(snake.getLen() + 1);
}
}
@Override
public void RandFood() {
if(!food.isFlay()){
randfood();
for(SnakeNode node : snake.getBody()){
if(food.equals(node)){
randfood();
node = snake.getBody().getFirst();
}
}
food.setFlay(true);
}
}
private void randfood(){
food.setX((int)((Math.random() * 88) + 1) * 10);
food.setY((int)((Math.random() * 57) + 1) * 10);
}
public SnakeBody getSnake() { return snake; }
public void setSnake(SnakeBody snake) { this.snake = snake; }
public Food getFood() { return food; }
public void setFood(Food food) { this.food = food; }
}
- GoGame
package SnakeGame;
import SnakeGame.Data.Enumeration;
import SnakeGame.Data.Food;
import SnakeGame.Move.HomeInter;
import SnakeGame.Move.InitInter;
import SnakeGame.Data.SnakeBody;
import SnakeGame.Move.SnakeGameLabel;
import SnakeGame.TestInterface.TestSnakeGameInter;
public class GoGame{
public static void main(String[] args) throws InterruptedException{
TestSnakeGameInter test = new TestSnakeGameInter();
SnakeBody snake = test.getSnake();
Food food = test.getFood();
SnakeGameLabel snakeGameLabel = new SnakeGameLabel(snake, food);
HomeInter home = new HomeInter(snake);
home.add(snakeGameLabel);
new InitInter(snake);
while(snake.getStatus() != Enumeration.G_EXIT){
Thread draw = new Thread(snakeGameLabel);
if(snake.getStatus() == Enumeration.G_IN){
if(test.IsDie()){ continue;}
test.Run();
test.EatFood();
test.RandFood();
Thread.sleep(100);
draw.start();
}else{
draw.join();
}
}
System.exit(0);
}
}