0

I`ve been making a simple snake game. But sometimes when i run the application, the screen is just blank. I dont know why this is happening, can someone help me?

Heres the code (Please dont mind how bad it is, it`s like really bad)


import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Main {
    public static JFrame f = new JFrame("Snake");
    public static JPanel p = new Panel();

    public static void main(String[] args) {
        f.add(p);
        p.setVisible(true);
        //Gameloop obj = new Gameloop();
        //Thread thread = new Thread(obj);
        //thread.start();


        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("Timer happened!");
                Panel.Move();
                Main.p.repaint();
                Panel.CheckApple();
            }
        };
        new Timer(250, taskPerformer).start();

        /*
        todo:
        -game over X
        -fix screen not appearing bug
        -getting bigger X
        -cool features like different color apples or something like that X
         */
    }
}

that was my main class now my panel class :


import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Random;

public class Panel extends JPanel {
    //variables
    public static char Direction = 's';
    public static boolean bigger = false;
    public static int prevC, prevR;
    public static ArrayList<Integer> c = new ArrayList<Integer>();
    public static ArrayList<Integer> r = new ArrayList<Integer>();
    public static int length = 3;
    public static JFrame f = Main.f;
    public static int[][] Board = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
           /* Lol hi! */            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, };
    public static int[][] SBoard = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
    public static int[][] Apples = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
    //this code gets run when the panel gets made
    Panel() {
        //body
        r.add(0);
        c.add(0);
        r.add(1);
        c.add(2);
        r.add(2);
        c.add(2);
        //head
        r.add(3);
        c.add(2);
        //setup
        f.setBounds(0, 0, 1515, 1015);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setResizable(false);
        f.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                System.out.println(e.getKeyChar());
                //setting the direction
                if(e.getKeyChar() == 'w' || e.getKeyChar() == 'W') {
                    Direction = 'w';
                } else if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A') {
                    Direction = 'a';
                } else if(e.getKeyChar() == 's' || e.getKeyChar() == 'S') {
                    Direction = 's';
                } else if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D') {
                    Direction = 'd';
                }
            }
        });
        System.out.println("Constructor");
        PlaceNewApple();
    }

    protected void paintComponent(Graphics g) {
        //the grid is 20 long and 13 wide this code draws it
        //drawing the grid and apples and snakes and stuff
        for(int i = 0; i < 20; i++) {
            for(int j = 0; j < 13; j++) {
                //System.out.println((int) (Math.random()*(11-1)) + 1);
                if(Board[j][i] == 0) {
                    g.setColor(Color.black);
                    g.fillRect(i * 75, j * 75, 75, 75);
                } else if(Board[j][i] == 1) {
                    g.setColor(Color.blue);
                    g.fillRect(i * 75, j * 75, 75, 75);
                } else if(Board[j][i] == 2) {
                    g.setColor(Color.green);
                    g.fillRect(i * 75, j * 75, 75, 75);
                } else if(Board[j][i] == 3) {
                    //red apples
                    g.setColor(Color.black);
                    g.fillRect(i * 75, j * 75, 75, 75);
                    g.setColor(Color.red);
                    g.fillOval(i * 75 - 1, j * 75 - 1, 76, 76);
                } else if(Board[j][i] == 4) {
                    //yellow apples
                    g.setColor(Color.black);
                    g.fillRect(i * 75, j * 75, 75, 75);
                    g.setColor(Color.ORANGE);
                    g.fillOval(i * 75 - 1, j * 75 - 1, 76, 76);
                }
            }
        }
    }

    public static void PlaceNewApple() {
        Random rd = new Random();
        //getting rid of previous apples not necessary but just to be safe
        for(int i = 0; i < 20; i++) {
            for(int j = 0; j < 13; j++) {
                if(Board[j][i] == 3)
                    Board[j][i] = 0;
                    Apples[j][i] = 0;
            }
        }
        //making the random numbers
        int r = (int) (Math.random() * (13));
        int c = (int) (Math.random() * (20));
        //if what the apple is being placed on is a 0 do it else try again
        if(Board[r][c] == 0) {
            if(rd.nextBoolean()) { Board[r][c] = 3; } else { Board[r][c] = 4; }
            Apples[r][c] = 3;
        } else {PlaceNewApple();}
    }

    public static void DrawSnake() {
        //clearing
        for (int i = 0; i < 13; i++) {
            for (int j = 0; j < 20; j++) {
                if(Board[i][j] == 2) {
                    Board[i][j] = 0;
                }
            }
        }
        SBoard = new int[][] { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};


        //drawing snake

        for(int ij = 0; ij < r.size(); ij++) {
            try {
                SBoard[r.get(ij)][c.get(ij)] = 1;
                Board[r.get(ij)][c.get(ij)] = 2;
            }catch(ArrayIndexOutOfBoundsException e) {Lose();}
        }

        for (int i = 0; i < 13; i++) {
            for (int j = 0; j < 20; j++) {
                if(Apples[i][j] == 3) {
                    if(SBoard[i][j] != 1) {
                        SBoard[i][j] = 3;
                    }
                }
            }
        }

        for (int rs = 0; rs < 13; rs++) {
            for (int c = 0; c < 20; c++) {
                System.out.print(SBoard[rs][c] + " ");
            }
            System.out.println();
        }

    }

    public static void Move() {
        prevC = c.get(0);
        prevR = r.get(0);
        System.out.println("r = " + r);
        System.out.println("c = " + c);
        if(Direction == 'w') {
            for(int i = 0; i < length/*because we don't want to do the head*/; i++) {
                //if(i == length-1) {

                //}
                c.set(i, c.get(i+1));
                r.set(i, r.get(i+1));
            }
            //setting the head to new position
            System.out.println("Removing: c = " + c.get(length-1) + " r = " + r.get(length-1));
            c.add((c.get(length)));
            c.remove(length - 1);
            r.add((r.get(length))-1);
            r.remove(length - 1);


        } else if(Direction == 'a') {


            for(int i = 0; i < length/*because we don't want to do the head*/; i++) {
                c.set(i, c.get(i+1));
                r.set(i, r.get(i+1));
            }
            //setting the head to new position
            c.add((c.get(length))-1);
            c.remove(length - 1);
            r.add((r.get(length)));
            r.remove(length - 1);


        } else if(Direction == 's') {


            for(int i = 0; i < length/*because we don't want to do the head*/; i++) {
                c.set(i, c.get(i+1));
                r.set(i, r.get(i+1));
            }
            //setting the head to new position
            System.out.println("Removing: c = " + c.get(length-1) + " r = " + r.get(length-1) + " length = " + length);
            c.add((c.get(length)));
            c.remove(length - 1);
            r.add((r.get(length))+1);
            r.remove(length - 1);


        } else if(Direction == 'd') {


            for(int i = 0; i < length/*because we don't want to do the head*/; i++) {
                c.set(i, c.get(i+1));
                r.set(i, r.get(i+1));
            }
            //setting the head to new position
            c.add((c.get(length))+1);
            c.remove(length - 1);
            r.add((r.get(length)));
            r.remove(length - 1);
        }
        System.out.println("After updating:");
        System.out.println("r = " + r);
        System.out.println("c = " + c);

        //checking if you're supposed to go bigger
        if(bigger) {
            bigger = false;
            c.add(0, prevC);
            r.add(0, prevR);
            length++;
        }

        DrawSnake();
    }

    public static void CheckApple() {
        if(Apples[r.get(length)][c.get(length)] == 3 || Apples[r.get(length)][c.get(length)] == 4) {
            PlaceNewApple();
            bigger = true;
        }
        //also checking if you collide with your own body
        for(int i = 0; i < length; i++) {
            if(r.get(length).equals(r.get(i))) {
                if(c.get(length).equals(c.get(i))) {
                    Lose();
                }
            }
        }
    }

    public static void Lose() {
        System.exit(0);
    }


}

That's it! sorry it was to much code, but does anyone know how to fix this?

  • 2
    Swing operations must take place in the dedicated AWT event dispatch thread. You can’t use a new thread for your game loop. Use a [javax.swing.Timer](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/Timer.html) (not java.util.Timer!) instead, and remove your `sleep` call. – VGR Oct 02 '21 at 18:20
  • Yes, you are using a background thread, and that *may* be a good thing if done correctly, but you are also calling Swing methods from this background thread, not the EDT (the Swing Event Dispatch Thread), and this is most definitely a *very bad* thing. The solution is as @VGR suggests: use a [Swing Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html) instead. – Hovercraft Full Of Eels Oct 02 '21 at 18:36
  • Thx for the recommendation i now use a swing timer, but the problem still happens! Sometimes it works the other times it doesnt – idkwhattonamemyself Oct 02 '21 at 18:38
  • 1
    Meaning that you've still got a bug in your code, now code *not shown*, a very hard bug for anyone to help with. Either show your code or you must debug it yourself. You're not still using `Thread.sleep` anywhere or a `while` loop are you? – Hovercraft Full Of Eels Oct 02 '21 at 18:42
  • 1
    Side issue: your code uses a lot of static fields and methods suggesting that your design is off. If this were my code, the only things static would be constants, the main method and a few utility methods and that's it. All the rest would be and, more importantly, ***should*** be instance (non-static) – Hovercraft Full Of Eels Oct 02 '21 at 18:43
  • No im not using thread,sleep in a while loop, ill edit the original question to show the new code – idkwhattonamemyself Oct 02 '21 at 18:44
  • Wait but whats wrong with static methods? They always work for me? (btw i updated the original question with the new timer code) – idkwhattonamemyself Oct 02 '21 at 18:48
  • 1
    While static methods will probably work fine in small trivial applications like this one, if you scale up in size and complexity, even just a little bit, they are associated with an increase in code's cyclomatic complexity which greatly increases the risk of bugs. Please read [Why aren't static methods considered good OO practice?](https://stackoverflow.com/questions/4002201/why-arent-static-methods-considered-good-oo-practice) – Hovercraft Full Of Eels Oct 02 '21 at 18:51
  • Cool! Thx for telling me this! But you said that it works fine in small trivial applications like mine? But if it works fine then why is it broken? – idkwhattonamemyself Oct 02 '21 at 18:57
  • 1
    Because likely in 1 to 8 weeks, your class will advance into larger and more complex programs, or if you choose programming as a career, for the rest of your life you will be dealing with large and complex programs, and there you will be running into significant hard to fix issues of increased complexity, coupling and logical nightmares if you use mostly static fields and methods. Please see [Jon Skeet's summary on this issue](https://stackoverflow.com/a/7026563/522444) as well. – Hovercraft Full Of Eels Oct 02 '21 at 18:59
  • Ok i will try to not use static methods anymore thx for this information, but on topic again Could anyone please help me with why my code isnt working? because i used the timer recommended but it still doesnt work. (but seriously thx for telling this info about static methods) – idkwhattonamemyself Oct 02 '21 at 19:04

0 Answers0