我正在用java练习一些OOP。
我只想写一些带有图形对象的游戏,但我想用一些类来构建它。
整体布局应如下所示:
MainClass - >新的MainPanel(扩展JPanel) - >新的StartWindow(扩展包含gameloop的抽象GameWindow)
这样我就可以创建StartWindow,Level1Window,Level2Window等等。 我的StartWindow现在应该为第一级绘制布局。 StartWindow将创建其他对象(Player,Enemy等),这些对象稍后将负责绘制自己。
所以我想创建类似“每个对象都有责任自我绘制”的东西
我希望我能说明这应该如何运作。 问题是,我无法弄清楚如何委派这项任务。
我的代码目前看起来像这样:
public class MainClass extends JFrame implements ActionListener {
//..... other stuff
public MainClass () {
MainPanel mainPanel = new MainPanel();
}
//.... other stuff
}
class MainPanel extends JPanel {
private GameWindow currentWindow;
public MainPanel () {
currentWindow = new StartWindow(this);
}
public void paintComponent(Graphics g) {
g.drawRect (10, 10, 200, 200); // <-- can see on the window
}
}
abstract class GameWindow {
// contains game loop and update functions and so on
}
public class StartWindow extends GameWindow {
GamePanel _parentWindow;
public StartWindow(GamePanel parentWindow) {
super();
_parentWindow = parentWindow;
}
public void paintComponent(Graphics g) {
//Does not work
g.drawRect (20, 20, 100, 100);
}
}
“_ parent Window”包含MainPanel,所以我应该拥有在其Panel上绘制所需的所有信息,我只是想弄清楚如何去做。
编辑: 工作的最低范例:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainClass extends JFrame implements ActionListener {
public static void main(String[] args)
{
System.out.println("Program Window1");
MainClass glt = new MainClass();
glt.setVisible(true);
}
//..... other stuff
public MainClass () {
super("Fixed Timestep Game Loop Test");
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
JPanel p = new JPanel();
p.setLayout(new GridLayout(1,2));
System.out.println("Program Window2");
MainPanel gamePanel= new MainPanel();
cp.add(gamePanel, BorderLayout.CENTER);
cp.add(p, BorderLayout.SOUTH);
setSize(500, 500);
}
//.... other stuff
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
class MainPanel extends JPanel {
private GameWindow currentWindow;
public MainPanel () {
currentWindow = new StartWindow(this);
}
public void paintComponent(Graphics g) {
g.drawRect (0, 0, 200, 200); // <-- can see on the window
}
}
abstract class GameWindow {
// contains game loop and update functions and so on
}
class StartWindow extends GameWindow {
MainPanel _parentWindow;
public StartWindow(MainPanel parentWindow) {
super();
_parentWindow = parentWindow;
}
public void paintComponent(Graphics g) {
//Does not work
g.drawRect (20, 20, 100, 100);
}
}
答案 0 :(得分:2)
在MainPanel类的paintComponent方法中尝试这样的事情。
public void paintComponent(Graphics g) {
g.drawRect (10, 10, 200, 200); // <-- can see on the window
Graphics2D g2d = (Graphics2D) g.create();
((StartWindow) currentWindow).paintComponent(g2d);
g2d.dispose();
}
答案 1 :(得分:2)
我会在主绘图JComponent中绘制精灵,例如,
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainClass extends JFrame implements ActionListener {
public static void main(String[] args) {
System.out.println("Program Window1");
MainClass glt = new MainClass();
glt.setVisible(true);
}
// ..... other stuff
public MainClass() {
super("Fixed Timestep Game Loop Test");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
JPanel p = new JPanel();
p.setLayout(new GridLayout(1, 2));
System.out.println("Program Window2");
MainPanel gamePanel = new MainPanel();
cp.add(gamePanel, BorderLayout.CENTER);
cp.add(p, BorderLayout.SOUTH);
setSize(500, 500);
}
// .... other stuff
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
class MainPanel extends JPanel {
private GameWindow currentWindow;
public MainPanel() {
currentWindow = new StartWindow(this);
}
// public void paintComponent(Graphics g) {
// g.drawRect(0, 0, 200, 200); // <-- can see on the window
// }
// this should be protected, not public and should call super method
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, 200, 200); // <-- can see on the window
currentWindow.draw(g);
}
}
interface Drawable {
void draw(Graphics g);
}
abstract class GameWindow implements Drawable {
// contains game loop and update functions and so on
}
class StartWindow extends GameWindow {
MainPanel _parentWindow;
public StartWindow(MainPanel parentWindow) {
super();
_parentWindow = parentWindow;
}
@Override
public void draw(Graphics g) {
g.setColor(Color.red);
g.drawRect(20, 20, 100, 100);
}
}
但是我再次强调,游戏循环不应该被继承,而是应该传递它的引用。通过组合而不是继承进行扩展。
或者甚至更好,让你的模型类实现一个接口,如:
public interface Tickable {
void tick(int deltaTime);
}
然后主模型持有诸如List<Tickable>
之类的集合,并且每次游戏循环滴答时,它都会遍历列表中每个项目上调用tick(...)
的列表。