gpt4 book ai didi

Java 游戏开发 : Graphics

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:51:52 24 4
gpt4 key购买 nike

我是新来的。希望您能提供帮助。

问题:在 JFrame 上显示动画时出现问题。似乎我想念/不太了解 Java 的图形是如何工作的。

全局理念:假设我想制作游戏/电影/剪辑。为此,我需要这个(不是)简单的动画开始工作。

这个问题的一个例子:我得到了 Screen 类,它具有屏幕内容 - JFrame 的声明,设置其配置(大小,关闭操作等),然后创建 Box 类的对象,以显示在框架上。请检查这张图片/类图(希望我写得正确):ClassesDiagram

现在,Box 类扩展了 JPanel。我从 JPanel 继承了 Paint() 方法并覆盖它,绘制框。

在 Screen 类中,在我创建了两个 Boxes 之后,我将它们添加到 JFrame。接下来,启动一个循环 while(true),并通过让线程 hibernate 该时间来每 200 毫秒更新一次框的位置。(在这种情况下,只是简单的 x++ 或 y++ 取决于哪个框,box1 或 box2)。

主要问题 1): 程序运行并显示 JFrame,但在 JFrame 上它显示最后添加的对象/组件- Box。它没有显示另一个。为什么?

我找到了一个话题,How to add multiple components to a JFrame? ,并尝试了 jjnguy 2010 年 11 月 15 日 17:02 投票最多的帖子给出的提示。出于某种奇怪的原因,第一个和第二个提示都不适合我。

主要问题 2): 据我了解,我需要布局管理器。如果我只想在框架上的特定 X、Y 处绘制 (),为什么我需要它?

找到其他帖子(找不到了)+Oracle关于布局的指南,建议我需要考虑使用setLayout(null);我尝试这样做,但又出现了问题。

主要问题 3): JFrame 出现,它只显示 1 个框(绿色框不会出现,无论你做什么。不知道为什么),当它移动时 -它从另一侧被删除。这里:Box Movement

提前感谢您提供的任何帮助、提示和解释!希望帖子清晰、有条理且美观。


public class Screen {

public static void main(String[] args) {
new Screen();
}

private JFrame window;

public Screen() {
window = new JFrame("Multiply components panel");
//window.setLayout(null);
window.setSize(200, 200);

window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

Box b1 = new Box(10,10, "box1");
//b1.setBounds(10, 10, 50, 50);

Box b2 = new Box(100,100, "box2");
//b2.setBounds(100, 100, 50, 50);


window.add(b1);
//window.add(b2);


window.setVisible(true);

while (true){

b1.update();
b2.update();

try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}

}
}

public class Box extends JPanel{

int x, y, w, h;
private String name;

public Box(int x, int y, String name) {
this.x = x;
this.y = y;
this.w = 100;
this.h = 100;
this.name=name;
}


public void paint(Graphics g){
System.out.println(this.name.equalsIgnoreCase("box1"));
if(this.name.equalsIgnoreCase("box1")){
g.setColor(Color.BLACK);
g.fillRect(x, y, w, h);
}else{
g.setColor(Color.GREEN);
g.fillRect(x, y, w, h);
}


}


public void update() {
if(this.name.equalsIgnoreCase("box1"))
x++;
else
y++;
//this.setBounds(x, y, w, h);
System.out.println("Current "+name+": X: "+x+", Y: "+y+", W: "+w+", H: "+h);
repaint();
}

}

最佳答案

Main Problem 1): The program runs, and shows the JFrame, but on the JFrame it shows only the last added object/component- Box. It doesn't show the other one. Why?

你做的 window.add(b1);
window.add(b2);
,默认 JFrameBorderLayout因此,当您执行 add(..) 时,您将替换最后添加的框.

Main Problem 2): As far as I understand, i need layout manager. Why do I need it, if I just want to paint() at specific X,Y on the frame?

如果您使用 JPanel作为游戏中的对象,这将是唯一一次使用 setLayout(null)因为我们想要完全控制 JPanel放置。

Main Problem 3): The JFrame shows up, it shows only 1 box(the green one wont show up, whatever you will do. Don't know why) and when it DOES move- it gets erased from the other side. Here: Box Movement

因为你你这样做g.fillRect(x,y,w,h) ,应该是g.fillRect(0,0,w,h)

其他问题:

1) 我认为你遇到的一个主要问题是:

public class Box extends JPanel{

...

public void paint(Graphics g){

...
}

}

你应该覆盖 paintComponentJPanel ,记得调用super.paintComponent(g)作为覆盖方法中的第一次调用。

3) 你应该覆盖 getPreferredSizeJPanel并返回与 JPanel 的图像或内容匹配的正确尺寸

4) 不要调用 setSizeJFrame使用正确 Layoutmanager和/或覆盖 getPreferredSize必要的容器比简单地调用 pack()JFrame在将其设置为可见之前。

5) 正如@MadProgrammer 所说,阅读 Concurrency in Swing但基本上所有 Swing 组件都应该通过 SwingUtilities.inokeXXX 在 EDT 上创建/操作 block 。

6) 这样做绝对不好:

while (true){

b1.update();
b2.update();

try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}

因为您不仅要创建连续循环,还要调用 Thread.sleep在您创建 GUI 的线程上,因此似乎会卡住。看看How to use Swing Timers , 另见 this关于上述主题的类似问题。

这是实现了上述修复的代码:

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Screen {

private JFrame window;

public static void main(String[] args) {

//creat UI on EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Screen();
}
});
}

public Screen() {
window = new JFrame("Multiply components panel") {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
};

window.setLayout(null);//only reason this is warrented is because its a gmae using JPanels as game objects thus we need full control over its placing
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//changed from DISPOSE to EXIT so Timers will be exited too

final Box b1 = new Box(10, 10, 50, 50, "box1");

final Box b2 = new Box(100, 100, 50, 50, "box2");

window.add(b1);
window.add(b2);

window.pack();
window.setVisible(true);

Timer timer = new Timer(200, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
b1.update();
b2.update();
}
});
timer.setInitialDelay(0);
timer.start();

}
}

class Box extends JPanel {

int x, y, w, h;
private String name;

public Box(int x, int y, int w, int h, String name) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.name = name;
setBounds(x, y, w, h);//let the Box class handle setting the bounds more elegant OOP
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(this.name.equalsIgnoreCase("box1"));
if (this.name.equalsIgnoreCase("box1")) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, h);
} else {
g.setColor(Color.GREEN);
g.fillRect(0, 0, w, h);
}
}

@Override
public Dimension getPreferredSize() {
return new Dimension(w, h);
}

public void update() {
if (this.name.equalsIgnoreCase("box1")) {
x++;
} else {
y++;
}
this.setBounds(x, y, w, h);//set the new bounds so box may be updated
System.out.println("Current " + name + ": X: " + x + ", Y: " + y + ", W: " + w + ", H: " + h);
revalidate();
repaint();
}
}

最后看看我的教程/代码片段 Game Development Loop, Logic and Collision detection Java Swing 2D .

它拥有开始一个简单的 2D 游戏所需的一切,例如游戏循环、逻辑、像素碰撞检测、动画(即在多个 Sprite 之间交换以创建 Sprite 集的动画)等等,但根本的区别在于使用对象作为游戏实体,即一个类将保存要绘制的对象所需的所有信息,IMO 这就是游戏应该如何完成的,事情可能会变得图形化,并且有许多 JPanel 想知道屏幕肯定会降低整体 FPS

关于Java 游戏开发 : Graphics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17373979/

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