我的这个老项目已经存在了很长时间。我有两个版本的同一个游戏,一个显示游戏,另一个只显示一个空白的白色面板。原来是一个大网格,我试图改变它以逐个像素显示,但现在它只给我一个空白的白色屏幕,但我不知道如何解决它。我已经搜索了很长时间的代码,逐行交叉引用,注释掉代码行以查看它们是否导致了问题,但我无法弄清楚它的生命周期。我。我试着在这里寻找类似的案例,但我没有运气。
要查看很多代码,但是我真的很感谢比我更有知识的人提供的帮助。具体来说,我认为这个问题可能出现在main()
函数中的某个地方在WizardGame.java
,或paintComponent()
中的GamePanel.java
功能,或可能GamePanel()
本身,但此时我甚至不知道在哪里看。
这是破碎的代码:
WizardGame.java
:
package wizard.game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class WizardGame implements KeyListener
{
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static JPanel surface;
private static boolean keyUpPressed;
private static boolean keyDownPressed;
private static boolean keyRightPressed;
private static boolean keyLeftPressed;
private static int keyFramesX;
private static int keyFramesY;
private static double moveXValue;
private static double moveYValue;
private static double moveXCount;
private static double moveYCount;
private static double lastFrame;
private static double currentFrame;
private static boolean painted;
public static int getWIDTH() { return WIDTH; }
public static int getHEIGHT() { return HEIGHT; }
public static double getMoveX() { return moveXCount; }
public static double getMoveY() { return moveYCount; }
public static void resetXY() { moveXValue = 0; moveYValue = 0; }
private static double getTime() { return System.currentTimeMillis(); }
public static void setFrame() { currentFrame = getTime(); }
public static void setPainted(boolean p) { painted = p; }
public WizardGame()
{
BufferedImage icon = null;
try {
icon = ImageIO.read(getClass().getResource("Wizard.png"));
} catch (IOException ex) {
Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
}
// Set frame time counter to 0
currentFrame = (double)0.0;
lastFrame = (double)0.0;
JFrame wizard = new JFrame();
wizard.setTitle("Wizard");
wizard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wizard.setSize(WIDTH+6,HEIGHT+28);
wizard.setResizable(false);
wizard.setIconImage(icon);
wizard.setVisible(true);
surface = new GamePanel();
wizard.getContentPane().add(surface);
surface.addKeyListener(this);
surface.setFocusable(true);
surface.setDoubleBuffered(true);
surface.grabFocus();
}
public static void main(String[] args)
{
new WizardGame();
while(true){
lastFrame = currentFrame;
surface.repaint();
while(painted != true){
surface.repaint();
painted = true;
}
painted = false;
currentFrame = getTime();
setMoveCount();
}
}
private static void setMoveCount() {
double frameDelta = currentFrame - lastFrame;
setVelocity();
moveXCount = (frameDelta * moveXValue);
moveYCount = (frameDelta * moveYValue);
}
private static void setVelocity() {
if(keyRightPressed == true) {
if(keyFramesX < 3)
keyFramesX = 3;
if(keyFramesX < 15)
keyFramesX ++;
moveXValue = 0.005 * keyFramesX;
}
if(keyLeftPressed == true) {
if(keyFramesX < 3)
keyFramesX = 3;
if(keyFramesX < 15)
keyFramesX ++;
moveXValue = -0.005 * keyFramesX;
}
if(keyDownPressed == true) {
if(keyFramesY < 3)
keyFramesY = 3;
if(keyFramesY < 15)
keyFramesY ++;
moveYValue = 0.005 * keyFramesY;
}
if(keyUpPressed == true) {
if(keyFramesY < 3)
keyFramesY = 3;
if(keyFramesY < 15)
keyFramesY ++;
moveYValue = -0.005 * keyFramesY;
}
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
// Right arrow key
if (e.getKeyCode() == 39) {
keyRightPressed = true;
}
// Left arrow key
if (e.getKeyCode() == 37) {
keyLeftPressed = true;
}
// Down arrow key
if (e.getKeyCode() == 40) {
keyDownPressed = true;
}
// Up arrow key
if (e.getKeyCode() == 38) {
keyUpPressed = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
// Right arrow key
if (e.getKeyCode() == 39) {
keyRightPressed = false;
keyFramesX = 0;
}
// Left arrow key
if (e.getKeyCode() == 37) {
keyLeftPressed = false;
keyFramesX = 0;
}
// Down arrow key
if (e.getKeyCode() == 40) {
keyDownPressed = false;
keyFramesY = 0;
}
// Up arrow key
if (e.getKeyCode() == 38) {
keyUpPressed = false;
keyFramesY = 0;
}
}
}
和GamePanel.java
:
package wizard.game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class GamePanel extends JPanel
{
private Wizard wizard;
private static Entity[][] spaces;
private static ArrayList<Entity> spacesList;
private static final int width = WizardGame.getWIDTH();
private static final int height = WizardGame.getHEIGHT();
boolean instantiated;
BufferedImage textBox;
BufferedImage invBox;
BufferedImage invBoxNums;
BufferedImage background;
private static final Color PAULGRAY = new Color(25, 25, 25);
private static final Color PAULTEXT = new Color(229, 0, 202);
public GamePanel() {
spaces = new Entity[width][height];
spacesList = new ArrayList<Entity>();
// Tell whether entities have been instantiated yet or not
wizard = new Wizard(24, 20, 1);
/*try {
loadLevel("src/wizard/game/levelOne.txt");
} catch (FileNotFoundException ex) {
Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
}*/
new Potion(10, 10, "heal_instant", 50, 0);
new Potion(15, 10, "harm_instant", 15, 0);
new Potion(20, 10, "mult_maxHealth", 1.1, 0);
// Random instantiations must come after non-random instantiations
// to prevent location overlapping
EntitySpawner.spawnEnemies(20);
}
// *** Interfacing methods ***
// Return entity from a given location
public static Entity getEntity(int x, int y) {
if(isInBounds(x, y)) {
if(spaces[x][y] == null)
return null;
return spaces[x][y];
}
return null;
}
// Determine whether a given entity is an instance of Wizard
public static boolean isWizard(Entity e) {
if(e instanceof Wizard)
return true;
return false;
}
// Determine whether a location is within the bounds of the game
public static boolean isInBounds(int x, int y) {
if(x<getW() && x>=0 && y<getH() && y>=0)
return true;
return false;
}
// Determine whether a loacation is within 3 sapaces of the 'Wizard'
public static boolean isNearWizard(int x, int y) {
if(Math.sqrt(Math.pow(getWizardX() - x, 2) + Math.pow(getWizardY() - y, 2)) <= 3)
return true;
return false;
}
// Instatntiate entites in a level from a text file
public static void loadLevel(String l) throws FileNotFoundException {
File level = new File(l);
Scanner s = new Scanner(level);
for(int y=1; y<=GamePanel.getH(); y++) {
for(int x=1; x<=GamePanel.getW(); x++) {
int a = x-1;
int b = y-1;
if(isInBounds(a, b)) {
String nextIdentifier = s.next();
switch(nextIdentifier) {
case("x"):
// Nothing
break;
case("s"):
new WallSandstone(a, b);
break;
case("e"):
EntitySpawner.spawnEnemy(a, b);
break;
}
}
}
}
}
// Return the width of the GamePanel
public static int getW() { return width; }
// Return the height of the GamePanel
public static int getH() { return height; }
// Return X position of Wizard
public static int getWizardX() { return Wizard.getX(); }
// return Y position of Wizard
public static int getWizardY() { return Wizard.getY(); }
// Return the entire 'spaces' array
public static Entity[][] getSpaces() { return spaces; }
// Return the list of entities
public static ArrayList<Entity> getSpacesList() { return spacesList; }
// Overwrite the entire spaces array
public static void setSpaces( Entity[][] newSpaces ) { spaces = newSpaces; }
// Overwrite the list of entities
public static void setSpacesList( ArrayList<Entity> newList ) { spacesList = newList; }
// Add entity to 'spacesList'
public static void addEntity( Entity newEnt ) {spacesList.add(newEnt);}
@Override
public void paintComponent(Graphics g)
{
// Ugly sprite instantiation bullshit
try { textBox = ImageIO.read(getClass().getResource("textbox.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
try { invBox = ImageIO.read(getClass().getResource("invbox.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
try { invBoxNums = ImageIO.read(getClass().getResource("invboxnums.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
try { background = ImageIO.read(getClass().getResource("tempbackground.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
// No idea what this is, I only know I need it
super.paintComponent(g);
// Paints the background
g.setColor(PAULGRAY);
g.fillRect( 0, 0, WizardGame.getWIDTH(), WizardGame.getHEIGHT() );
g.drawImage(background, 0, 0, this);
// Update health stats and draw the Wizard
wizard.attack();
g.drawImage(wizard.getSprite(), wizard.getSetX(), wizard.getSetY(), 16, 21, null);
// Paints all entities
// Search through 'spaces'
for(Entity ent: spacesList) {
int x = ent.getX();
int y = ent.getY();
// Only accept non-'Wizard' entities
if((getEntity(x, y) != null) && (!(getEntity(x, y) instanceof Wizard))) {
g.drawImage(getEntity(x, y).getSprite(),
getEntity(x, y).getSetX(),
getEntity(x, y).getSetY(), 16, 21, null);
// Determine if entity is an instance of 'Character'
if(getEntity(x, y) instanceof Character) {
// Update all variables of the character
((Character)getEntity(x, y)).updateStats();
// Determine if entity is still an instance of 'Character'
if(getEntity(x, y) instanceof Character) {
// Determing if character is supposed to display stats
if((boolean)((Character)getEntity(x, y)).dispLev()==true) {
// Display character stats
g.drawString("" + (int)((Character)getEntity(x, y)).getLevel(),
getEntity(x, y).getX()+5, getEntity(x, y).getY()-8);
g.setColor(Color.RED);
g.fillRect(getEntity(x, y).getX()-6, getEntity(x, y).getY()-6, 28, 2);
g.setColor(Color.GREEN);
int m = (int)((Character)getEntity(x, y)).getMaxHealth();
g.fillRect(getEntity(x, y).getX()-6, getEntity(x, y).getY()-6,
(int)(((double)((Character)getEntity(x, y)).getHealth()/m)*28), 2);
}
}
}
}
}
// Paints the Textbox
g.drawImage(textBox, 4, WizardGame.getHEIGHT()-204, this);
g.setColor(PAULTEXT);
int textX = 55;
int textYStart = WizardGame.getHEIGHT()-140;
g.drawString("XP: " + wizard.getEXP() + "\\" + wizard.getNextXP(),
textX, textYStart);
g.setColor(PAULTEXT);
g.fillRect( textX, textYStart + 12, (int)(((double)wizard.getEXP()/
wizard.getNextXP())*100.00), 7);
g.setColor(Color.GREEN);
g.drawLine(textX, textYStart + 10, textX, textYStart + 20);
g.drawLine(textX + 50, textYStart + 10, textX + 50, textYStart + 20);
g.drawLine(textX + 100, textYStart + 10, textX + 100, textYStart + 20);
g.setColor(PAULTEXT);
g.drawString("Level: " + wizard.getLevel(), textX, textYStart + 40);
g.drawString("Health: " + wizard.getHealth() + "\\" + wizard.getMaxHealth(),
textX, textYStart + 60);
g.setColor(Color.RED);
g.fillRect(textX, textYStart + 70, 100, 10);
g.setColor(Color.GREEN);
g.fillRect(textX, textYStart + 70, (int)(((double)wizard.getHealth()
/wizard.getMaxHealth())*100.00), 10);
// Paints the inventory boxes
g.drawImage(invBox, 6, WizardGame.getHEIGHT()-240, this);
g.drawImage(invBoxNums, 6, WizardGame.getHEIGHT()-240, this);
// Clears GamePanel
//WizardGame.resetXY();
//WizardGame.setPainted(true);
}
}
这是工作版本:
WizardGame.java
:
package wizard.game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class WizardGame implements KeyListener
{
private static final int WIDTH = 800+6;
private static final int HEIGHT = 600+28;
private static JPanel surface;
private static int moveX;
private static int moveY;
private static int direction;
public static int getWIDTH() { return WIDTH-6; }
public static int getHEIGHT() { return HEIGHT-28; }
public static int getMoveX() { return moveX; }
public static int getMoveY() { return moveY; }
public static void resetXY() { moveX = 0; moveY = 0; }
public static int getDirection() { return direction; }
public WizardGame()
{
BufferedImage icon = null;
try {
icon = ImageIO.read(getClass().getResource("Wizard.png"));
} catch (IOException ex) {
Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
}
JFrame wizard = new JFrame();
wizard.setTitle("Wizard");
wizard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wizard.setSize(WIDTH,HEIGHT);
wizard.setVisible(true);
wizard.setResizable(false);
wizard.setIconImage(icon);
surface = new GamePanel();
wizard.getContentPane().add(surface);
surface.addKeyListener(this);
surface.setFocusable(true);
surface.setDoubleBuffered(true);
surface.grabFocus();
}
public static void main(String[] args)
{
new WizardGame();
while(true){
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis();
while(endTime%startTime<=20){
endTime = System.currentTimeMillis();
}
surface.repaint();
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 39){
moveX = 1;
direction = 90;
}
if (e.getKeyCode() == 37){
moveX = -1;
direction = 270;
}
if (e.getKeyCode() == 40){
moveY = 1;
direction = 0;
}
if (e.getKeyCode() == 38){
moveY = -1;
direction = 180;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
和GamePanel.java
:
package wizard.game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class GamePanel extends JPanel
{
public Wizard wizard;
public static Entity[][] spaces;
public static final int width = 49;
public static final int height = 28;
boolean instantiated;
BufferedImage textBox;
BufferedImage invBox;
BufferedImage invBoxNums;
private static final Color PAULGRAY = new Color(25, 25, 25);
private static final Color PAULTEXT = new Color(229, 0, 202);
public GamePanel() {
spaces = new Entity[width][height];
// Tell whether entities have been instantiated yet or not
instantiated = false;
}
// *** Interfacing methods ***
// Return entity from a given location
public static Entity getEntity(int x, int y) {
if(isInBounds(x, y)) {
if(spaces[x][y] == null)
return null;
return spaces[x][y];
}
return null;
}
// Determine whether a location is within the bounds of the game
public static boolean isInBounds(int x, int y) {
if(x<getW() && x>=0 && y<getH() && y>=0 && !(x<13 && y>15))
return true;
return false;
}
// Determine whether a loacation is within 3 sapaces of the 'Wizard'
public static boolean isNearWizard(int x, int y) {
for(int a = x-3; a <= x+3; a++) {
for(int b = y-3; b <= y+3; b++) {
if( getEntity(a, b) instanceof Wizard ) {
return true;
}
}
}
return false;
}
// Instatntiate entites in a level from a text file
public static void loadLevel(String l) throws FileNotFoundException {
File level = new File(l);
Scanner s = new Scanner(level);
for(int y=1; y<=GamePanel.getH(); y++) {
for(int x=1; x<=GamePanel.getW(); x++) {
int a = x-1;
int b = y-1;
if(isInBounds(a, b)) {
String nextIdentifier = s.next();
switch(nextIdentifier) {
case("x"):
// Nothing
break;
case("s"):
new WallSandstone(a, b);
break;
case("e"):
EntitySpawner.spawnEnemy(a, b);
break;
}
}
}
}
}
// Return the width of the GamePanel
public static int getW() { return width; }
// Return the height of the GamePanel
public static int getH() { return height; }
// Return the entire 'spaces' array
public static Entity[][] getSpaces() { return spaces; }
// Overwrite the entire spaces array
public static void setSpaces( Entity[][] newSpaces ) { spaces = newSpaces; }
@Override
public void paintComponent(Graphics g)
{
// Instantiate entities here only once
while(instantiated == false){
wizard = new Wizard(24, 20, 1);
try {
loadLevel("src/wizard/game/levelOne.txt");
} catch (FileNotFoundException ex) {
Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex);
}
new Potion(10, 10, "heal_instant", 50, 0);
new Potion(15, 10, "harm_instant", 15, 0);
new Potion(20, 10, "mult_maxHealth", 1.1, 0);
// Random instantiations must come after non-random instantiations
// to prevent location overlapping
EntitySpawner.spawnEnemies(30);
instantiated = true;
}
// Ugly sprite instantiation bullshit
try { textBox = ImageIO.read(getClass().getResource("textbox.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
try { invBox = ImageIO.read(getClass().getResource("invbox.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
try { invBoxNums = ImageIO.read(getClass().getResource("invboxnums.png")); } catch (IOException ex) { Logger.getLogger(GamePanel.class.getName()).log(Level.SEVERE, null, ex); }
// No idea what this is, I only know I need it
super.paintComponent(g);
// Paints the background
g.setColor(PAULGRAY);
g.fillRect( 0, 0, WizardGame.getWIDTH(), WizardGame.getHEIGHT() );
// Paints the Textbox
g.drawImage(textBox, 4, WizardGame.getHEIGHT()-204, this);
g.setColor(PAULTEXT);
int textX = 55;
int textYStart = WizardGame.getHEIGHT()-140;
g.drawString("XP: " + wizard.getEXP() + "\\" + wizard.getNextXP(),
textX, textYStart);
g.setColor(PAULTEXT);
g.fillRect( textX, textYStart + 12, (int)(((double)wizard.getEXP()/
wizard.getNextXP())*100.00), 7);
g.setColor(Color.GREEN);
g.drawLine(textX, textYStart + 10, textX, textYStart + 20);
g.drawLine(textX + 50, textYStart + 10, textX + 50, textYStart + 20);
g.drawLine(textX + 100, textYStart + 10, textX + 100, textYStart + 20);
g.setColor(PAULTEXT);
g.drawString("Level: " + wizard.getLevel(), textX, textYStart + 40);
g.drawString("Health: " + wizard.getHealth() + "\\" + wizard.getMaxHealth(),
textX, textYStart + 60);
g.setColor(Color.RED);
g.fillRect(textX, textYStart + 70, 100, 10);
g.setColor(Color.GREEN);
g.fillRect(textX, textYStart + 70, (int)(((double)wizard.getHealth()
/wizard.getMaxHealth())*100.00), 10);
// Paints the inventory boxes
g.drawImage(invBox, 6, WizardGame.getHEIGHT()-240, this);
g.drawImage(invBoxNums, 6, WizardGame.getHEIGHT()-240, this);
wizard.attack();
g.drawImage(wizard.getSprite(), wizard.getSetX(), wizard.getSetY(), 16, 21, null);
// Paints all entities
// Search through 'spaces'
for(int w = 0; w < spaces.length; w++) {
for(int h = 0; h < spaces[1].length; h++) {
// Only accept non-'Wizard' entities
if((getEntity(w, h) != null) && (!(getEntity(w, h) instanceof Wizard))) {
g.drawImage(getEntity(w, h).getSprite(),
getEntity(w, h).getSetX(),
getEntity(w, h).getSetY(), 16, 21, null);
// Determine if entity is an instance of 'Character'
if(getEntity(w, h) instanceof Character) {
// Update all variables of the character
((Character)getEntity(w, h)).updateStats();
// Determine if entity is still an instance of 'Character'
if(getEntity(w, h) instanceof Character) {
// Determing if character is supposed to display stats
if((boolean)((Character)getEntity(w, h)).dispLev()==true) {
// Display character stats
g.drawString("" + (int)((Character)getEntity(w, h)).getLevel(),
getEntity(w, h).getX()+5, getEntity(w, h).getY()-8);
g.setColor(Color.RED);
g.fillRect(getEntity(w, h).getX()-6, getEntity(w, h).getY()-6, 28, 2);
g.setColor(Color.GREEN);
int m = (int)((Character)getEntity(w, h)).getMaxHealth();
g.fillRect(getEntity(w, h).getX()-6, getEntity(w, h).getY()-6,
(int)(((double)((Character)getEntity(w, h)).getHealth()/m)*28), 2);
}
}
}
}
}
}
// Clears GamePanel
WizardGame.resetXY();
}
}
答案 0 :(得分:0)
我明白了!实体实例化必须在GamePanel.java中的paintComponent()函数内发生。我不知道为什么。