简体   繁体   中英

drawString() isn't drawing the String on my game

I am using drawString() to write text on the string, but nothing shows up. I set the color to white and set the coordinates to (100,100). Is there anything else that I am doing wrong?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;

public class Screen extends JPanel implements Runnable {

    private static final long serialVersionUID = 1L;

    public static final int WIDTH = 800, HEIGHT = 800;
    private Thread thread;
    private boolean running = false;

    private BodyPart b;
    private ArrayList<BodyPart> snake;

    private Apple apple;
    private ArrayList<Apple> apples;

    private Random r;

    private int xCoor = 20, yCoor = 20;
    private int size = 10;
    private int score = 0;

    private boolean right = true, left = false, up = false, down = false;

    private int ticks = 0;

    private Key key;

    public Screen() {
        setFocusable(true);
        key = new Key();
        addKeyListener(key);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));

        r = new Random();

        snake = new ArrayList<BodyPart>();
        apples = new ArrayList<Apple>();

        start();
    }

    public void reset() {
        snake.clear();
        apples.clear();
        xCoor = 20;
        yCoor = 20;
        size = 10;
        score = 0;
        running = true;
    }

    public void tick() {
        if(snake.size() == 0) {
            b = new BodyPart(xCoor, yCoor, 20);
            snake.add(b);
        }

        if(apples.size() == 0) {
            int xCoor = r.nextInt(40);
            int yCoor = r.nextInt(40);

            apple = new Apple(xCoor, yCoor, 20);
            apples.add(apple);
        }

        for(int i = 0; i < apples.size(); i++) {
            if(xCoor == apples.get(i).getxCoor() && yCoor ==  apples.get(i).getyCoor()) {
                size++;
                apples.remove(i);
                score += 10;
                i--;
            }
        }

        for(int i = 0; i < snake.size(); i++) {
            if(xCoor == snake.get(i).getxCoor() && yCoor ==  snake.get(i).getyCoor()) {
                if(i != snake.size() - 1) {
                    reset();
                }
            }
        }

        if(xCoor < 0) xCoor = 40;
        if(xCoor > 40) xCoor = 0;
        if(yCoor < 0) yCoor = 40;
        if(yCoor > 40) yCoor = 0;

        ticks++;

        if(ticks > 250000) {
            if(right) xCoor++;
            if(left) xCoor--;
            if(up) yCoor--;
            if(down) yCoor++;

            ticks = 185000;

            b = new BodyPart(xCoor, yCoor, 20);
            snake.add(b);

            if(snake.size() > size) {
                snake.remove(0);
            }
        }
    }

    public void paint(Graphics g) {
        g.clearRect(0, 0, WIDTH, HEIGHT);

        g.drawString("Score: " + score, 100, 100);
            g.setColor(Color.WHITE);

        g.setColor(new Color(20, 50, 0));
        g.fillRect(0, 0, WIDTH, HEIGHT);

        g.setColor(Color.BLACK);
        for(int i = 0; i < WIDTH / 20; i++) {
            g.drawLine(i * 20, 0, i * 20, HEIGHT);
        }

        for(int i = 0; i < HEIGHT / 20; i++) {
            g.drawLine(0, i * 20, WIDTH, i * 20);
        }

        for(int i = 0; i < snake.size(); i++) {
            snake.get(i).draw(g);
        }
        for(int i = 0; i < apples.size(); i++) {
            apples.get(i).draw(g);
        }

    }

    public void start() {
        running = true;
        thread = new Thread(this, "Game Loop");
        thread.start();
    }

    public void stop() {
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        while(running) {
            tick();
            repaint();
        }
    }

    private class Key implements KeyListener {

        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();

            if(key == KeyEvent.VK_RIGHT && !left) { 
                up = false;
                down = false;
                right = true;
            }

            if(key == KeyEvent.VK_LEFT && !right) { 
                up = false;
                down = false;
                left = true;
            }

            if(key == KeyEvent.VK_UP && !down) {
                left = false;
                right = false;
                up = true;
            }

            if(key == KeyEvent.VK_DOWN && !up) {
                left = false;
                right = false;
                down = true;
            }

        }



    }

The order in which you do things is very important, remember, painting in Swing is like painting on paper, if you paint the text first, then paint over it, it will no longer be visible...

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.setColor(new Color(20, 50, 0));
    g.fillRect(0, 0, WIDTH, HEIGHT);

    g.setColor(Color.BLACK);
    for (int i = 0; i < WIDTH / 20; i++) {
        g.drawLine(i * 20, 0, i * 20, HEIGHT);
    }

    for (int i = 0; i < HEIGHT / 20; i++) {
        g.drawLine(0, i * 20, WIDTH, i * 20);
    }

    for (int i = 0; i < snake.size(); i++) {
        snake.get(i).draw(g);
    }
    for (int i = 0; i < apples.size(); i++) {
        apples.get(i).draw(g);
    }

    g.setColor(Color.WHITE);
    g.drawString("Score: " + score, 100, 100);
}
  1. Don't override paint, override paintComponent , you've circumvented the painting process, meaning you could end up with all sorts of nasty glitches
  2. Call super.paintComponent

Take a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting is done.

Swing is also not thread safe and you need to be careful any time you are changing anything that the paint process uses to update the UI, as painting may occur at any time and for any reason.

Consider using a Swing Timer instead of Thread . The timer executes it's tick events within the context of the Event Dispatching Thread, making it safer to update the UI from within. See Creating a GUI With JFC/Swing

You have a few things in the wrong order. When painting, you need to paint in the correct order, otherwise you will paint over the top of other objects.

So, in your code, the first 5 lines of the paint() method should look like this... (note the same code, but a different order)

    g.clearRect(0, 0, WIDTH, HEIGHT);

    g.setColor(new Color(20, 50, 0));
    g.fillRect(0, 0, WIDTH, HEIGHT);

    g.setColor(Color.WHITE);
    g.drawString("Score: " + score, 100, 100);

You need to paint the background color first. Then you can paint the String on top of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM