Java 重新绘制isn';t呼叫抽签
我试图在while循环中使用repaint调用draw函数。我不太熟悉重新油漆的工作原理 我在repaint上所做的研究表明,它在调用draw方法之前会等待操作完成,这可能是问题所在,因为我处于一个while循环中 然而,我也读到,我试图调用repaint的方法也应该有效,所以此时此刻我感到困惑。在我的代码中加入一些系统输出,似乎并没有启动我的任何绘图功能 这是什么原因造成的?下面列出了我的代码 gamewindow.javaJava 重新绘制isn';t呼叫抽签,java,swing,draw,java-2d,repaint,Java,Swing,Draw,Java 2d,Repaint,我试图在while循环中使用repaint调用draw函数。我不太熟悉重新油漆的工作原理 我在repaint上所做的研究表明,它在调用draw方法之前会等待操作完成,这可能是问题所在,因为我处于一个while循环中 然而,我也读到,我试图调用repaint的方法也应该有效,所以此时此刻我感到困惑。在我的代码中加入一些系统输出,似乎并没有启动我的任何绘图功能 这是什么原因造成的?下面列出了我的代码 gamewindow.java package Game; import java.awt.Fram
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)
{
}
}
打包游戏;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.KeyEvent;
导入java.awt.event.MouseEvent;
公共类框架扩展画布{
//框架宽度和高度
公共静态整数帧宽度;
公共静态帧高度;
//时间变量
公共静态最终长secInNanosec=1000000000L;
公共静态最终长米利塞金纳秒=1000000毫升;
//FPS
私人决赛整场比赛_FPS=60;
//在更新周期之间暂停
私人最终长游戏更新周期=秒数秒/游戏FPS;
//游戏状态
公共静态枚举游戏状态{开始、可视化、游戏内容加载、主菜单、选项、播放、游戏结束、销毁}
//当前游戏状态
公共静态博弈状态;
//比赛时间
私人游戏时间长;
//帮助计算游戏时间
私有长lastTime=0;
//实际比赛
私人游戏=新游戏();
公共框架()
{
超级();
游戏状态=游戏状态。可视化;
//以新线程开始游戏
线程gameThread=新线程(){
@凌驾
公开募捐{
GameLoop();
}
};
gamesthread.start();
}
/**
*设置变量和对象。
*/
私有void初始化()
{
}
/**
*加载文件-图像、声音。。。
*/
私有void LoadContent()
{
}
/**
*在特定的时间间隔内(游戏更新期),游戏/逻辑更新,然后在屏幕上绘制游戏。
*/
私有void GameLoop()
{
//等待一段时间,以便获得正确的帧/窗口分辨率。
long visualizingTime=0,lastVisualizingTime=System.nanoTime();
//计算我们需要多长时间睡眠才能达到FPS。
漫长的开始,耗时的,永恒的;
while(true)
{
beginTime=System.nanoTime();
开关(游戏状态)
{
案例分析:
gameTime+=System.nanoTime()-lastTime;
game.UpdateGame(游戏时间);
lastTime=System.nanoTime();
打破
案例结束:
//...
打破
机箱主菜单:
//...
打破
案例选项:
//...
打破
案例游戏内容加载:
//...
打破
案件开始:
//设置变量和对象。
初始化();
//加载文件-图像、声音。。。
LoadContent();
//当上面调用的所有内容完成后,我们将游戏状态更改为“正在玩”或“主菜单”
gameState=gameState.PLAYING;
打破
案例可视化:
//此.getWidth()方法不会立即返回正确的值
//因此,我们等待一秒钟,等待窗口/框架设置为正确的大小
//如果未及时设置窗口/框架大小,请插入'this.getWidth()>1'条件,
//这样我们就得到了大概的尺寸。
if(this.getWidth()>1&&visualizingTime>secInNanosec)
{
frameWidth=this.getWidth();
frameHeight=this.getHeight();
//当我们得到帧的大小时,我们改变状态。
gameState=gameState.STARTING;
}
其他的
{
visualizingTime+=System.nanoTime()-lastVisualizingTime;
lastVisualizingTime=System.nanoTime();
}
打破
案件销毁:
打破
违约:
打破
}
//重新粉刷屏幕。
重新油漆();
//计算我们需要多长时间睡眠才能达到FPS。
timetake=System.nanoTime()-beginTime;
timeLeft=(游戏更新周期-耗时)/milisecInNanosec;//以毫秒为单位
//如果时间小于10毫秒,那么我们将使线程睡眠10毫秒,以便其他线程可以执行一些工作。
如果(时间间隔<10)
timeLeft=10;//设置最小值
试一试{
//提供必要的延迟,并产生控制,以便其他线程可以执行工作。
线程。睡眠(timeLeft);
}catch(InterruptedException ex){}
}
}
/**
*将游戏绘制到屏幕上。它通过GameLoop()方法中的repaint()方法调用。
*/
@凌驾
公共空心图(Graphics2D g2d)
{
System.out.println(“Paint!”);
开关(游戏状态)
{
案例分析:
System.out.println(“我们正在开火抽签”);
game.Draw(g2d,mousePosition());
打破
案例结束:
//...
打破
机箱主菜单:
//...
打破
案例选项:
//...
打破
// i think this needs @Override but the system won't allow it.
public void paintComponenet(Graphics g) {