尽管运行代码显示菜单,但Java applet显示白屏

【尽管运行代码显示菜单,但Java applet显示白屏】寸阳分阴须爱惜,休负春色与时光。这篇文章主要讲述尽管运行代码显示菜单,但Java applet显示白屏相关的知识,希望能为你提供帮助。
我有一个小游戏applet和朋友正在为我们的计算机科学课做准备。我们正在尝试创建一个在applet开头打开的菜单,然后在1秒后显示一个类选择屏幕。然而,在一秒钟之后,屏幕只是变成白色,但是输出分配的打印语句信号类选择屏幕已经加载,我不确定为什么会发生这种情况并且想要解决这个问题。
我已经尝试将代码放在另一个线程中显示类选择屏幕,因此在运行时没有别的东西会阻止它,但是,这没有改变。我还确保显示屏幕的条件是真实的,并且每隔0.2秒显示一次,但似乎没有任何效果。我试图让代码在角色的构造函数中运行,它应该运行一次,它运行一次,但运行一次的问题是它立即退出菜单并进入游戏的下一阶段没理由。

import java.awt.*; import java.applet.*; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.*; import java.io.*; import javax.swing.*; import java.util.*; public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener { int xCoord = 50; int yCoord = 600; int moveScale = 20; int xSize = 20; int ySize = 20; int leftWall = 0; int rightWall = 1000; int topWall = 0; int bottomWall = 650; public volatile Graphics graphics; boolean isInMenu = false; boolean firstRun = true; boolean drawMap = true; int hostileAmount = 1000; Character P1; @Override public void init() { addKeyListener(this); addMouseListener( this ); }public void Looper(Graphics g) { drawPlayer(g); // Enemy 1 HostileObject enemy = new HostileObject(100, 250); enemy.CreateHostile(g); }public void paint(Graphics g) { if (firstRun) { firstRun = false; isInMenu = true; System.out.println("Character Created"); P1 = new Character(g); } if (!isInMenu & & !firstRun) { System.out.println("Game has begun!"); Map1 firstMap = new Map1(g); Looper(g); } }public void drawPlayer(Graphics g) { g.setColor(Util.black); g.fillRect(xCoord - xSize, yCoord - ySize, xSize, ySize); }public void MovePlayer(int x, int y) { if (CheckPosition(xCoord + x, yCoord + y)) { xCoord += x; yCoord += y; } }public boolean CheckPosition(int x, int y) { if (WallCheck1(x,y) & & WallCheck2(x,y) & & CheckBorders(x, y)) { return true; } else return false; }public boolean CheckBorders(int x, int y) { if (y + ySize < = bottomWall & & y - ySize > = topWall & & x - xSize > = leftWall & & x + xSize < = rightWall) { return true; } else return false; }public boolean WallCheck1(int x, int y) { if ((y - ySize > = Map1.wall1y1 || y + ySize < = Map1.wall1y2 + 20) || x - xSize > = Map1.wall1x2) { return true; } else return false; } public boolean WallCheck2(int x, int y) { if ((y - ySize > = Map1.wall2y1 || y + ySize < = Map1.wall2y2 + 20) || x - xSize < = Map1.wall2x2) { return true; } else return false; }boolean keyIsHeld; char moveChar; public void keyReleased( KeyEvent e ) { keyIsHeld = false; moveChar = ' '; } public void keyTyped( KeyEvent e ) { }public void keyPressed( KeyEvent a ) { char c = a.getKeyChar(); if ( c == 'w' ) { moveChar = 'w'; keyIsHeld = true; } else if ( c == 'a') { moveChar = 'a'; keyIsHeld = true; } else if ( c == 's') { moveChar = 's'; keyIsHeld = true; } else if ( c == 'd') { moveChar = 'd'; keyIsHeld = true; } }public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (isInMenu & & P1.ClassID == 0) { if (x < 500 & & y > 100 & & y < 375) { P1.ClassID = 1; isInMenu = false; System.out.println(P1.Pseudo + " has chosen class: Warrior!"); } if (x < 500 & & y > = 375) { P1.ClassID = 3; isInMenu = false; System.out.println(P1.Pseudo + " has chosen class: UO3!"); } if (x > = 500 & & y > 100 & & y < 375) { P1.ClassID = 2; isInMenu = false; System.out.println(P1.Pseudo + " has chosen class: Thief!"); } if (x > = 500 & & y > = 375) { P1.ClassID = 4; isInMenu = false; System.out.println(P1.Pseudo + " has chosen class: Mage!"); } repaint(); } } public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public boolean mouseDown(Event e, int x, int y){return true; }public void run() { while (!isInMenu || !firstRun) { if (moveChar == 'w') { MovePlayer(0, -moveScale); } else if (moveChar == 'a') { MovePlayer(-moveScale, 0); } else if (moveChar == 's') { MovePlayer(0, moveScale); } else if (moveChar == 'd') { MovePlayer(moveScale, 0); } Util.wait(200); repaint(); } } Thread moveThread; Graphics g; boolean increaseDecrease = false; public void SetUpGraphics(Graphics graphics) { g = graphics; }public void start () { if (moveThread == null) { moveThread = new Thread(this); moveThread.start(); } }}class Map1 extends FinalProjectTest { protected static int wall1x1 = 0; protected static int wall1y1 = 500; protected static int wall1x2 = 810; protected static int wall1y2 = 440; protected static int wall2x1 = 1000; protected static int wall2y1 = 200; protected static int wall2x2 = 190; protected static int wall2y2 = 140; public Map1(Graphics g) { Walls wall1 = new Walls(g, wall1x1, wall1y1, wall1x2, wall1y2); Walls wall2 = new Walls(g, wall2x1, wall2y1, wall2x2, wall2y2); } }class HostileObject { private int startPosX, startPosY; private int xSize = 35; private int ySize = 35; public int health = 100; public HostileObject(int x, int y) { startPosX = x; startPosY = y; }public void CreateHostile(Graphics g) { g.setColor(Util.black); //Util.fillRect(g ,startPosX,startPosY,xSize,ySize); } }class Walls { private static int wallCount = 2; public Walls(Graphics g, int x1, int y1, int x2, int y2) { Util.fillRect(g, x1, y1, x2, y2); } }class Character extends FinalProjectTest implements MouseListener, Runnable { protected int ClassID = 0; protected int PlayerID = 0; protected int GP = 100; protected String Pseudo = "Muritor"; protected boolean DebuggingMode = false; protected Graphics menuGraphics; Thread startMenuThread; public Character(Graphics g) { g.setColor(Util.black); Util.fillRect(g, 1, 1, 1000, 650); Util.drawButton(g, 1, 1, 1000, 100, "3 Floors", 2); Util.wait(1000); menuGraphics = g; startMenuThread = new Thread(this); startMenuThread.start(); }public void run() { while (Thread.currentThread() == startMenuThread) { Util.fillRect(menuGraphics, 1, 1, 1000, 650); Util.drawButton(menuGraphics, 1, 1, 1000, 100, "Choose a Class", 2); Util.drawButton(menuGraphics, 1, 100, 500, 375, "Warrior", 1); Util.drawButton(menuGraphics, 501, 100, 1000, 375, "Thief", 1); Util.drawButton(menuGraphics, 1, 376, 500, 650, "UO3", 1); Util.drawButton(menuGraphics, 501, 376, 1000, 650, "Mage", 1); repaint(); System.out.println("Menu loaded"); Util.wait(200); } } public static void ButtonSelection(Graphics g) {} }class Util { static final Color black = Color.black; static final Color white = Color.white; public static void wait(int mil) { try { Thread.sleep((mil)); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } }public static void fillRect(Graphics g, int x1, int y1, int x2, int y2) { int widthPlaceholder = x2 - x1; int heightPlaceholder = y2 - y1; g.fillRect(x1,y1,widthPlaceholder,heightPlaceholder); }public static void drawButton(Graphics g, int x1, int y1, int x2, int y2, String title, int fontType) { g.setColor(Util.black); int widthPlaceholder = x2 - x1; int heightPlaceholder = y2 - y1; g.fillRect(x1,y1,widthPlaceholder,heightPlaceholder); g.setColor(Util.white); widthPlaceholder = x2 - x1; heightPlaceholder = y2 - y1; for (int k = 0; k < 3; k++) { g.drawRect(x1+k,y1+k,widthPlaceholder-k,heightPlaceholder-k); } switch(fontType) { case 1: Font characterCreateButton = new Font("SansSerif", Font.PLAIN, 75); g.setFont(characterCreateButton); g.drawString(title, x1+100, y1+100); break; case 2: Font characterCreateTitle = new Font("SansSerif", Font.BOLD, 100); g.setFont(characterCreateTitle); g.drawString(title, x1+25, y1+80); break; case 3: Font mainMenu = new Font("Arial", Font.ITALIC, 50); g.setFont(mainMenu); break; } } }

我希望它每隔0.2秒说“菜单加载”并以相同的速率刷新实际的菜单屏幕,我收到消息,但小程序窗口只是白色。
答案 Problem #1
public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener {

我不了解你,但是当我编译你的代码时,我得到了
注意:... / FinalProjectTest.java使用或覆盖不推荐使用的API。注意:使用-Xlint重新编译:弃用以获取详细信息。
所以,如果我启用编译器标志,我得到......
Compiling 1 source file to .../build/classes .../FinalProjectTest.java:18: warning: [deprecation] Applet in java.applet has been deprecated public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener { .../FinalProjectTest.java:179: warning: [deprecation] mouseDown(Event,int,int) in Component has been deprecated public boolean mouseDown(Event e, int x, int y) { ^ .../FinalProjectTest.java:179: warning: [deprecation] Event in java.awt has been deprecated public boolean mouseDown(Event e, int x, int y) { ^ 3 warnings

这应该是警钟。
Applet已经被积极地弃用,并且不再受支持,并且相信已经在最新版本的API中删除了,认真的时间继续前进。
事实上,当我运行代码时,我得到:
警告:不推荐使用Applet API和AppletViewer。
Problem #2
public void paint(Graphics g) { if (firstRun) { firstRun = false; isInMenu = true; System.out.println("Character Created"); P1 = new Character(g); } if (!isInMenu & & !firstRun) { System.out.println("Game has begun!"); Map1 firstMap = new Map1(g); Looper(g); } }

绘画应该描绘状态,不做出合乎逻辑的决定或改变状态,事实上,更令人担忧的是......
P1 = new Character(g);

你永远不应该保持对你自己没有创建的Graphics上下文的引用。 AWT / Swing中的绘画系统使用共享上下文,因此所有组件将使用相同的Graphics上下文,也不能保证上下文在绘制周期之间是相同的。
这也强调了你不了解绘画系统在AWT / Swing中的工作原理。
从Performing Custom Painting和Painting in AWT and Swing开始,了解有关绘画实际如何工作以及如何使用它的更多细节
Problem ?好的,所以从那以后,其他所有事情都只是基于上面的复合,使情况变得更糟,例如......
public void run() { while (Thread.currentThread() == startMenuThread) { Util.fillRect(menuGraphics, 1, 1, 1000, 650); Util.drawButton(menuGraphics, 1, 1, 1000, 100, "Choose a Class", 2); Util.drawButton(menuGraphics, 1, 100, 500, 375, "Warrior", 1); Util.drawButton(menuGraphics, 501, 100, 1000, 375, "Thief", 1); Util.drawButton(menuGraphics, 1, 376, 500, 650, "UO3", 1); Util.drawButton(menuGraphics, 501, 376, 1000, 650, "Mage", 1); repaint(); System.out.println("Menu loaded"); Util.wait(200); } }

这个“可能”似乎没问题,但是如果你理解了这幅画,你就会明白调用repaint会触发并画出传递并导致再次调用paint ......等等,坚持......
class Character extends FinalProjectTest implements MouseListener, Runnable {

为什么CharacterFinalProjectTest延伸?它甚至没有添加到任何可以涂漆的容器中......亲爱的......
Answer...重新开始。
不,严肃地说,扔掉你所做的并重新开始。这一次从阅读(和理解)开始......
  • “责任分离”的基本OO设计概念。而不是将所有逻辑复合到一个方法中,将程序的每个部分的责任分成他们自己的类。菜单应该是一个独立的组件,游戏画布应该是它自己的,独立组件,你应该有一个“控制器”,根据这些组件的反馈(通过observer pattern)决定每个应该是什么时候显示(以及如何)。
  • Model-View-Controller(渗入以前的评论)
  • Performing Custom Painting和Painting in AWT and Swing
  • How to Use Key Bindings因为KeyListener在这里不是一个好选择
  • Concurrency in Swing因为Swing和大多数GUI框架一样,不是线程而且是单线程的,你应该知道如何处理它。
  • How to Make Frames (Main Windows)因为Applet死了
  • How to Use CardLayout因为这将有助于您的生活更轻松
  • 使用JavaFX。至少你应该使用Swing,但如果可以的话,使用JavaFX

    推荐阅读