When designing the game , The first is to make a main interface Namely SnakeUI class , Modify the main interface in this class , Initialization of snake , Food initialization , Keyboard listening events ,

<>1,SnakeUI class
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import
java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.image.BufferedImage; import
javax.swing.JFrame; import javax.swing.JOptionPane; public class SnakeUI
extends JFrame implements KeyListener { private BufferedImage uiImg = new
BufferedImage(Constant.JFRAME_WIDTH, Constant.JFRAME_HEIGHT,
BufferedImage.TYPE_3BYTE_BGR); private Rectangle rec; private SNode food;
private Snake snake; // Defining snake objects private static int SPEED = Constant.SNAKE_NORMAL;
public SnakeUI() { this.rec = Constant.rec; this.food = new SNode(Color.BLUE);
this.snake = new Snake(this);// Initializes the snake object this.launchFrame(); } // Get the food of the current interface
public SNode getFood() { return food; } private void launchFrame() {
this.setTitle(" Greedy snake V0.1"); this.setBounds(200, 100, Constant.JFRAME_WIDTH,
Constant.JFRAME_HEIGHT); this.setVisible(true); this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); new Thread(new
UIUpdate()).start(); // Start update thread this.addKeyListener(this); // Monitor keyboard events } public
void paint(Graphics g) { // 1. Draw directly into the figure .g.drawRect Draw in flicker effect [ Undesirable ] //
2. Drawing graphics into cached images , Let's talk about drawing pictures into Frame in , Avoid flicker effect // Sets the color of the rectangle , And draw it into uiImg picture , Write this picture directly to memory Graphics2D
g2d = (Graphics2D) uiImg.getGraphics(); // Draw a white background in the cache image
g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, this.getWidth(),
this.getHeight()); // Set border color g2d.setColor(Color.BLACK); g2d.drawRect((int)
this.rec.getX(), (int) this.rec.getY(), (int) this.rec.getWidth(), (int)
this.rec.getHeight()); // Set middle square g2d.setColor(Color.CYAN); int startx = (int)
this.rec.getX(); int starty = (int) this.rec.getY(); for (int i = 0; i < 35;
i++) { for (int j = 0; j < 50; j++) { g2d.drawRect(startx + j *
Constant.FOOD_WIDTH, starty + i * Constant.FOOD_HEIGHT, Constant.FOOD_WIDTH,
Constant.FOOD_HEIGHT); } } // Set version text g2d.setColor(Color.RED); g2d.setFont(new
Font(" Song style ", Font.ITALIC, 16));// Set font g2d.drawString(" Version text 2019", 580, 530); //
Painting food , food paint Methods in the SNode Class definition , stay UI In the interface paint Method called this.food.paint(g2d); // Drawing snakes
this.snake.paint(g2d); // Snake eating food drawing : The snake is already eating food , Redefine a food object after the food has been eaten , And overlap with the snake's body if
(this.snake.eat(this.food)) { this.food = new SNode(Color.BLUE); while
(this.snake.hit(this.food)) { this.food = new SNode(Color.BLUE); } }
g.drawImage(uiImg, 0, 0, null); // Write to memory } public static void main(String[]
args) { new SnakeUI(); } @Override public void keyTyped(KeyEvent e) { // TODO
Auto-generated method stub } @Override // Press the keyboard to change the direction of the snake's movement public void
keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case
KeyEvent.VK_LEFT: snake.setDir(Constant.L); System.out.println("dddl"); break;
case KeyEvent.VK_RIGHT: snake.setDir(Constant.R); System.out.println("dddr");
break; case KeyEvent.VK_UP: snake.setDir(Constant.U);
System.out.println("dddu"); break; case KeyEvent.VK_DOWN:
snake.setDir(Constant.D); break; case KeyEvent.VK_W: SPEED =
Constant.SNAKE_ADD; break; case KeyEvent.VK_D: SPEED = Constant.SNAKE_NORMAL;
break; case KeyEvent.VK_S: SPEED = Constant.SNAKE_SUB; break; case
KeyEvent.VK_T: SPEED = Constant.SNAKE_SUPER; break; } } @Override public void
keyReleased(KeyEvent e) { SPEED = Constant.SNAKE_NORMAL; } // Threads that constantly refresh the interface class
UIUpdate implements Runnable { @Override public void run() { while
(SnakeUI.this.snake.isLive()) { System.out.println("..............thread....");
SnakeUI.this.repaint(); // In order to slow down the update speed , Set pause after each drawing 1 second . try { Thread.sleep(SPEED);
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace(); } } JOptionPane.showMessageDialog(SnakeUI.this, " Game crossing ,game
over."); } } }
<>2,Snake Snakes

Instantiate the snake class , Using a list The collection stores and displays the various parts of the snake ,
import java.awt.Color; import java.awt.Graphics2D; import java.util.ArrayList;
import java.util.List; import javax.swing.JOptionPane; public class Snake {
private SNode snakeHead; // Snakehead node private int startx, starty; // Coordinates of snake head private
List<SNode> nodes = new ArrayList<SNode>(); // The whole snake , from SNode Node composition : // Linear table List
private int dir; // position private boolean isLive = true; // The snake is running
// Add speed to snake , Every run 3 Pixels private int speed = 3; // getter.setter The direction of the snake public int
getDir() { return dir; } public void setDir(int dir) { this.dir = dir; } //
Enter the interface where the snake is located , Get the current food object through the interface public Snake(SnakeUI ui) { this.dir = Constant.U;
this.noOverride(ui.getFood()); } // The coordinates of randomly generated snake heads are not repeated with food public void
noOverride(SNode food) { this.generateSnake(); while (this.hit(food)) { //
Snakes overlap with food this.generateSnake(); } } private void generateSnake() { int x =
SNode.generate(50); // [0,49) int y = SNode.generate(35); if (x == 0) { x += 1;
} else if (x == 49) { x -= 1; } if (y == 0) { y += 1; } else if (y == 34) { y
-= 1; } this.startx = ((int) Constant.rec.getX() + x * Constant.FOOD_WIDTH);
this.starty = ((int) Constant.rec.getY() + y * Constant.FOOD_HEIGHT);
this.snakeHead = new SNode(this.startx, this.starty, Color.GREEN);
nodes.add(snakeHead); this.addNode(); // The default is 2 Nodes , Need to add again 1 Nodes } //
Determine whether the snake overlaps with food :true: overlap ,false: No overlap public boolean hit(SNode food) { boolean result
= false; for (SNode snode : nodes) { boolean res =
snode.getRec().intersects(food.getRec()); if (res) { result = true; break; } }
return result; } // Eating food public boolean eat(SNode food) { boolean result =
false; for (SNode snode : nodes) { boolean res =
snode.getRec().intersects(food.getRec()); if (res) { result = true; if
(nodes.size() >= 2) { // 1. Initial encounter ,2. Meet on the move this.addNode(); // Snake growth 1 } break; }
} return result; } // Add a node to the tail of the snake , It's related to the location of the snake private void addNode() { int size =
nodes.size(); switch (dir) { case Constant.L: // turn left , To the right, add 2 Nodes , And it didn't hit a wall if (size
== 1) { // The snake is still , You need to add a node to the snake tail int x = this.startx + Constant.FOOD_WIDTH; int y =
this.starty; SNode snode = new SNode(x, y, Color.GREEN); nodes.add(snode); //
Add to end of collection } else { int x = this.startx - Constant.FOOD_WIDTH; int y =
this.starty; SNode snode = new SNode(x, y, Color.GREEN); nodes.add(0, snode);
this.snakeHead = snode; this.startx = x; this.starty = y; // Judge the snake head to cross the border on the left if
(this.startx < Constant.rec.getX()) { this.isLive = false; } } break; case
Constant.R: if (size == 1) { // The snake is still , You need to add a node to the snake tail int x = this.startx -
Constant.FOOD_WIDTH; int y = this.starty; SNode snode = new SNode(x, y,
Color.GREEN); nodes.add(snode); // Add to end of collection } else { int x = this.startx +
Constant.FOOD_WIDTH; int y = this.starty; SNode snode = new SNode(x, y,
Color.GREEN); nodes.add(0, snode); this.snakeHead = snode; this.startx = x;
this.starty = y; // Judge the right crossing of the snake head if (this.startx > Constant.GAME_WIDTH) { this.isLive
= false; } } break; case Constant.U: if (size == 1) { // The snake is still , You need to add a node to the snake tail int x
= this.startx; int y = this.starty + Constant.FOOD_HEIGHT; SNode snode = new
SNode(x, y, Color.GREEN); nodes.add(snode); // Add to end of collection } else { int x =
this.startx; int y = this.starty - Constant.FOOD_HEIGHT; SNode snode = new
SNode(x, y, Color.GREEN); nodes.add(0, snode); this.snakeHead = snode;
this.startx = x; this.starty = y; // Judge whether the snake head is crossing the boundary if (this.starty <
Constant.rec.getY()) { this.isLive = false; } } break; case Constant.D: if
(size == 1) { // The snake is still , You need to add a node to the snake tail int x = this.startx; int y = this.starty -
Constant.FOOD_HEIGHT; SNode snode = new SNode(x, y, Color.GREEN);
nodes.add(snode); // Add to end of collection } else { int x = this.startx; int y = this.starty
+ Constant.FOOD_HEIGHT; // int y = this.starty + this.speed; SNode snode = new
SNode(x, y, Color.GREEN); nodes.add(0, snode); this.snakeHead = snode;
this.startx = x; this.starty = y; // Judge the snake head to cross the boundary if (this.starty >
((int)Constant.rec.getY()+ Constant.GAME_HEIGHT-Constant.FOOD_HEIGHT)) {
this.isLive = false; } } break; } } public boolean isLive() { return isLive; }
// Snake's movement , Constantly changing the snake head , Remove snake tail private void move() { this.addNode(); // Add a new node , Delete end node
int len = nodes.size(); nodes.remove(len - 1); } // Drawing snakes and their movements public void
paint(Graphics2D g2d) { // Yes nodes The nodes are drawn in turn
g2d.setColor(this.snakeHead.getColor()); // Draw the body of the snake for (SNode snode : nodes)
{ g2d.fillRect(snode.getX(), snode.getY(), Constant.FOOD_WIDTH,
Constant.FOOD_HEIGHT); } this.move(); } }
<>3,SNode Food

Designing food can also be said to be a simplification of snakes
import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle;
// Definition of food : public class SNode { private int x,y; // Starting coordinates of food , Relate to the starting point of the game private
Color color; // The color of food private Rectangle rec; // A rectangular area of food public Color getColor() {
return color; } public int getX() { // Read data return x; } public void setX(int x)
{ this.x = x; } public int getY() { return y; } public void setY(int y) {
this.y = y; } public Rectangle getRec() { return rec; } public void
setRec(Rectangle rec) { this.rec = rec; } // Randomly produce food in a certain location public SNode(Color
color) { this.x =
(int)Constant.rec.getX()+this.generate(50)*Constant.FOOD_WIDTH; this.y =
(int)Constant.rec.getY()+this.generate(35)*Constant.FOOD_HEIGHT; this.rec = new
Rectangle(this.x, this.y, Constant.FOOD_WIDTH, Constant.FOOD_HEIGHT);
this.color = color; } // Generate fixed location nodes , Used to produce snake heads public SNode(int x,int y,Color color)
{ this.x = x; this.y = y; this.color = color; this.rec = new Rectangle(this.x,
this.y, Constant.FOOD_WIDTH, Constant.FOOD_HEIGHT); } // Random number generation public static
int generate(int number) { //[0,numbder) int x = 0; x =
(int)(Math.random()*number); return x; } // Defining the way to draw food : Drawing method based on graphics cache Graphics2D public
void paint(Graphics2D g2d) { g2d.setColor(this.color); g2d.fillRect(this.x,
this.y, Constant.FOOD_WIDTH, Constant.FOOD_HEIGHT); } public static void
main(String[] args) { } }
<>4,Constant Constant class

Save the constants you need to use , It is convenient to modify the whole interface
import java.awt.Rectangle; public class Constant { public static final int
FOOD_WIDTH = 15; // Width and height of food public static final int FOOD_HEIGHT = 15; public
static final int GAME_WIDTH = FOOD_WIDTH*50; public static final int
GAME_HEIGHT = FOOD_HEIGHT*35; public static final int JFRAME_WIDTH =
FOOD_WIDTH*52; public static final int JFRAME_HEIGHT = FOOD_HEIGHT*38+6; public
static final int L=1,R=2,U=3,D=4; public static final int SNAKE_NORMAL = 500;
public static final int SNAKE_ADD = 180; public static final int SNAKE_SUPER =
50; public static final int SNAKE_SUB = 850; // Game grid area public static final
Rectangle rec = new Rectangle(FOOD_WIDTH, FOOD_HEIGHT*2+6, GAME_WIDTH,
GAME_HEIGHT); }

Technology
©2019-2020 Toolsou All rights reserved,
The 11th Blue Bridge Cup python The real topic of the University Group National Games JavaSwing To achieve a simple Lianliankan games 【Spring Source code analysis 】42-@Conditional Detailed explanation element-ui Step on pit record 2019PHP Interview questions ( Continuously updated )PHPJava Misunderstanding —— Method overloading is a manifestation of polymorphism ? First issue 500 100 million , Set up a new Department , What is Tencent going to do ? Google chrome The browser can't open the web page , But what if other browsers can open it ? Regression of dependent variable order categories (R language )【Golang Basic series 10 】Go language On conditional sentences if