Advertisement
LegendSujay2019

Snake game

Aug 24th, 2019
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.31 KB | None | 0 0
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4. import java.util.*;
  5.  
  6. public class Snake {
  7. // GUI components
  8. private JPanel board;
  9. private JButton[] snakeBodyPart;
  10. private JButton bonusfood;
  11. private JTextArea scoreViewer;
  12.  
  13. // Constants
  14. private final int SNAKE_RUNNING_SPEED_FASTEST = 25;
  15. private final int SNAKE_RUNNING_SPEED_FASTER = 50;
  16. private final int SNAKE_RUNNING_SPEED_FAST = 100;
  17. private final int BOARD_WIDTH = 500;
  18. private final int BOARD_HEIGHT = 250;
  19. private final int SCORE_BOARD_HEIGHT = 20;
  20. private final int SNAKE_LENGTH_DEFAULT = 4;
  21. private final int SNAKE_BODY_PART_SQURE = 10;
  22. private final int BONUS_FOOD_SQURE = 15;
  23. private final Point INIT_POINT = new Point(100, 150);
  24.  
  25. // Others values
  26. private enum GAME_TYPE {NO_MAZE, BORDER, TUNNEL};
  27. private int selectedSpeed = SNAKE_RUNNING_SPEED_FASTER;
  28. private GAME_TYPE selectedGameType = GAME_TYPE.NO_MAZE;
  29. private int totalBodyPart;
  30. private int directionX;
  31. private int directionY;
  32. private int score;
  33. private Point pointOfBonusFood = new Point();
  34. private boolean isRunningLeft;
  35. private boolean isRunningRight;
  36. private boolean isRunningUp;
  37. private boolean isRunningDown;
  38. private boolean isBonusFoodAvailable;
  39. private boolean isRunning;
  40. private Random random = new Random();
  41. this is where the game starts
  42.  
  43. Snake() {
  44.     //initialize all variables.
  45.     resetDefaultValues();
  46.     // initialize GUI.
  47.     init();
  48.     // Create Initial body of a snake.
  49.     createInitSnake();
  50.     // Initialize Thread.
  51.     isRunning = true;
  52.     createThread();
  53. }
  54. this is where the board is set up
  55.  
  56. public void init() {
  57.     JFrame frame = new JFrame("Snake");
  58.     frame.setSize(500, 330);
  59.  
  60.     //Create Menue bar with functions
  61.     setJMenueBar(frame);
  62.     // Start of UI design
  63.     JPanel scorePanel = new JPanel();
  64.     scoreViewer = new JTextArea("Score ==>" + score);
  65.     scoreViewer.setEnabled(false);
  66.     scoreViewer.setBackground(Color.BLACK);
  67.  
  68.     board = new JPanel();
  69.     board.setLayout(null);
  70.     board.setBounds(0, 0, BOARD_WIDTH, BOARD_HEIGHT);
  71.     board.setBackground(Color.WHITE);
  72.     scorePanel.setLayout(new GridLayout(0, 1));
  73.     scorePanel.setBounds(0, BOARD_HEIGHT, BOARD_WIDTH, SCORE_BOARD_HEIGHT);
  74.     scorePanel.setBackground(Color.RED);
  75.     scorePanel.add(scoreViewer); // will contain score board
  76.  
  77.     frame.getContentPane().setLayout(null);
  78.     frame.getContentPane().add(board);
  79.     frame.getContentPane().add(scorePanel);
  80.     frame.setVisible(true);
  81.     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  82.     frame.addKeyListener(new KeyAdapter() {
  83.         @Override
  84.         public void keyPressed(KeyEvent e) {
  85.             snakeKeyPressed(e);
  86.         }
  87.     });
  88.     frame.setResizable(false);
  89. }
  90. this is the menu
  91.  
  92. public void setJMenueBar(JFrame frame) {
  93.  
  94.     JMenuBar mymbar = new JMenuBar();
  95.  
  96.     JMenu game = new JMenu("Game");
  97.     JMenuItem newgame = new JMenuItem("New Game");
  98.     JMenuItem exit = new JMenuItem("Exit");
  99.     newgame.addActionListener(new ActionListener() {
  100.         public void actionPerformed(ActionEvent e) {
  101.             startNewGame();
  102.         }
  103.     });
  104.     exit.addActionListener(new ActionListener() {
  105.         public void actionPerformed(ActionEvent e) {
  106.             System.exit(0);
  107.         }
  108.     });
  109.     game.add(newgame);
  110.     game.addSeparator();
  111.     game.add(exit);
  112.     mymbar.add(game);
  113.  
  114.     JMenu type = new JMenu("Type");
  115.     JMenuItem noMaze = new JMenuItem("No Maze");
  116.     noMaze.addActionListener(new ActionListener() {
  117.         public void actionPerformed(ActionEvent e) {
  118.             selectedGameType = GAME_TYPE.NO_MAZE;
  119.             startNewGame();
  120.         }
  121.     });
  122.     JMenuItem border = new JMenuItem("Border Maze");
  123.     border.addActionListener(new ActionListener() {
  124.         public void actionPerformed(ActionEvent e) {
  125.             selectedGameType = GAME_TYPE.BORDER;
  126.             startNewGame();
  127.         }
  128.     });
  129.     type.add(noMaze);
  130.     type.add(border);
  131.     mymbar.add(type);
  132.  
  133.     JMenu level = new JMenu("Level");
  134.     JMenuItem level1 = new JMenuItem("Level 1");
  135.     level1.addActionListener(new ActionListener() {
  136.         public void actionPerformed(ActionEvent e) {
  137.             selectedSpeed = SNAKE_RUNNING_SPEED_FAST;
  138.             startNewGame();
  139.         }
  140.     });
  141.     JMenuItem level2 = new JMenuItem("Level 2");
  142.     level2.addActionListener(new ActionListener() {
  143.         public void actionPerformed(ActionEvent e) {
  144.             selectedSpeed = SNAKE_RUNNING_SPEED_FASTER;
  145.             startNewGame();
  146.         }
  147.     });
  148.     JMenuItem level3 = new JMenuItem("Level 3");
  149.     level3.addActionListener(new ActionListener() {
  150.         public void actionPerformed(ActionEvent e) {
  151.             selectedSpeed = SNAKE_RUNNING_SPEED_FASTEST;
  152.             startNewGame();
  153.         }
  154.     });
  155.     level.add(level1);
  156.     level.add(level2);
  157.     level.add(level3);
  158.     mymbar.add(level);
  159.  
  160.     JMenu help = new JMenu("Help");
  161.     JMenuItem creator = new JMenuItem("Creator");
  162.     JMenuItem instruction = new JMenuItem("Instraction");
  163.     creator.addActionListener(new ActionListener() {
  164.         public void actionPerformed(ActionEvent e) {                
  165.             JOptionPane.showMessageDialog(null, "Author: Jack Moffe");
  166.         }
  167.     });
  168.  
  169.     help.add(creator);
  170.     help.add(instruction);
  171.     mymbar.add(help);
  172.  
  173.     frame.setJMenuBar(mymbar);
  174. }
  175. this resets all the values
  176.  
  177. public void resetDefaultValues() {
  178.     snakeBodyPart = new JButton[2000];
  179.     totalBodyPart = SNAKE_LENGTH_DEFAULT;
  180.     directionX = SNAKE_BODY_PART_SQURE;
  181.     directionY = 0;
  182.     score = 0;
  183.     isRunningLeft = false;
  184.     isRunningRight = true;
  185.     isRunningUp = true;
  186.     isRunningDown = true;
  187.     isBonusFoodAvailable = false;
  188. }
  189.  
  190. void startNewGame() {
  191.     resetDefaultValues();
  192.     board.removeAll();
  193.     createInitSnake();
  194.     scoreViewer.setText("Score==>" + score);
  195.     isRunning = true;
  196. }
  197. This method is responsible to initialize the snake with four body part.
  198.  
  199. public void createInitSnake() {
  200.     // Location of the snake's head.
  201.     int x = (int) INIT_POINT.getX();
  202.     int y = (int) INIT_POINT.getY();
  203.  
  204.     // Initially the snake has three body part.
  205.     for (int i = 0; i < totalBodyPart; i++) {
  206.         snakeBodyPart[i] = new JButton();            
  207.         snakeBodyPart[i].setBounds(x, y, SNAKE_BODY_PART_SQURE, SNAKE_BODY_PART_SQURE);
  208.         snakeBodyPart[i].setBackground(Color.GRAY);
  209.         board.add(snakeBodyPart[i]);
  210.         // Set location of the next body part of the snake.
  211.         x = x - SNAKE_BODY_PART_SQURE;
  212.     }
  213.  
  214.     // Create food.
  215.     createFood();
  216. }
  217. This method is responsible to create food of a snake. The most last part of this snake is treated as a food, which has not become a body part of the snake yet. This food will be the body part if and only if when snake head will touch it.
  218.  
  219. void createFood() {
  220.     int randomX = SNAKE_BODY_PART_SQURE + (SNAKE_BODY_PART_SQURE * random.nextInt(48));
  221.     int randomY = SNAKE_BODY_PART_SQURE + (SNAKE_BODY_PART_SQURE * random.nextInt(23));
  222.  
  223.     snakeBodyPart[totalBodyPart] = new JButton();
  224.     snakeBodyPart[totalBodyPart].setEnabled(false);
  225.     snakeBodyPart[totalBodyPart].setBounds(randomX, randomY, SNAKE_BODY_PART_SQURE, SNAKE_BODY_PART_SQURE);
  226.     board.add(snakeBodyPart[totalBodyPart]);
  227.  
  228.     totalBodyPart++;
  229. }
  230.  
  231. private void createBonusFood() {
  232.     bonusfood = new JButton();
  233.     bonusfood.setEnabled(false);
  234.     //Set location of the bonus food.
  235.     int bonusFoodLocX = SNAKE_BODY_PART_SQURE * random.nextInt(50);
  236.     int bonusFoodLocY = SNAKE_BODY_PART_SQURE * random.nextInt(25);
  237.  
  238.     bonusfood.setBounds(bonusFoodLocX, bonusFoodLocY, BONUS_FOOD_SQURE, BONUS_FOOD_SQURE);
  239.     pointOfBonusFood = bonusfood.getLocation();
  240.     board.add(bonusfood);
  241.     isBonusFoodAvailable = true;
  242. }
  243. Process next step of the snake. And decide what should be done. ie what the snake is doing and how to respond
  244.  
  245. void processNextStep() {
  246.     boolean isBorderTouched = false;
  247.     // Generate new location of snake head.
  248.     int newHeadLocX = (int) snakeBodyPart[0].getLocation().getX() + directionX;
  249.     int newHeadLocY = (int) snakeBodyPart[0].getLocation().getY() + directionY;
  250.  
  251.     // Most last part of the snake is food.
  252.     int foodLocX = (int) snakeBodyPart[totalBodyPart - 1].getLocation().getX();
  253.     int foodLocY = (int) snakeBodyPart[totalBodyPart - 1].getLocation().getY();
  254.  
  255.     // Check does snake cross the border of the board?
  256.     if (newHeadLocX >= BOARD_WIDTH - SNAKE_BODY_PART_SQURE) {
  257.         newHeadLocX = 0;
  258.         isBorderTouched = true;
  259.     } else if (newHeadLocX <= 0) {
  260.         newHeadLocX = BOARD_WIDTH - SNAKE_BODY_PART_SQURE;
  261.         isBorderTouched = true;
  262.     } else if (newHeadLocY >= BOARD_HEIGHT - SNAKE_BODY_PART_SQURE) {
  263.         newHeadLocY = 0;
  264.         isBorderTouched = true;
  265.     } else if (newHeadLocY <= 0) {
  266.         newHeadLocY = BOARD_HEIGHT - SNAKE_BODY_PART_SQURE;
  267.         isBorderTouched = true;
  268.     }
  269.  
  270.     // Check has snake touched the food?
  271.     if (newHeadLocX == foodLocX && newHeadLocY == foodLocY) {
  272.         // Set score.
  273.         score += 5;
  274.         scoreViewer.setText("Score==>" + score);
  275.  
  276.         // Check bonus food should be given or not?
  277.         if (score % 50 == 0 && !isBonusFoodAvailable) {
  278.             createBonusFood();
  279.         }
  280.         // Create new food.
  281.         createFood();
  282.     }
  283.  
  284.     // Check has snake touched the bonus food?
  285.     if (isBonusFoodAvailable &&
  286.             pointOfBonusFood.x <= newHeadLocX &&
  287.             pointOfBonusFood.y <= newHeadLocY &&
  288.             (pointOfBonusFood.x + SNAKE_BODY_PART_SQURE) >= newHeadLocX &&
  289.             (pointOfBonusFood.y + SNAKE_BODY_PART_SQURE) >= newHeadLocY) {
  290.         board.remove(bonusfood);
  291.         score += 100;
  292.         scoreViewer.setText("Score ==>" + score);
  293.         isBonusFoodAvailable = false;
  294.     }
  295.  
  296.     // Check is game over?
  297.     if(isGameOver(isBorderTouched, newHeadLocX, newHeadLocY)) {
  298.        scoreViewer.setText("GAME OVER   " + score);
  299.        isRunning = false;
  300.        return;
  301.     } else {
  302.         // Move the whole snake body to forword.
  303.         moveSnakeForword(newHeadLocX, newHeadLocY);
  304.     }
  305.  
  306.     board.repaint();
  307. }
  308. This method is responsible to detect is game over or not? Game should be over while snake is touched by any maze or by itself.
  309.  
  310. private boolean isGameOver(boolean isBorderTouched, int headLocX, int headLocY) {
  311.     switch(selectedGameType) {
  312.         case BORDER:
  313.             if(isBorderTouched) {
  314.                 return true;
  315.             }
  316.             break;
  317.         case TUNNEL:
  318.             // TODO put logic here...
  319.             throw new UnsupportedOperationException();
  320.         default:
  321.             break;
  322.     }
  323.  
  324.     for (int i = SNAKE_LENGTH_DEFAULT; i < totalBodyPart - 2; i++) {
  325.         Point partLoc = snakeBodyPart[i].getLocation();
  326.         System.out.println("("+partLoc.x +", "+partLoc.y+")  ("+headLocX+", "+headLocY+")");
  327.         if (partLoc.equals(new Point(headLocX, headLocY))) {
  328.             return true;
  329.         }
  330.     }
  331.  
  332.     return false;
  333. }
  334.  
  335. /**
  336.  * Every body part should be placed to location of the front part.
  337.  * For example if part:0(100,150) , part: 1(90, 150), part:2(80,150) and new head location (110,150) then,
  338.    Location of part:2 should be (80,150) to (90,150), part:1 will be (90,150) to (100,150) and part:3 will be (100,150) to (110,150)
  339.  * This movement process should be start from the last part to first part.
  340.  * We must avoid the food that means most last body part of the snake.
  341.  * Notice that we write (totalBodyPart - 2) instead of (totalBodyPart - 1).
  342.  * (totalBodyPart - 1) means food and (totalBodyPart - 2) means tail.
  343.  * @param headLocX
  344.  * @param headLocY
  345.  */
  346. public void moveSnakeForword(int headLocX, int headLocY) {
  347.     for (int i = totalBodyPart - 2; i > 0; i--) {
  348.         Point frontBodyPartPoint = snakeBodyPart[i - 1].getLocation();
  349.         snakeBodyPart[i].setLocation(frontBodyPartPoint);
  350.     }
  351.     snakeBodyPart[0].setBounds(headLocX, headLocY, SNAKE_BODY_PART_SQURE, SNAKE_BODY_PART_SQURE);
  352. }
  353.  
  354. public void snakeKeyPressed(KeyEvent e) {
  355.     // snake should move to left when player pressed left arrow
  356.     if (isRunningLeft == true && e.getKeyCode() == 37) {
  357.         directionX = -SNAKE_BODY_PART_SQURE; // means snake move right to left by 10 pixel
  358.         directionY = 0;
  359.         isRunningRight = false;     // means snake cant move from left to right
  360.         isRunningUp = true;         // means snake can move from down to up
  361.         isRunningDown = true;       // means snake can move from up to down
  362.     }
  363.     // snake should move to up when player pressed up arrow
  364.     if (isRunningUp == true && e.getKeyCode() == 38) {
  365.         directionX = 0;
  366.         directionY = -SNAKE_BODY_PART_SQURE; // means snake move from down to up by 10 pixel
  367.         isRunningDown = false;     // means snake can move from up to down
  368.         isRunningRight = true;     // means snake can move from left to right
  369.         isRunningLeft = true;      // means snake can move from right to left
  370.     }
  371.     // snake should move to right when player pressed right arrow
  372.     if (isRunningRight == true && e.getKeyCode() == 39) {
  373.         directionX = +SNAKE_BODY_PART_SQURE; // means snake move from left to right by 10 pixel
  374.         directionY = 0;
  375.         isRunningLeft = false;
  376.         isRunningUp = true;
  377.         isRunningDown = true;
  378.     }
  379.     // snake should move to down when player pressed down arrow
  380.     if (isRunningDown == true && e.getKeyCode() == 40) {
  381.         directionX = 0;
  382.         directionY = +SNAKE_BODY_PART_SQURE; // means snake move from left to right by 10 pixel
  383.         isRunningUp = false;
  384.         isRunningRight = true;
  385.         isRunningLeft = true;
  386.     }
  387. }
  388.  
  389. private void createThread() {
  390.     // start thread
  391.     Thread thread = new Thread(new Runnable() {
  392.  
  393.         public void run() {
  394.             runIt();
  395.         }
  396.     });
  397.     thread.start(); // go to runIt() method
  398. }
  399.  
  400. public void runIt() {
  401.     while (true) {
  402.         if(isRunning) {
  403.             // Process what should be next step of the snake.
  404.             processNextStep();
  405.             try {
  406.                 Thread.sleep(selectedSpeed);
  407.             } catch (InterruptedException ie) {
  408.                 ie.printStackTrace();
  409.             }
  410.         }
  411.     }
  412. }
  413. }
  414. Main class:
  415. public class Main {
  416. /**
  417.  * @param args the command line arguments
  418.  */
  419. public static void main(String[] args) {
  420.     new Snake();
  421. }
  422. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement