内容概要:
在JFrame容器里加入一个JPanel,
对JPane进行绘画:方格+蛇身+食物
创建一个计时器(Time)+任务(TimerTask)对JPanel进行重绘
在任务里加入吃移动+判断是否活着+蛇吃食物
可用加入登录注册界面: 带登录页面的猜数字小游戏_小菜鸡℡的博客-CSDN博客
主线
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.TimerTask;
import java.util.Timer;
public class GluttonousSnakeGame extends JFrame{
private JPanel JP;
private Snake snake = new Snake();
public GluttonousSnakeGame(){
init();
repaintEveryPeriod();//计时器
initDirectionListener();//方向监听
this.setVisible(true);
}
private void init() {
this.setTitle("贪吃蛇");
this.setSize(600,401);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
//对JPanel进行绘画
JP= new JPanel(){
@Override
public void paint(Graphics g) {
//绘制方格
g.clearRect(0,0,600,401);
for (int i = 0; i < 37; i++) {
g.drawLine(0,i*10 ,580,i*10);
}
for (int i = 0; i < 59; i++) {
g.drawLine(i*10,0,i*10,360);
}
//获取蛇身
LinkedList<Grid> body = snake.getBody();
g.setColor(Color.RED);
//绘制蛇头
g.fillRect(body.getFirst().getX(),body.getFirst().getY(),10,10);
g.setColor(Color.BLACK);
//遍历集合 绘制蛇身。
for (int i = 1; i < body.size(); i++) {
g.fillRect(body.get(i).getX(),body.get(i).getY(),10,10);
}
//新食物
int[] ints = snake.newFood();
g.fillRect(ints[0], ints[1], 10, 10);
}
};
this.add(JP);
}
/**
* 计时器,重绘
*/
private void repaintEveryPeriod(){
Timer t = new Timer();//计时器
TimerTask task = new TimerTask(){//任务
@Override
public void run() {
snake.move();
if (snake.isAlive()==false){
Thread.currentThread().stop();
}
//吃食物
snake.addBody();
//重绘
JP.repaint();
}
};
//可根据getBody().size()设置蛇的速度,积分等
t.schedule(task,0, 100);
}
/**
* 对蛇行进的方向进行监听
*/
private void initDirectionListener() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
if (snake.getDirection() !=KeyEvent.VK_DOWN)
snake.setDirection(KeyEvent.VK_UP);
break;
case KeyEvent.VK_DOWN:
if (snake.getDirection() !=KeyEvent.VK_UP)
snake.setDirection(KeyEvent.VK_DOWN);
break;
case KeyEvent.VK_LEFT:
if (snake.getDirection() !=KeyEvent.VK_RIGHT)
snake.setDirection(KeyEvent.VK_LEFT);
break;
case KeyEvent.VK_RIGHT:
if (snake.getDirection() !=KeyEvent.VK_LEFT)
snake.setDirection(KeyEvent.VK_RIGHT);
break;
}
}
});
}
}
方格
package test1;
public class Grid {
private int x;
private int y;
public Grid() {
}
public Grid(int x, int y) {
this.x = x;
this.y = 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;
}
}
蛇
package test1;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;
public class Snake {
Random random = new Random();
//食物坐标为食物左上角坐标,最多只能在最下和右侧倒数第二格出现,不然出界
private int foodY = (random.nextInt(36)) * 10;
private int foodX = (random.nextInt(58)) * 10;
private LinkedList<Grid> body = new LinkedList();
private int direction = KeyEvent.VK_DOWN;
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
public Snake(){
body.add(new Grid(200,100));
body.add(new Grid(210,100));
body.add(new Grid(220,100));
body.add(new Grid(230,100));
body.add(new Grid(240,100));
body.add(new Grid(250,100));
body.add(new Grid(260,100));
}
public void setBody(LinkedList<Grid> body) {
this.body = body;
}
public LinkedList<Grid> getBody() {
return body;
}
/**
* 蛇随着键盘上下左右,而移动
*/
public void move(){
Grid first = body.getFirst();
switch (direction){
case KeyEvent.VK_UP:
body.addFirst(new Grid(first.getX(),first.getY() - 10));
body.removeLast();
break;
case KeyEvent.VK_DOWN:
body.addFirst(new Grid(first.getX(),first.getY() + 10));
body.removeLast();
break;
case KeyEvent.VK_LEFT:
body.addFirst(new Grid(first.getX() - 10,first.getY()));
body.removeLast();
break;
case KeyEvent.VK_RIGHT:
body.addFirst(new Grid(first.getX() + 10,first.getY()));
body.removeLast();
break;
}
}
/**
*判断蛇是否活着,即是否撞壁,撞自己
*/
public boolean isAlive(){
int y = body.getFirst().getY();
int x = body.getFirst().getX();
if (x<0 || y<0 || x>570 || y>350){//蛇头坐标为蛇头左上角坐标,最下和右侧倒数第二格碰撞就会死亡
return false;
}
for (int i = 3; i < body.size(); i++) {
Grid grid = body.get(i);
if (x == grid.getX() && y == grid.getY()){
return false;
}
}
return true;
}
/**
* 创建食物
* 食物如果出现在蛇身体上,则重新生成
*/
public int[] newFood(){
for (int i = 0; i < body.size(); i++) {
if (body.get(i).getX() == foodX && body.get(i).getY() == foodY){
//食物坐标为食物左上角坐标,最多只能在最下和右侧倒数第二格出现,不然出界
foodY = (random.nextInt(36)) * 10;
foodX = (random.nextInt(58)) * 10;
}
}
return new int[]{foodX,foodY};
}
/**
* 蛇吃食物增加身体
* a,在蛇尾添加:取蛇在刷新前的最后一节坐标,在刷新后加上
* b,另一种方法在头部添加:在迟到食物之后不.removeLast();
* 不是在键盘监听里写判断,这样会出现延迟。吃一个食物增加n节
* 另写一个方法在 move()调用
*/
public void addBody() {
if (body.getFirst().getX() == foodX && body.getFirst().getY() == foodY){
int bodyLastX = body.getLast().getX();
int bodyLastY = body.getLast().getY();
body.add(new Grid(bodyLastX,bodyLastY));
}
}
}
视频原解:小贤讲Java的个人空间_哔哩哔哩_bilibili