我正在尝试使用while循环中的重绘来调用绘图函数。我不太熟悉精确重复的作品。
我在重画上所做的研究表明,在调用draw方法之前,它等待动作完成,这可能是问题,因为我正处于while循环中。
但是我也读过我试图调用重绘的方式应该也能正常工作,所以我现在很困惑。把一些系统输出到我的代码中它似乎没有启动我的任何绘图功能。
这会导致什么?我的代码列在下面。
gamewindow.java
package Game;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.*;
import Game.Login;
//our window class that will set up the framework of the game
public class GameWindow {
public static boolean stillLoading = true;
public static GridBagConstraints gBC = new GridBagConstraints();
public static JFrame frame = new JFrame();
private static boolean useFullScreen = false;
public GameWindow() {
//Set game Title
frame.setTitle("Gaian Empires");
frame.setLayout(new GridBagLayout());
//set size of the frame
if(useFullScreen) { // full screen
// Disable decorations for the frame.
frame.setUndecorated(true);
//put frame to full screen.
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
} else { // windowed mode
// set size of the frame
frame.setSize(1024,768);
// put frame to center of screen
frame.setLocationRelativeTo(null);
// make it so frame can not be resized
frame.setResizable(false);
}
//Exit the application when user closes frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create instance of the framework so that it extends the canvas
// class and puts it to frame
Login.CreateLogin();
frame.setVisible(true);
frame.add(new Framework());
stillLoading = false;
}
public static void main(String[] args) {
// Use the event dispatch to build UI for safety.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GameWindow();
}
});
}
}
game.java
package Game;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import Game.Login;
public class Game {
public static boolean login = true;
public static boolean loginDone = false;
public Game()
{
Framework.gameState = Framework.GameState.GAME_CONTENT_LOADING;
Thread threadForInitGame = new Thread() {
@Override
public void run(){
// Sets variables and objects for the game.
Initialize();
// Load game files (images, sounds, ...)
LoadContent();
Framework.gameState = Framework.GameState.PLAYING;
}
};
threadForInitGame.start();
}
/**
* Set variables and objects for the game.
*/
private void Initialize()
{
}
/**
* Load game files - images, sounds, ...
*/
private void LoadContent()
{
}
/**
* Restart game - reset some variables.
*/
public void RestartGame()
{
}
/**
* Update game logic.
*
* @param gameTime gameTime of the game.
* if the game is using the mouse for something. @param mousePosition current mouse position.
*/
public void UpdateGame(long gameTime)
{
if (GameWindow.stillLoading) {
return;
}
//System.out.println("UPDATE!");
if (login == true) {
Login.showLogin();
login = false;
}
}
/**
* Draw the game to the screen.
*
* @param g2d Graphics2D
* @param mousePosition current mouse position.
*/
public void Draw(Graphics2D g2d, Point mousePosition)
{
System.out.println("drawing!");
}
}
canvas.java
package Game;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
public abstract class Canvas extends JPanel implements KeyListener, MouseListener {
// Keyboard states - Here are stored states for keyboard keys - is it down or not.
private static boolean[] keyboardState = new boolean[525];
// Mouse States - here are the stored mouse states for mouse key being down or not
private static boolean[] mouseState = new boolean[3];
private static boolean noMouse = false; // removes mouse pointer from game.
public Canvas() {
// use double buffer to draw the screen
this.setDoubleBuffered(true);
this.setFocusable(true);
//this.setBackground(Color.black);
// If you will draw your own mouse cursor or if you just want that mouse cursor disappear,
// insert "true" into if condition and mouse cursor will be removed.
if (noMouse) {
BufferedImage blankCursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(blankCursorImg, new Point(0, 0), null);
this.setCursor(blankCursor);
}
// adds keyboard listener to receive events from jpanel
this.addKeyListener(this);
// adds mouse listener to receive events from jpanel
this.addMouseListener(this);
}
// This method is Override in Framework.java and is used for drawing to the screen
public abstract void Draw(Graphics2D g2d);
// i think this needs @Override but the system won't allow it.
public void paintComponenet(Graphics g) {
System.out.println("painting");
Graphics2D g2d = (Graphics2D)g;
super.paintComponent(g2d);
Draw(g2d);
}
// Keyboard
/**
* Is keyboard key "key" down?
*
* @param key Number of key for which you want to check the state.
* @return true if the key is down, false if the key is not down.
*/
public static boolean keyboardKeyState(int key) {
return keyboardState[key];
}
// Methods of keyboard listener
@Override
public void keyPressed(KeyEvent e) {
keyboardState[e.getKeyCode()] = true;
}
@Override
public void keyReleased(KeyEvent e) {
keyboardState[e.getKeyCode()] = false;
keyReleasedFramework(e);
}
@Override
public void keyTyped(KeyEvent e){
}
public abstract void keyReleasedFramework(KeyEvent e);
// Mouse
/**
* Is mouse button "button" down?
* @param button Number of mouse button for which you want to check the state.
* @return true if the button is down, false if the button is not down.
*/
public static boolean mouseButtonState(int button)
{
return mouseState[button - 1];
}
// Sets mouse key status.
private void mouseKeyStatus(MouseEvent e, boolean status)
{
if(e.getButton() == MouseEvent.BUTTON1)
mouseState[0] = status;
else if(e.getButton() == MouseEvent.BUTTON2)
mouseState[1] = status;
else if(e.getButton() == MouseEvent.BUTTON3)
mouseState[2] = status;
}
// Methods of the mouse listener.
@Override
public void mousePressed(MouseEvent e)
{
mouseKeyStatus(e, true);
}
@Override
public void mouseReleased(MouseEvent e)
{
mouseKeyStatus(e, false);
}
@Override
public void mouseClicked(MouseEvent e) { }
@Override
public void mouseEntered(MouseEvent e) { }
@Override
public void mouseExited(MouseEvent e) { }
}
Framework.java
package Game;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
public class Framework extends Canvas {
// frame width and height
public static int frameWidth;
public static int frameHeight;
//time variables
public static final long secInNanosec = 1000000000L;
public static final long milisecInNanosec = 1000000L;
// FPS
private final int GAME_FPS = 60;
// pause between update cycles
private final long GAME_UPDATE_PERIOD = secInNanosec / GAME_FPS;
// states of game
public static enum GameState{STARTING, VISUALIZING, GAME_CONTENT_LOADING, MAIN_MENU, OPTIONS, PLAYING, GAMEOVER, DESTROYED}
// current game state
public static GameState gameState;
// game time
private long gameTime;
// help calc game time
private long lastTime = 0;
// The actual game
private Game game = new Game();
public Framework ()
{
super();
gameState = GameState.VISUALIZING;
//start game in new thread
Thread gameThread = new Thread() {
@Override
public void run(){
GameLoop();
}
};
gameThread.start();
}
/**
* Set variables and objects.
*/
private void Initialize()
{
}
/**
* Load files - images, sounds, ...
*/
private void LoadContent()
{
}
/**
* In specific intervals of time (GAME_UPDATE_PERIOD) the game/logic is updated and then the game is drawn on the screen.
*/
private void GameLoop()
{
// wait some time so that we get correct frame/window resolution.
long visualizingTime = 0, lastVisualizingTime = System.nanoTime();
// calculate the time for how long we should put threat to sleep to meet FPS.
long beginTime, timeTaken, timeLeft;
while(true)
{
beginTime = System.nanoTime();
switch (gameState)
{
case PLAYING:
gameTime += System.nanoTime() - lastTime;
game.UpdateGame(gameTime);
lastTime = System.nanoTime();
break;
case GAMEOVER:
//...
break;
case MAIN_MENU:
//...
break;
case OPTIONS:
//...
break;
case GAME_CONTENT_LOADING:
//...
break;
case STARTING:
// Sets variables and objects.
Initialize();
// Load files - images, sounds, ...
LoadContent();
// When all things that are called above finished, we change game status to playing or main menu
gameState = GameState.PLAYING;
break;
case VISUALIZING:
// this.getWidth() method doesn't return the correct value immediately
// So we wait one second for the window/frame to be set to its correct size. Just in case we
// also insert 'this.getWidth() > 1' condition in case when the window/frame size wasn't set in time,
// so that we get approximately size.
if(this.getWidth() > 1 && visualizingTime > secInNanosec)
{
frameWidth = this.getWidth();
frameHeight = this.getHeight();
// When we get size of frame we change status.
gameState = GameState.STARTING;
}
else
{
visualizingTime += System.nanoTime() - lastVisualizingTime;
lastVisualizingTime = System.nanoTime();
}
break;
case DESTROYED:
break;
default:
break;
}
// Repaint the screen.
repaint();
// calculate the time for how long we should put threat to sleep to meet FPS.
timeTaken = System.nanoTime() - beginTime;
timeLeft = (GAME_UPDATE_PERIOD - timeTaken) / milisecInNanosec; // In milliseconds
// If the time is less than 10 milliseconds, then we will put thread to sleep for 10 millisecond so that some other thread can do some work.
if (timeLeft < 10)
timeLeft = 10; //set a minimum
try {
//Provides the necessary delay and also yields control so that other thread can do work.
Thread.sleep(timeLeft);
} catch (InterruptedException ex) { }
}
}
/**
* Draw the game to the screen. It is called through repaint() method in GameLoop() method.
*/
@Override
public void Draw(Graphics2D g2d)
{
System.out.println("Paint!");
switch (gameState)
{
case PLAYING:
System.out.println("we are firing draw");
game.Draw(g2d, mousePosition());
break;
case GAMEOVER:
//...
break;
case MAIN_MENU:
//...
break;
case OPTIONS:
//...
break;
case GAME_CONTENT_LOADING:
//...
break;
case DESTROYED:
break;
case STARTING:
break;
case VISUALIZING:
break;
default:
break;
}
}
/**
* Starts new game.
*/
@SuppressWarnings("unused")
private void newGame()
{
// We set gameTime to zero and lastTime to current time for later calculations.
gameTime = 0;
lastTime = System.nanoTime();
game = new Game();
}
/**
* Restart game - reset game time and call RestartGame() method of game object so that reset some variables.
*/
@SuppressWarnings("unused")
private void restartGame()
{
// We set gameTime to zero and lastTime to current time for later calculations.
gameTime = 0;
lastTime = System.nanoTime();
game.RestartGame();
// We change game status so that the game can start.
gameState = GameState.PLAYING;
}
/**
* Returns the position of the mouse pointer in game frame/window.
* If mouse position is null than this method return 0,0 coordinate.
*
* @return Point of mouse coordinates.
*/
private Point mousePosition()
{
try
{
Point mp = this.getMousePosition();
if(mp != null)
return this.getMousePosition();
else
return new Point(0, 0);
}
catch (Exception e)
{
return new Point(0, 0);
}
}
/**
* This method is called when keyboard key is released.
*
* @param e KeyEvent
*/
@Override
public void keyReleasedFramework(KeyEvent e)
{
}
/**
* This method is called when mouse button is clicked.
*
* @param e MouseEvent
*/
@Override
public void mouseClicked(MouseEvent e)
{
}
}
答案 0 :(得分:4)
这看起来像问题:
// i think this needs @Override but the system won't allow it.
public void paintComponenet(Graphics g) {
您尝试覆盖的方法是paintComponent
。你有一个错字。
值得关注编译器警告并了解问题所在。 @Override
错误告诉您正在尝试覆盖超类中不存在的方法。