0

I made a snake game following a youtube tutorial. The game has two states: either "RUNNING" when you start the game and play or "END" when you die. To play the game again you have to close the window and run the code again. I would like to make the game start again when i hit the ENTER key on the "END" screen. Ill attack some of the code and any help is appreciated.

this is the code for the GameUI

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import java.awt.Toolkit;

public class GameUI 

// This is the code for the GameUI

implements KeyListener{
    private Snake player;
    
    private Food food;
    private Drawing drawing;
    private Superfood sfood;
    
    private JFrame panel;
    private ImageIcon icon;
    
    
    
    public static final int width = 20;
    public static final int height = 20;
    public static final int dimension = 30;
    
    public GameUI() {
        
        // definde the Jframe within which the game is played
        
        panel = new JFrame();
        
        player = new Snake();
        
        food = new Food(player);
        
        sfood = new Superfood(player);
        
        drawing = new Drawing(this);
        
        panel.getContentPane().add(drawing);
        
        panel.setTitle("Cryptic Snake v1");
        panel.setSize(width * dimension + 2, height * dimension + dimension + 4);
        panel.setVisible(true);
        panel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        icon = new ImageIcon("images/SNAKE.png");
        panel.setIconImage(Toolkit.getDefaultToolkit().getImage(GameUI.class.getResource("/images/SNAKE.png")));
                
    }
    
    public void start() {
        drawing.state = "RUNNING"; //set state to running and initiate the game
    }
    
    // with this if else loop we can manage the game
    
    public void checker() {
        if(drawing.state == "RUNNING") {  // given that the game is running...
            if(foodcrash()) {
                player.grow();               // call grow-method when snake bumps into food
                food.random_spawn(player);      // and spawn new food
            }
            if(sfoodcrash()) {
                player.grow();  
                player.grow(); 
                player.grow(); 
                // call grow-method when snake bumps into food
                food.random_spawn(player);      // and spawn new food
            }
            else if(wallcrash() || autocrash()) { //end the game if the snake bumps into itself or a wall
                drawing.state = "END";
            }
            else {
                player.move();
            }
        }
    }
    
    //here we check if the snake is bumping into a wall
    
    private boolean wallcrash() {
        if(player.getX() < 0 || player.getX() >= width * dimension 
                || player.getY() < 0|| player.getY() >= height * dimension) {
            return true;
        }
        return false;
    }
    
    // here we check if the snake is bumping into food
    
    private boolean foodcrash() {
        if(player.getX() == food.getX() * dimension && player.getY() == food.getY() * dimension) {
            return true;
        }
        return false;
    }
    
    // here we check if the snake is bumping into food
    
        private boolean sfoodcrash() {
            if(player.getX() == sfood.getSx() * dimension && player.getY() == sfood.getSy() * dimension) {
                return true;
            }
            return false;
        }
    
    // here we check has bumped into itself
    
    private boolean autocrash() {
        for(int i = 1; i < player.getSnk().size(); i++) {
            if(player.getX() == player.getSnk().get(i).x &&
                    player.getY() == player.getSnk().get(i).y) {
                return true;
            }
        }
        return false;
    }

    // now we add a keylistener that listens to the inputs on our keyboard
    
    @Override
    public void keyTyped(KeyEvent e) {  }

    @Override
    public void keyPressed(KeyEvent e) {
        
        int keyCode = e.getKeyCode();
        
        if(drawing.state == "RUNNING") {
            if(keyCode == KeyEvent.VK_UP && player.getMove() != "UP") { // up-arrow-key
                player.up();
            }
        
            if(keyCode == KeyEvent.VK_DOWN && player.getMove() != "DOWN") { // down-arrow-key
                player.down();
            }
        
            if(keyCode == KeyEvent.VK_LEFT && player.getMove() != "LEFT") { //left-arrow-key
                player.left();
            }
        
            if(keyCode == KeyEvent.VK_RIGHT && player.getMove() != "RIGHT") {//right-arrow-key
                player.right();
            }
            
            

        }
        
        else {
            this.start();}
                
            
        
    }

    @Override
    public void keyReleased(KeyEvent e) {   }

    //auto-generated getters and setters
    
    public Snake getPlayer() {
        return player;
    }

    public void setPlayer(Snake player) {
        this.player = player;
    }

    public Food getFood() {
        return food;
    }

    public void setFood(Food food) {
        this.food = food;
    }

    public JFrame getPanel() {
        return panel;
    }

    public Superfood getSfood() {
        return sfood;
    }

    public void setSfood(Superfood sfood) {
        this.sfood = sfood;
    }

    public void setPanel(JFrame window) {
        this.panel = window;
    }

    public Drawing getGraphics() {
        return drawing;
    }

    public static int getWidth() {
        return width;
    }

    public static int getHeight() {
        return height;
    }

    public static int getDimension() {
        return dimension;
    }

    public void setGraphics(Drawing drawing) {
        this.drawing = drawing;
    }

    

    
    
    
}

this is the code for the drawing class

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.awt.Font;

import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import java.awt.SystemColor;

//this code is responsible for the graphics, so everything you see on the screen
// we use a paint component that redraws everything within a given time interval

public class Drawing
extends JPanel
implements ActionListener  {
    private Timer t = new Timer(100, this); //we want to redraw the screen every 100 milliseconds, this defindes speed of snake
    public String state; // we use states as there are two different situations: either the game is running or you died
    
    
    private Superfood sf;
    private Snake s;
    private Food f;
    
    private GameUI gameUI;
    
    public Drawing(GameUI g) {
        setBackground(SystemColor.activeCaptionBorder);
        t.start();
        state = "RUNNING";
        
        gameUI = g;
        s = g.getPlayer();
        f = g.getFood();
        sf= g.getSfood();
        
        
        
        //add a keyListner 
        this.addKeyListener(g);
        this.setFocusable(true);
        this.setFocusTraversalKeysEnabled(false);
        GroupLayout groupLayout = new GroupLayout(this);
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGap(0, 450, Short.MAX_VALUE)
        );
        groupLayout.setVerticalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGap(0, 300, Short.MAX_VALUE)
        );
        setLayout(groupLayout);
    }
    
    public void paintComponent(java.awt.Graphics g) {
        super.paintComponent(g);
        
        
        Font font = new Font("Playbill", 10,50);
        Font sfont = new Font("Perpetua Titling MT", 10,30);
        
        Graphics2D g2d = (Graphics2D) g; //make it 2D
        
        //drawing the background
        
        g2d.setColor(Color.gray);
        g2d.fillRect(0, 0, GameUI.width * GameUI.dimension + 5, GameUI.height * GameUI.dimension + 5);
    
    
        if(state == "RUNNING") { // drawing the food in the case that the game is running
            g2d.setColor(Color.cyan);
            g2d.fillOval(f.getX() * GameUI.dimension, f.getY() * GameUI.dimension, GameUI.dimension, GameUI.dimension);
        
            g2d.setColor(Color.BLUE);
            if (s.getSnk().size() % 5 == 0)
            
            g2d.fillRoundRect(sf.getSx() * GameUI.dimension, sf.getSy() * GameUI.dimension, GameUI.dimension, GameUI.dimension,12,12);
            
        
            g2d.setColor(Color.DARK_GRAY); //drawing the snake in the case the the game is runnng
            for(Rectangle r : s.getSnk()) {
                g2d.fill(r);
            }
        }
        
        
        else { //if the game is not running display the score
            g2d.setColor(Color.DARK_GRAY);
            g2d.setFont(sfont);
            g2d.drawString("Your score was", GameUI.width/2 * GameUI.dimension - 175, GameUI.height / 2 * GameUI.dimension - 25);
            g2d.setFont(font);
            g2d.drawString("" + (s.getSnk().size() ), GameUI.width/2 * GameUI.dimension + 117, GameUI.height / 2 * GameUI.dimension - 20);
            
            
            
        }
            
        
        

        
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
        gameUI.checker(); //check if the snake is bumping into a wall itself or food or nothing to determine what to draw next
    }
}
greg-449
  • 109,219
  • 232
  • 102
  • 145
Gus
  • 1
  • 2
    You'd basically need to listen for the Enter key being pressed (or better use a button) and reinitialize your game objects, which I assume are `player`, `food` and `superfood`. Once that's done a call to `start()` might do the trick. Ideally, try to separate your game model from your rendering/UI. Once you've done that all you'd need to do is reset your game model. – Thomas Jul 01 '21 at 14:20
  • 3
    Sidenote: This is not how you compare `String`s in java: `if(state == "RUNNING")`. This can be observed multiple times throughout your code. See [How do I compare Strings in Java?](https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) However, the state smells like it should actually be an `Enum`. Same for `player.getMove() != "UP"`, which is also incorrectly compared, but the "move" should most likely also be changed to an `Enum`. – maloomeister Jul 01 '21 at 14:22
  • ok thank you. ive added the keylistner that prints out a string when i hit enter (which works), but when i add this.start(); still nothing happens. i know that i have to reset all my objects but for now i need to find a way to set the state to "RUNNING" again. – Gus Jul 01 '21 at 14:29
  • *"ok thank you."* Thank who? Tip: Add @Thomas (or whoever, the `@` is important) to *notify* the person of a new comment. – Andrew Thompson Aug 16 '21 at 19:29

1 Answers1

0

I had something similar and I did this:

button.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e) {
                Main.frame.dispose();
                new Main();
                }
        });

where the Main is a class you initializing the frame in it.

hamid
  • 9
  • 7