尽管运行代码显示菜单,但Java applet显示白屏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尽管运行代码显示菜单,但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 {
为什么Character
从FinalProjectTest
延伸?它甚至没有添加到任何可以涂漆的容器中......亲爱的......
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
以上是关于尽管运行代码显示菜单,但Java applet显示白屏的主要内容,如果未能解决你的问题,请参考以下文章
java.security.AccessControlException:运行applet时发生