gpt4 book ai didi

尽管运行代码来显示菜单,Java 小程序仍显示白屏

转载 作者:行者123 更新时间:2023-12-02 09:59:03 25 4
gpt4 key购买 nike

我有一个小游戏的小程序,我和一个 friend 正在为我们的计算机科学课开发一个小游戏。我们正在尝试制作一个在小程序启动时打开的菜单,然后 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 秒显示一次“菜单已加载”,并以相同的速率刷新实际菜单屏幕,我收到消息,但小程序窗口只是白色。

最佳答案

问题#1

public class FinalProjectTest extends Applet implements KeyListener, Runnable, MouseListener {

我不了解你,但是当我编译你的代码时,我明白了

Note: .../FinalProjectTest.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details.

所以,如果我启用编译器标志,我会得到...

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

这应该引起警钟。

小程序已被积极弃用,并且不再受支持,并且相信已在最新版本的 API 中删除,是时候继续前进了。

事实上,当我运行代码时,我得到:

Warning: Applet API and AppletViewer are deprecated.

问题#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有关绘画实际工作原理以及应如何使用它的更多详细信息

问题♾

好吧,所以从现在开始,其他一切都只是在上述基础上复合,让糟糕的情况变得无限糟糕,例如......

    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扩展?它甚至没有添加到任何可以绘制它的容器中......哦天哪......

回答...

重新开始。

不,说真的,扔掉你所做的一切并重新开始。这次从阅读(和理解)开始......

  • “责任分离”的基本 OO 设计理念。不要将所有逻辑复合到一个方法中,而是将程序每个部分的职责分离到它们自己的类中。菜单应该是一个单独的、独立的组件,游戏 Canvas 应该是它自己的、独立的组件,然后您应该有一个“ Controller ”,它可以根据这些组件的反馈(通过 observer pattern )决定每个组件何时应该显示(以及如何显示)。
  • Model-View-Controller (渗透到之前的评论中)
  • Performing Custom PaintingPainting in AWT and Swing
  • How to Use Key Bindings因为 KeyListener 在这里不是一个好的选择
  • Concurrency in Swing因为 Swing 与大多数 GUI 框架一样,不是线程,而是单线程,您应该知道如何处理它。
  • How to Make Frames (Main Windows)因为小程序已经死了
  • How to Use CardLayout因为这将使您的生活更轻松
  • 使用 JavaFX。至少您应该使用 Swing,但如果可以的话,请使用 JavaFX

关于尽管运行代码来显示菜单,Java 小程序仍显示白屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55769143/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com