graphics2D drawImage не работает с timer.schedule - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь смоделировать игру Gameboy в Java. Я пытаюсь печатать буквы в текстовое поле каждые полсекунды или около того, но когда я запускаю код, окно отображается правильно, но в нем нет текста.

Текстовое поле:

package components;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

public class Textbox extends Entity { //Only create one instance
private static String[] lines;
private static final int x = 1;
private static final int y = 97;
private Graphics2D graphics2D;
int lineNo = 0; //Used to count the line number when printing
int charNo = 0; //Used to count the character number when printing
int cx; //Used for the coordinates of each character printed
int cy; //Used for the coordinates of each character printed
boolean timerInitialized = false; //Used to indicate end of line when printing
java.util.Timer timer = new Timer(); //Used to control text speed
//java.util.TimerTask task;

private static volatile Textbox textbox = new Textbox();

public Textbox() {
    super(x, y);
    addLines();
}

public void draw(Graphics2D graphics2D) {
    this.graphics2D = graphics2D;
    this.graphics2D.drawImage(getImage(), x, y, null);
    if (!timerInitialized) {
        System.out.println("Scheduled..."); //For testing
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!"); //For testing
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 1000);
        timerInitialized = true;
    }
}

/*public void drawText(Image image, Point coordinates) {
    this.graphics2D.drawImage(image, coordinates.x, coordinates.y, null);
}*/

public Image getImage() {
    //graphics2D.drawString("Hello World", 100, 100); //Draws  a string
    ImageIcon imageIcon = new ImageIcon(
            "enterDirectoryHere"
                    + "\\src\\components\\Display\\Textbox.png");
    return imageIcon.getImage();
}

public void keyReleased(KeyEvent event) {
    int key = event.getKeyCode();

    if (key == KeyEvent.VK_ENTER) {
        if (GameFrame.screenPaused == true) {
            GameFrame.screenPaused = false;
        } else {
            GameFrame.screenPaused = true;
        }

    }
}

//FOR TESTING ONLY
public static void addLines() {
    lines = new String[] {"Hello", "World"};

}


/*
Make a boolean to indicate that line1 is full, and to continue on line 2 if
more text remains
Show cursor to indicate more text in lines
When pressing 'A' to continue text, translate text upward
If text exceeds boundaries, begin to cut off, starting from top, until gone

 */
/*public void printText(Graphics2D graphics2D) {
    if (lines != null) {
        //Assume that you already know the arrangement of words in the box
        //Starting point is 8, 112
        lineNo = 0;
        //endLine = false;
        while (lineNo < lines.length) {
            String line = lines[lineNo];
            if (line != null) {
                charNo = 0;
                for (int i = 0; i < line.length(); i++) {
                    printChars(graphics2D, line);
                }
            }
            lineNo++; //Move to the next line
            //line takes new line into account
            cx = 8;
        }
    }

}*/

public void printChars(Graphics2D graphics2D, String line) {
    if (charNo < line.length()) {
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        if (line.charAt(charNo) >= 'A' && line.charAt(charNo) <= 'Z') {
            Image image = getCharImage(line.charAt(charNo));
            graphics2D.drawImage(image, cx, cy, null);
            cx += image.getWidth(null);
        } else if (line.charAt(charNo) >= 'a' && line.charAt(charNo) <= 'z') {
            if (line.charAt(charNo) == 'b' || line.charAt(charNo) == 'd'
                    || line.charAt(charNo) == 'f' || line.charAt(charNo) == 'h'
                    || line.charAt(charNo) == 'k' || line.charAt(charNo) == 'l') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == 'i' || line.charAt(charNo) == 'j'
                    || line.charAt(charNo) == 't') {
                cy += 1;
                //Add extra spaces for i, j, and l
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else {
                cy += 2;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        } else if (line.charAt(charNo) >= 32 && line.charAt(charNo) <= 95) {
            //Check for symbols and spaces
            if (line.charAt(charNo) == '_') {
                cx += 7;
            } else if (line.charAt(charNo) == '.') {
                cy += 5;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == ',') {

            } else if (line.charAt(charNo) == '/') {

            } else if (line.charAt(charNo) == '?') {

            } else if (line.charAt(charNo) == '!') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null) + 8;
            } else if (line.charAt(charNo) == ']') {

            } else if (line.charAt(charNo) == '[') {

            } else if (line.charAt(charNo) == ':') {

            } else if (line.charAt(charNo) == ';') {

            } else if (line.charAt(charNo) == '-') {

            } else if (line.charAt(charNo) == '(') {

            } else if (line.charAt(charNo) == ')') {

            } else if (line.charAt(charNo) == '\'') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        }
        cx += 2; //move two pixels to the right
        //Writes on the second half of the box if there is
        //more than 1 line
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        charNo++;
    } else {
        //charNo = 0;
        //lineNo++;
    }
    //Schedule the next letter here if there are more letters
    if (lineNo < lines.length || charNo < line.length()) {
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 200);
    }
}

GameFrame:

package components;

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

public class GameFrame extends JPanel implements ActionListener{

javax.swing.Timer mainTimer;
Player player;
Textbox textbox;
Trainer trainer;
//static boolean showDialogueBox = true;
static boolean screenPaused = true;

static ArrayList<Trainer> trainerList = new ArrayList<>();

//Each setting has its own trainers

public GameFrame() {
    setFocusable(true);

    player = new Player();
    //player = new Player(138, 98); The bottom right corner
    //trainerList.add(trainer);
    textbox = new Textbox();
    addKeyListener(new KeyAdapt(player, textbox));
    mainTimer = new Timer(10, this); //Resets the screen every 10 millisecs
    mainTimer.start();
}

public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D graphics2D = (Graphics2D) graphics;
    //player.draw(graphics2D);
    if (screenPaused) {
        textbox.draw(graphics2D);
        //textbox.printText(graphics2D);
    }

}

@Override
public void actionPerformed(ActionEvent event) {
    player.update();
    repaint();
}

public static ArrayList<Trainer> getTrainerList() {
    return trainerList;
}

}

Но я получаю пустое поле: Смотрите результат здесь

Когда я комментирую из частей, где я установил таймер, например:

GameFrame:

package components;

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

public class GameFrame extends JPanel implements ActionListener{

javax.swing.Timer mainTimer;
Player player;
Textbox textbox;
Trainer trainer;
//static boolean showDialogueBox = true;
static boolean screenPaused = true;

static ArrayList<Trainer> trainerList = new ArrayList<>();

//Each setting has its own trainers

public GameFrame() {
    setFocusable(true);

    player = new Player();
    //player = new Player(138, 98); The bottom right corner
    //trainerList.add(trainer);
    textbox = new Textbox();
    addKeyListener(new KeyAdapt(player, textbox));
    mainTimer = new Timer(10, this); //Resets the screen every 10 millisecs
    mainTimer.start();
}

public void paint(Graphics graphics) {
    super.paint(graphics);
    Graphics2D graphics2D = (Graphics2D) graphics;
    if (screenPaused) {
        textbox.draw(graphics2D);
        textbox.printText(graphics2D);
    }

}

@Override
public void actionPerformed(ActionEvent event) {
    player.update();
    repaint();
}

public static ArrayList<Trainer> getTrainerList() {
    return trainerList;
}

}

Текстовое поле:

import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

public class Textbox extends Entity {

private static String[] lines;

private static final int x = 1;
private static final int y = 97;
private Graphics2D graphics2D;
int lineNo = 0; //Used to count the line number when printing
int charNo = 0; //Used to count the character number when printing
int cx; //Used for the coordinates of each character printed
int cy; //Used for the coordinates of each character printed
boolean timerInitialized = false; //Used to indicate end of line when printing
java.util.Timer timer = new Timer();

private static volatile Textbox textbox = new Textbox();

public Textbox() {
    super(x, y);
    addLines();
}

public void draw(Graphics2D graphics2D) {
    this.graphics2D = graphics2D;
    this.graphics2D.drawImage(getImage(), x, y, null);
    if (!timerInitialized) {
        /*System.out.println("Scheduled..."); //For testing
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!"); //For testing
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 1000);*/
        timerInitialized = true;
    }
}

/*public void drawText(Image image, Point coordinates) {
    this.graphics2D.drawImage(image, coordinates.x, coordinates.y, null);
}*/

public Image getImage() {
    //graphics2D.drawString("Hello World", 100, 100); //Draws  a string
    ImageIcon imageIcon = new ImageIcon(
            "C:\\EnterDirectoryHere"
                    + "\\src\\components\\Display\\Textbox.png");
    return imageIcon.getImage();

public void keyReleased(KeyEvent event) {

    int key = event.getKeyCode();

    if (key == KeyEvent.VK_ENTER) {
        if (GameFrame.screenPaused == true) {
            GameFrame.screenPaused = false;
        } else {
            GameFrame.screenPaused = true;
        }

    }
}

//FOR TESTING ONLY
public static void addLines() {
    lines = new String[] {"Hello", "World"};

}


/*
Make a boolean to indicate that line1 is full, and to continue on line 2 if
more text remains
Show cursor to indicate more text in lines
When pressing 'A' to continue text, translate text upward
If text exceeds boundaries, begin to cut off, starting from top, until gone

 */
public void printText(Graphics2D graphics2D) {
    if (lines != null) {
        //Assume that you already know the arrangement of words in the box
        //Starting point is 8, 112
        lineNo = 0;
        //endLine = false;
        while (lineNo < lines.length) {
            String line = lines[lineNo];
            if (line != null) {
                charNo = 0;
                for (int i = 0; i < line.length(); i++) {
                    printChars(graphics2D, line);
                }
            }
            lineNo++; //Move to the next line
            //line takes new line into account
            cx = 8;
        }
    }

}

public void printChars(Graphics2D graphics2D, String line) {
    if (charNo < line.length()) {
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        if (line.charAt(charNo) >= 'A' && line.charAt(charNo) <= 'Z') {
            Image image = getCharImage(line.charAt(charNo));
            graphics2D.drawImage(image, cx, cy, null);
            cx += image.getWidth(null);
        } else if (line.charAt(charNo) >= 'a' && line.charAt(charNo) <= 'z') {
            if (line.charAt(charNo) == 'b' || line.charAt(charNo) == 'd'
                    || line.charAt(charNo) == 'f' || line.charAt(charNo) == 'h'
                    || line.charAt(charNo) == 'k' || line.charAt(charNo) == 'l') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == 'i' || line.charAt(charNo) == 'j'
                    || line.charAt(charNo) == 't') {
                cy += 1;
                //Add extra spaces for i, j, and l
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else {
                cy += 2;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        } else if (line.charAt(charNo) >= 32 && line.charAt(charNo) <= 95) {
            //Check for symbols and spaces
            if (line.charAt(charNo) == '_') {
                cx += 7;
            } else if (line.charAt(charNo) == '.') {
                cy += 5;
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            } else if (line.charAt(charNo) == ',') {

            } else if (line.charAt(charNo) == '/') {

            } else if (line.charAt(charNo) == '?') {

            } else if (line.charAt(charNo) == '!') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null) + 8;
            } else if (line.charAt(charNo) == ']') {

            } else if (line.charAt(charNo) == '[') {

            } else if (line.charAt(charNo) == ':') {

            } else if (line.charAt(charNo) == ';') {

            } else if (line.charAt(charNo) == '-') {

            } else if (line.charAt(charNo) == '(') {

            } else if (line.charAt(charNo) == ')') {

            } else if (line.charAt(charNo) == '\'') {
                Image image = getCharImage(line.charAt(charNo));
                graphics2D.drawImage(image, cx, cy, null);
                cx += image.getWidth(null);
            }
        }
        cx += 2; //move two pixels to the right
        //Writes on the second half of the box if there is
        //more than 1 line
        if (lineNo == 0) {
            cy = 112;
        } else {
            cy = 128;
        }
        charNo++;
    } else {
        //charNo = 0;
        //lineNo++;
    }
    //Schedule the next letter here if there are more letters
    if (lineNo < lines.length || charNo < line.length()) {
        /*timer.schedule(new TimerTask() {
            @Override
            public void run() {
                printChars(graphics2D, lines[lineNo]);
                timer.cancel();
            }
        }, 200);*/
    }
}

, текст показывает все в порядке, но он появляется все сразу, а это не то, чего я хочу. Смотрите результат здесь Я забыл что-то сделать?

1 Ответ

0 голосов
/ 06 апреля 2020

Я понял, в чем проблема. Я не обновлял текст, который должен отображаться каждый раз, когда вызывается draw (). Я смог получить желаемые результаты, выполнив следующее:

public void draw(Graphics2D graphics2D) {
    graphics2D.drawImage(getImage(), x, y, null);
    //Every time draw is called, ensure that the coordinates are the same
    //each time text is redrawn
    if (!display.isEmpty()) { //This will only print when characters have
        //been added every second
        for (int i = 0; i < display.size(); i++) {
            drawText(graphics2D, display.get(i).charAt(0), coordinates.get(i));
        }
    }
    if (!timerInitialized && line1 != null) { //This only allows the timer to be set once
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                addTextToDisplay(lines[0]);
            }
        }, 100);
        timerInitialized = true;
    }
}

Я использовал два массива: отображение и координаты. На дисплее отображаются буквы для печати и координаты, обозначающие координаты этого символа на экране.

...