0

我正在创建一个游戏,并且有一个 Player 类、Enemy 类和 Bullet 类。根据我的引擎设计,通过简单地调用 游戏中每个对象的已经存在的for (Shape s : shapes { g.fill(s) } 位置来绘制我的图形是最合乎逻辑的。这很好用,但是我希望子弹的颜色与玩家不同,而玩家与敌人的颜色不同。如何修改我的 Player、Bullet 和 Enemy 类,以便 awt.Graphics 知道将它们绘制成哪种颜色?shapesList<Shapes>

编辑:另一个可接受的答案可能涉及找到一种方法来shapes按类进行排序和分离,尽管这似乎与已经存在的完整列表相悖。

4

4 回答 4

2

像这样的东西:

彩色形状

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;

class ColoredShapes {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new BorderLayout(5,5));

                final ArrayList<Drawable> drawables = new ArrayList<Drawable>();
                final PaintPanel paintPanel = new PaintPanel(drawables);
                gui.add(paintPanel, BorderLayout.CENTER);

                final Random r = new Random();

                JToolBar tools = new JToolBar();
                gui.add(tools, BorderLayout.PAGE_START);

                JButton addCircle = new JButton("Add Circle");
                ActionListener addCircleListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Point p = new Point(r.nextInt(400), r.nextInt(400));
                        int s = r.nextInt(50) + 50;
                        Color c = new Color(
                                r.nextInt(255), r.nextInt(255), r.nextInt(255));
                        drawables.add(new DrawableCircle(p, s, c));
                        paintPanel.repaint();
                    }
                };
                tools.add(addCircle);
                addCircle.addActionListener(addCircleListener);

                JButton addSquare = new JButton("Add Square");
                ActionListener addSquareListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Point p = new Point(r.nextInt(400), r.nextInt(400));
                        int s = r.nextInt(50) + 50;
                        Color c = new Color(
                                r.nextInt(255), r.nextInt(255), r.nextInt(255));
                        drawables.add(new DrawableSquare(p, s, c));
                        paintPanel.repaint();
                    }
                };
                tools.add(addSquare);
                addSquare.addActionListener(addSquareListener);

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}

interface Drawable {

    public abstract void draw(Graphics2D g);

    public abstract Color getColor();
}

class DrawableCircle implements Drawable {

    private Color color;
    private Shape shape;

    DrawableCircle(Point topLeft, int size, Color color) {
        shape = new Ellipse2D.Double(topLeft.x, topLeft.y, size, size);
        this.color = color;
    }

    public void draw(Graphics2D g) {
        g.setColor(getColor());
        g.fill(shape);
    }

    public Color getColor() {
        return color;
    }
}

class DrawableSquare implements Drawable {

    private Color color;
    private Shape shape;

    DrawableSquare(Point topLeft, int size, Color color) {
        shape = new Rectangle2D.Double(topLeft.x, topLeft.y, size, size);
        this.color = color;
    }

    public void draw(Graphics2D g) {
        g.setColor(getColor());
        g.fill(shape);
    }

    public Color getColor() {
        return color;
    }
}

class PaintPanel extends JPanel {

    Dimension preferredSize = new Dimension(400,400);
    ArrayList<Drawable> drawables;

    PaintPanel(ArrayList<Drawable> drawables) {
        this.drawables = drawables;
    }

    public Dimension getPreferredSize() {
        return preferredSize;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);
        for (Drawable drawable : drawables) {
            drawable.draw(g2);
        }
    }
}
于 2013-05-19T07:43:37.943 回答
1

如果您只想要颜色区分,请g.setColor(Color)在调用之前调用g.fill(s)

于 2013-05-19T06:54:11.383 回答
1

您需要使用 OOP 示例

 Interface Shapes{
  public Color getColor() ;
 }
 class Player implements Shapes{ 
     public Color getColor() {
        return Color.red;
     }
 }
 class Enemy implements Shapes{ 
     public Color getColor() {
        return Color.green;
     }
 }
 //  now the Paint

 for (Shape s : shapes} { g.fill(s.getColor())};
于 2013-05-19T06:52:46.763 回答
1

您可以使用某种地图将每个形状与颜色相关联。然后,当您绘制每个形状时,您只需要执行类似...

for (Shape shape : shapes) {
    Color color = mapColors.get(shape)(
    if (color != null) {
        g.setColor(color);
    } else{
        // set the color to a default value 
    }
    g.fill(shape);
}

对我来说,这种方法的问题在于它使形状与颜色分离。它还限制了资产的绘制方式

更好的解决方案是设计一个Asset提供简单paint方法的类。To 将允许每个资产定义它想要呈现的方式

public interface Asset {
    public void paint(Graphics g);
}

然后,您将简单地使用一个List资产,类似于您的形状列表,但调用paint(g)(在 的实例上Asset)改为,允许资产决定它应该如何绘制......

于 2013-05-19T07:19:18.773 回答