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,
Hundreds of millions of locusts rarely collide Locusts want to be self driving Heroes Share has surpassed Ningde Era !LG Chemical confirmation to spin off battery business unit TypeScript Data types in is enough Python Garbage collection and memory leak msf Generate Trojan horse attack android mobile phone Element-UI Implementation of secondary packaging TreeSelect Tree drop-down selection component element-ui+vue-treeselect Verification of drop down box Spring Boot Lesson 16 :SpringBoot Implementation of multithreading with injection class A guess number of small games , use JavaScript realization Unity3D Input Key system