Package com. hbsi;
Import java. awt .*;
Import java. awt. event .*;
Import javax. swing .*;
Import java. util .*;
// Main Class
Public class GreedSnake extends KeyAdapter {
JFrame mainFrame;
Canvas paintCanvas;
JLabel labelScore; // card count
Snake Model snkemodel = null; // snake
Public static final int DEFAULT_WIDTH = 500;
Public static final int DEFAULT_HEIGHT = 300;
Public static final int nodeWidth = 10;
Public static final int nodeHeight = 10;
// GreedSnake (): initializes the game interface
Public GreedSnake (){
// Set interface elements
MainFrame = new JFrame ("Snake games ");
Container cp = mainFrame. getContentPane ();
LabelScore = new JLabel ("score:", JLabel. CENTER );
Cp. add (labelScore, BorderLayout. NORTH );
PaintCanvas = new Canvas ();
PaintCanvas. setSize (DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1 );
PaintCanvas. addKeyListener (this );
Cp. add (paintCanvas, BorderLayout. CENTER );
JPanel panelButtom = new JPanel ();
PanelButtom. setLayout (new BorderLayout ());
JLabel labelHelp; // help information
LabelHelp = new JLabel ("press the PageUP or PageDown key to change the speed", JLabel. CENTER );
PanelButtom. add (labelHelp, BorderLayout. NORTH );
LabelHelp = new JLabel ("Press Enter or S to restart the game", JLabel. CENTER );
PanelButtom. add (labelHelp, BorderLayout. CENTER );
LabelHelp = new JLabel ("pause the game by pressing SPACE or P", JLabel. CENTER );
PanelButtom. add (labelHelp, BorderLayout. SOUTH );
Cp. add (panelButtom, BorderLayout. SOUTH );
MainFrame. addKeyListener (this );
MainFrame. pack ();
MainFrame. setResizable (false); // you can specify that the window size cannot be changed.
MainFrame. setdefaclocloseoperation (JFrame. EXIT_ON_CLOSE );
MainFrame. setVisible (true );
Begin ();
}
// KeyPressed (): Key Detection
Public void keyPressed (KeyEvent e ){
Int keyCode = e. getKeyCode ();
If (snkemodel. running)
Switch (keyCode ){
Case KeyEvent. VK_UP:
Snake model. changeDirection (Snake model. UP );
Break;
Case KeyEvent. VK_DOWN:
Snake model. changeDirection (Snake model. DOWN );
Break;
Case KeyEvent. VK_LEFT:
Snake model. changeDirection (Snake model. LEFT );
Break;
Case KeyEvent. VK_RIGHT:
Snake model. changeDirection (Snake model. RIGHT );
Break;
Case KeyEvent. VK_ADD:
Case KeyEvent. VK_PAGE_UP:
Snake model. speedUp (); // Acceleration
Break;
Case KeyEvent. VK_SUBTRACT:
Case KeyEvent. VK_PAGE_DOWN:
Snail kemodel. speedDown (); // slow down
Break;
Case KeyEvent. VK_SPACE:
Case KeyEvent. VK_P:
Snail kemodel. changePauseState (); // pause or continue
Break;
Default:
}
// Start again
If (keyCode = KeyEvent. VK_S | keyCode = KeyEvent. VK_ENTER ){
Snake model. running = false;
Begin ();
}
}
// Repaint (): draws the game interface (including snakes and food)
Void repaint (){
Graphics g = paintCanvas. getGraphics ();
// Draw background
G. setColor (Color. LIGHT_GRAY );
G. fillRect (0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT );
// Draw the snake
G. setColor (Color. BLACK );
Required list na = snakmodel. nodeArray;
Iterator it = na. iterator ();
While (it. hasNext ()){
Node n = (Node) it. next ();
DrawNode (g, n );
}
// Draw the food
G. setColor (Color. RED );
Node n = snake model. food;
DrawNode (g, n );
UpdateScore ();
}
// DrawNode (): Draw a node (snake or food)
Private void drawNode (Graphics g, Node n ){
G. fillRect (n. x * nodeWidth, n. y * nodeHeight, nodeWidth-1 );
}
// UpdateScore (): Change the score card
Public void updateScore (){
String s = "score:" + snail kemodel. score;
LabelScore. setText (s );
}
// Begin (): Start the game and place the snake.
Void begin (){
If (snail kemodel = null |! Snake model. running ){
Snapshomodel = new snapshomodel (this, DEFAULT_WIDTH/nodeWidth,
DEFAULT_HEIGHT/nodeHeight );
(New Thread (snail kemodel). start ();
}
}
// Main (): main Function
Public static void main (String [] args ){
GreedSnake gs = new GreedSnake ();
}
}
// Node: Node class
Class Node {
Int x;
Int y;
Node (int x, int y ){
This. x = x;
This. y = y;
}
}
// Snake Model: Snake Model
Class snakmodel implements Runnable {
GreedSnake gs;
Boolean [] [] matrix; // The interface data is saved in the array.
Repeated list nodeArray = new writable list ();
Node food;
Int maxX; // The maximum width.
Int maxY; // The maximum length.
Int direction = 2; // direction
Boolean running = false;
Int timeInterval = 200; // interval (speed)
Double speedChangeRate = 0.75; // speed change degree
Boolean paused = false; // game status
Int score = 0;
Int countMove = 0;
// UP and DOWN are even numbers, and RIGHT and LEFT are odd numbers.
Public static final int UP = 2;
Public static final int DOWN = 4;
Public static final int LEFT = 1;
Public static final int RIGHT = 3;
// GreedModel (): initialization Interface
Public snkemodel (GreedSnake gs, int maxX, int maxY ){
This. gs = gs;
This. maxX = maxX;
This. maxY = maxY;
Matrix = new boolean [maxX] [];
For (int I = 0; I <maxX; ++ I ){
Matrix [I] = new boolean [maxY];
Arrays. fill (matrix [I], false); // set false for regions without snakes or food
}
// Initialize the snake
Int initArrayLength = maxX> 20? 10: maxX/2;
For (int I = 0; I <initArrayLength; ++ I ){
Int x = maxX/2 + I;
Int y = maxY/2;
NodeArray. addLast (new Node (x, y ));
Matrix [x] [y] = true; // true
}
Food = createFood ();
Matrix [food. x] [food. y] = true; // true for food disposal
}
// ChangeDirection (): changes the direction of motion.
Public void changeDirection (int newDirection ){
If (direction % 2! = NewDirection % 2) {// avoid conflict
Direction = newDirection;
}
}
// MoveOn (): Snake Function
Public boolean moveOn (){
Node n = (Node) nodeArray. getFirst ();
Int x = n. x;
Int y = n. y;
Switch (direction ){
Case UP:
Y --;
Break;
Case DOWN:
Y ++;
Break;
Case LEFT:
X --;
Break;
Case RIGHT:
X ++;
Break;
}
If (0 <= x & x <maxX) & (0 <= y & y <maxY )){
If (matrix [x] [y]) {// eat food or hit your body
If (x = food. x & y = food. y) {// eat food
NodeArray. addFirst (food); // Add a node to the header
// Scoring rules are related to moving length and speed.
Int scoreGet = (10000-200 * countMove)/timeInterval;
Score + = scoreGet> 0? ScoreGet: 10;
CountMove = 0;
Food = createFood ();
Matrix [food. x] [food. y] = true;
Return true;
}
Else return false; // hit the body
}
Else {// nothing happened
NodeArray. addFirst (new Node (x, y); // Add the header
Matrix [x] [y] = true;
N = (Node) nodeArray. removeLast (); // remove the tail
Matrix [n. x] [n. y] = false;
CountMove ++;
Return true;
}
}
Return false; // cross-border (hitting the wall)
}
/* Sent out a code for the Snake game. Who can help me explain the running process and steps of the snake program */
// Run (): A snake motion thread
Public void run (){
Running = true;
While (running ){
Try {
Thread. sleep (timeInterval );
}
Catch (Exception e ){
Break;
}
If (! Paused ){
If (moveOn () {// not completed
Gs. repaint ();
}
Else {// game end
JOptionPane. showMessageDialog (null, "game over ",
"Game Over", JOptionPane. INFORMATION_MESSAGE );
Break;
}
}
}
Running = false;
}
// CreateFood (): generate food and place of place
Private Node createFood (){
Int x = 0;
Int y = 0;
Do {
Random r = new Random ();
X = r. nextInt (maxX );
Y = r. nextInt (maxY );
}
While (matrix [x] [y]);
Return new Node (x, y );
}
// SpeedUp (): speed up snake Movement
Public void speedUp (){
TimeInterval * = speedChangeRate;
}
// SpeedDown (): slow down the speed of snake Movement
Public void speedDown (){
TimeInterval/= speedChangeRate;
}
// ChangePauseState (): changes the game status (pause or continue)
Public void changePauseState (){
Paused =! Paused;
}
}