java贪食蛇游戏
废话不多说,直接上代码,也比较简单。
1. 游戏桌面实体类
/**
* @author lk-tony
* @Title: 桌面实体类
* @Description:
* @date 2023/2/13 10:20
*/
public class Desk {
private Integer dWidth;
private Integer dHeight;
/**
* 坐标系
*/
private Integer[][] field;
public Desk(Integer dWidth, Integer dHeight) {
this.dWidth = dWidth;
this.dHeight = dHeight;
field = new Integer[dWidth][dHeight];
}
public Integer getdWidth() {
return dWidth;
}
public void setdWidth(Integer dWidth) {
this.dWidth = dWidth;
}
public Integer getdHeight() {
return dHeight;
}
public void setdHeight(Integer dHeight) {
this.dHeight = dHeight;
}
public Integer[][] getField() {
return field;
}
public void setField(Integer[][] field) {
this.field = field;
}
}
2. 坐标点类
/**
* @author lk-tony
* @Title: 点实体类
* @Description:
* @date 2023/2/13 10:20
*/
public class Point {
private Integer x;
private Integer y;
public Point(Integer x, Integer y) {
this.x = x;
this.y = y;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
}
3.贪食蛇实体类
/**
* @author lk-tony
* @Title: 贪食蛇实体类
* @Description:
* @date 2023/2/13 10:20
*/
public class Snake {
private final Random random = new Random();
private List<Point> body = new LinkedList<>();
/**
* 0 左 1 上 2 右 3 下
*/
private Integer dir;
public Integer getDir() {
return dir;
}
public void setDir(Integer dir) {
this.dir = dir;
}
public List<Point> getBody() {
return body;
}
public void setBody(List<Point> body) {
this.body = body;
}
public void init(Integer x, Integer y) {
// 初始化蛇
for (int i = 0; i < 4; i++) {
body.add(new Point(x + i, y));
}
}
/**
* 检查是否死亡
*
* @return
*/
public Boolean checkDeath(Desk desk) {
// 判断蛇头与蛇身的点是否有重合,重合则死亡,蛇头是否超过边界,过界则死亡
Point head = body.get(0);
for (int i = 1; i < body.size(); i++) {
if (head.getX().equals(body.get(i).getX()) && head.getY().equals(body.get(i).getY())) {
return true;
}
}
if (head.getX() < 0) {
return true;
}
if (head.getY() < 0) {
return true;
}
if (head.getX() > desk.getdWidth()) {
return true;
}
if (head.getY() > desk.getdHeight()) {
return false;
}
return false;
}
/**
* 移动一步
*/
public boolean moveOneStep(Point food) {
boolean isEatFood = false;
Point endPoint = new Point(0,0);
endPoint.setX(body.get(body.size() - 1).getX());
endPoint.setY(body.get(body.size() - 1).getY());
Point head = body.get(0);
// 蛇所有的点换成它上一个节点
for (int i = body.size() - 1; i > 0; i--) {
body.get(i).setX(body.get(i - 1).getX());
body.get(i).setY(body.get(i - 1).getY());
}
// 蛇头的最新位置
switch (dir) {
case 0:
// 左
head.setX(head.getX() - 1);
break;
case 1:
// 上
head.setY(head.getY() - 1);
break;
case 2:
// 右
head.setX(head.getX() + 1);
break;
case 3:
// 下
head.setY(head.getY() + 1);
break;
default:
}
// 如果蛇头当前位置是食物,则在蛇尾后增加一个点
if (head.getX().equals(food.getX()) && head.getY().equals(food.getY())) {
System.out.println("x=" + head.getX() + "y=" + head.getY());
body.add(endPoint);
isEatFood = true;
}
return isEatFood;
}
/**
* 生成食物
*/
public Point produceFood(Desk desk) {
// 随机获取桌面内的点,要求点与蛇身不重复
Point food = null;
boolean flag = true;
while (flag) {
Integer randomX = random.nextInt(desk.getdWidth());
Integer randomY = random.nextInt(desk.getdHeight());
// 判断随机点是否在蛇身,在则继续随机
boolean isOk = true;
for (Point point : body) {
if (point.getX().equals(randomX) && point.getY().equals(randomY)) {
isOk = false;
break;
}
}
if (isOk) {
flag = false;
food = new Point(randomX, randomY);
}
}
return food;
}
/**
* 刷新蛇身与食物坐标
*/
public void refresh(Desk desk, Point food) {
Integer[][] field = new Integer[desk.getdWidth()][desk.getdHeight()];
// 画上蛇身
for (Point point : body) {
field[point.getX()][point.getY()] = 1;
}
// 画上食物
field[food.getX()][food.getY()] = 1;
desk.setField(field);
}
}
4.游戏启动类
/**
* @author lk-tony
* @Title: 游戏实体类
* @Description:
* @date 2023/2/13 10:20
*/
public class SnakeGame extends JComponent {
private static Integer unit = 10;
private static Desk desk = new Desk(50, 50);
private static Snake snake = new Snake();
private static Point food = null;
private static Integer score = 0;
private static String menInfo = "";
public SnakeGame() {
setBackground(Color.WHITE);
// 先往上走
snake.setDir(1);
snake.init(25, 25);
// 每0.5秒刷新界面
new Timer(100, (event) -> {
// 判断是否死亡
if (snake.checkDeath(desk)) {
System.out.println("is dead");
return;
}
// 生成食物
if (null == food) {
food = snake.produceFood(desk);
}
// 移动一步
boolean isEatFood = snake.moveOneStep(food);
if (isEatFood) {
food = snake.produceFood(desk);
score++;
}
// 刷新界面
snake.refresh(desk, food);
// 显示分数
menInfo = String.format(" 分数 %d", score);
repaint();
}).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint(0, desk.getdHeight() * unit);
p.addPoint(desk.getdWidth() * unit, desk.getdHeight() * unit);
p.addPoint(desk.getdWidth() * unit, 0);
g.drawPolygon(p);
g2d.setColor(Color.BLUE);
for (int x = 0; x < desk.getField().length; x++) {
for (int y = 0; y < desk.getField()[x].length; y++) {
if (null != desk.getField()[x][y] && desk.getField()[x][y] == 1) {
int xPoint = x * unit;
int yPont = y * unit;
g2d.fillRect(xPoint, yPont, unit, unit);
//System.out.println("x=" + xPoint +" , y=" + xPoint);
}
}
}
g2d.setColor(Color.RED);
g2d.drawString(menInfo, desk.getdWidth() * unit + 10, 10);
}
/**
* 创建界面
*/
private static void createAndShowGUI() {
final JFrame f = new JFrame("Snake");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 800);
f.add(new SnakeGame());
f.setVisible(true);
f.setLocationRelativeTo(f.getOwner());
f.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// 获取对应的键盘字符代码
int keyCode = e.getKeyCode();
// 0 左 1 上 2 右 3 下
// 键盘按上
if (keyCode == 38) {
snake.setDir(1);
}
// 键盘按下
if (keyCode == 40) {
snake.setDir(3);
}
// 键盘按左
if (keyCode == 37) {
snake.setDir(0);
}
// 键盘按右
if (keyCode == 39) {
snake.setDir(2);
}
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
createAndShowGUI();
});
}
}
浙公网安备 33010602011771号