0

I have a strange problem. The g.drawString() does not work within an if-statement. It does outside the if-statement. I have tried System.out.print("TEST") within the if-statement. This works. If I however, add the drawString method, only the printing of Test works

    private void render() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
        createBufferStrategy(3);
        return;
    }

    Graphics g = bs.getDrawGraphics();

    g.setColor(Color.GREEN);
    g.fillRect(0, 0, WIDTH, HEIGHT);

    g.setColor(Color.BLACK);

    g.drawString("Score: " + score + " Tail: " + tailLength, 20, 10);

    // g.drawString("TEST", 0, 10);  Works

    if(gameover) g.drawString("TEST", 0, 10); // System.out.println("TEST"); works fine
    snake.render(g);
    cherry.render(g);

    g.dispose();
    bs.show();
}

Whole code:

package snake;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class Game extends Canvas implements Runnable, KeyListener {

    private static final int WIDTH = 400, HEIGHT = 350, SCALE = 10;
    private static final String TITLE = "Snake";

    private Thread thread;

    private Snake snake;
    private Cherry cherry;
    private Random random = new Random();

    private int score, tailLength;

    private boolean running = false, paused = false, gameover = false;

    // ///////////// WINDOW //////////////////////
    class Window {
        Window(Game game) {
            Dimension dim = new Dimension(WIDTH, HEIGHT);
            game.setPreferredSize(dim);
            game.setMaximumSize(dim);
            game.setMinimumSize(dim);

            JFrame frame = new JFrame(TITLE);
            frame.add(game);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(true);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            game.startGame();
        }

    }

    // //////////////// SNAKE ////////////////////////
    class Snake {

        Point head;
        Direction direction;
        int x, y;
        ArrayList<Point> snakeParts = new ArrayList<Point>();

        public Snake(int x, int y) {
            this.x = x;
            this.y = y;
            head = new Point(x, y);
            direction = Direction.DOWN;
        }

        void tick() {

            switch (direction) {
            case UP:
                head = new Point(x, y--);
                break;
            case DOWN:
                head = new Point(x, y++);
                break;
            case LEFT:
                head = new Point(x--, y);
                break;
            case RIGHT:
                head = new Point(x++, y);
                break;
            }
            snakeParts.add(head);
            if (x == cherry.x && y == cherry.y) {
                cherry = new Cherry();
                score += 10;
                tailLength++;
            } else {
                snakeParts.remove(0);
            }

            if (x < 0 || y < 0 || x * SCALE + SCALE > WIDTH
                    || y * SCALE + SCALE > HEIGHT) {
                gameover = true;
            }

            for (Point point : snakeParts) {
                if (x == point.getLocation().x && y == point.getLocation().y) {
                    gameover = true;
                }
            }
        }

        void render(Graphics g) {
            g.setColor(Color.BLUE);
            g.fillRect(x * SCALE, y * SCALE, SCALE, SCALE);

            for (Point point : snakeParts) {
                g.fillRect(point.getLocation().x * SCALE, point.getLocation().y
                        * SCALE, SCALE, SCALE);
            }
        }

    }

    // /////////// CHERRY //////////////////
    class Cherry {
        int x, y;

        public Cherry() {
            x = random.nextInt(WIDTH / SCALE);
            y = random.nextInt(HEIGHT / SCALE);
        }

        public void render(Graphics g) {
            g.setColor(Color.RED);
            g.fillRect(x * SCALE, y * SCALE, SCALE, SCALE);
        }
    }

    // ////////////////// DIRECTION ////////////////////////

    public enum Direction {
        UP, DOWN, LEFT, RIGHT;
    }

    // //////////////// GAME METHODS ////////////////////////
    public static void main(String args[]) {
        Game game = new Game();
        game.addKeyListener(game);
        game.new Window(game);
    }

    public void startGame() {
        thread = new Thread(this);
        thread.start();
        tailLength = 0;
        score = 0;
        gameover = false;

    }

    @Override
    public void run() {
        init();
        // Tells me when the lastTime when I started the loop
        long lastTime = System.nanoTime();

        // Time the thread took for a loop
        long loopTime = 0;
        // FPS
        double amountOfTicks = 10.0;

        // Optimal time per frame
        double ns = 1000000000 / amountOfTicks;

        // Time difference as a percentage of the optimal time per frame. Above
        // 1 means that the loop was slower than the optimal time.
        // Multiply an animation by that time to make up for the loss of time,
        double delta = 0;

        // To time when the loop has begun
        long timer = System.currentTimeMillis();

        // To keep an eye on the amount of updates and frames in a second
        int updates = 0;
        int frames = 0;

        // As long as the game is running.
        while (running) {
            // Curent time of the new loop
            long now = System.nanoTime();

            // Calculate the looptime/ time for 1 frame
            loopTime = (now - lastTime);

            // What percentage as the loopTime of the optimal time
            delta += loopTime / ns;

            // Reset lastTime
            lastTime = now;

            if (!gameover) {
                // As long as the delta is higher then one, tick.
                while (delta >= 1) {
                    // tick is the method that updates all calculations
                    tick();
                    updates++;
                    delta--;
                }
                // This is the method that draws
                render();
                frames++;
            }
            // When the loop is working for a second do this
            if (System.currentTimeMillis() - timer > 1000) {

                // Add a second to the timer, to make sure the new second has
                // begun and can be checked.
                timer += 1000;

                // Reset the frames and updates per second.
                frames = 0;
                updates = 0;
            }
        }
    }

    private void init() {
        snake = this.new Snake(0, 0);
        cherry = this.new Cherry();
        running = true;
    }

    private void tick() {
        if (!paused) {
            snake.tick();
        }
    }

    private void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }

        Graphics g = bs.getDrawGraphics();

        g.setColor(Color.GREEN);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        g.setColor(Color.BLACK);

        g.drawString("Score: " + score + " Tail: " + tailLength, 20, 10);

        // g.drawString("TEST", 0, 10); Works

        if (gameover)
            g.drawString("TEST", 0, 10); // System.out.println("TEST"); works
                                            // fine
        snake.render(g);
        cherry.render(g);

        g.dispose();
        bs.show();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_W:
            if (snake.direction != Direction.DOWN && !paused) {
                snake.direction = Direction.UP;
            }
            break;
        case KeyEvent.VK_S:
            if (snake.direction != Direction.UP && !paused) {
                snake.direction = Direction.DOWN;
            }
            break;
        case KeyEvent.VK_D:
            if (snake.direction != Direction.LEFT && !paused) {
                snake.direction = Direction.RIGHT;
            }
            break;
        case KeyEvent.VK_A:
            if (snake.direction != Direction.RIGHT && !paused) {
                snake.direction = Direction.LEFT;
            }
            break;
        case KeyEvent.VK_SPACE:
            if (gameover) {
                startGame();
            } else {
                if (paused) {
                    paused = false;
                } else {
                    paused = true;
                }
            }
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

PS. I am new to coding. So any tips are welcome :)

  • @Kayaman Except that all `dispose` does it disposes of any native resources or properties which where been used by the `Graphics` context, what was "drawn" to the context should still exist. But admittedly, I'd be interested to know more about the management with `BufferStrategy` – MadProgrammer Jun 30 '15 at 11:08
  • The state is only getting painting while the game is NOT over, once it's over, you stop painting...You need to continue rendering the screen (or a different screen) even while the game is over. Try this, allow the game to end and resize the screen, the whole content vanishes, because you are no longer painting it. Move render outside of the `if (!gameover) {` block of your main loop and you should see a difference – MadProgrammer Jun 30 '15 at 11:12
  • I withdraw my claim, it seems that it should work with `BufferStrategy`. – Kayaman Jun 30 '15 at 11:12
  • After putting the render() method call outside the if-statement it works. Thanks! – Jos IJntema Jun 30 '15 at 13:18

0 Answers0