1

我正在尝试做一个涉及在 JPanel 中弹跳形状的任务。每当形状撞到一边时,它们就会向另一个方向反弹。我已经让弹跳部分适用于正常形状,但现在我需要制作一个 NestingShape。

NestingShape 是一个矩形,其中包含零个或多个在其中反弹的形状,而 NestingShape 在 JPanel 中围绕 反弹。NestingShape 实例的子对象可以是简单的 Shapes,如 RectangleShape 和 OvalShape 对象,也可以是其他 NestingShape 实例。

NestingShape 的规格如下:

public class NestingShape extends Shape {   
    /**
     * Creates a NestingShape object with default values for state.
     */
    public NestingShape() {
        super();
    }

    /**
     * Creates a NestingShape object with specified location values, default values for other
     * state items.
     */
    public NestingShape(int x, int y) {
        super(x,y);
    }

    /**
     * Creates a NestingShape with specified values for location, velocity and direction.
     * Non-specified state items take on default values.
     */
    public NestingShape(int x, int y, int deltaX, int deltaY) {
        super(x,y,deltaX,deltaY);
    }

    /**
     * Creates a NestingShape with specified values for location, velocity, direction, width, and
     * height.
     */
    public NestingShape(int x, int y, int deltaX, int deltaY, int width, int height) {
        super(x,y,deltaX,deltaY,width,height);
    }

    /**
     * Moves a NestingShape object (including its children) with the bounds specified by arguments
     * width and height.
     */
    public void move(int width, int height) {
        //Not yet implemented
    }

    /**
     * Paints a NestingShape object by drawing a rectangle around the edge of its bounding box.
     * The NestingShape object's children are then painted.
     */
    public void paint(Painter painter) {
        painter.drawRect(fX,fY,fWidth,fHeight);
        painter.translate(fX,fY);
        // Paint children here. Not implemented yet
        painter.translate(0,0);
}

    /**
     * Attempts to add a Shape to a NestingShape object. If successful, a two-way link is
     * established between the NestingShape and the newly added Shape. Note that this method
     * has package visibility - for reasons that will become apparent in Bounce III.
     * @param shape the shape to be added.
     * @throws IllegalArgumentException if an attempt is made to add a Shape to a NestingShape
     * instance where the Shape argument is already a child within a NestingShape instance. An
     * IllegalArgumentException is also thrown when an attempt is made to add a Shape that will
     * not fit within the bounds of the proposed NestingShape object.
     */
    void add(Shape shape) throws IllegalArgumentException {
        // Not implemented yet  
    }

    /**
     * Removes a particular Shape from a NestingShape instance. Once removed, the two-way link
     * between the NestingShape and its former child is destroyed. This method has no effect if
     * the Shape specified to remove is not a child of the NestingShape. Note that this method
     * has package visibility - for reasons that will become apparent in Bounce III.
     * @param shape the shape to be removed.
     */
    void remove(Shape shape) {
        // Not implemented yet
    }

    /**
     * Returns the Shape at a specified position within a NestingShape. If the position specified
     * is less than zero or greater than the number of children stored in the NestingShape less
     * one this method throws an IndexOutOfBoundsException.
     * @param index the specified index position.
     */
    public Shape shapeAt(int index) throws IndexOutOfBoundsException {
        // Not implemented yet
    }

    /**
     * Returns the number of children contained within a NestingShape object. Note this method is
     * not recursive - it simply returns the number of children at the top level within the callee
     * NestingShape object.
     */
    public int shapeCount() {
        // Not implemented yet
    }

    /**
     * Returns the index of a specified child within a NestingShape object. If the Shape specified
     * is not actually a child of the NestingShape this method returns -1; otherwise the value
     * returned is in the range 0 .. shapeCount() - 1.
     * @param the shape whose index position within the NestingShape is requested.
     */
    public int indexOf(Shape shape) {
        // Not implemented yet
    }

    /**
     * Returns true if the shape argument is a child of the NestingShape object on which this method
     * is called, false otherwise.
     */
    public boolean contains(Shape shape) {
        // Not implemented yet
    }
}

我不确定这是否提供了足够的上下文,但我遇到问题的部分是实现addandremove方法。当它说“在 NestingShape 和新添加的 Shape 之间建立了双向链接”时,我不知道该怎么做。我会使用 ArrayList 或形状列表或其他东西吗?关于我将如何实现该add方法以及从该代码中调用该方法的位置是否有任何线索?

谢谢。

4

2 回答 2

2

如果我做对了,您实际上确实需要在这个嵌套形状内有某种列表(例如 ArrayList)或有序的子集,以便嵌套形状可以有更多的孩子。然后,您可以使用列表的方法在添加形状时检查它是否已包含,并删除和插入形状。

当他们说您建立双向连接时,他们的意思是您应该告诉插入的形状现在它的新父级是给定的嵌套形状。您没有给我们 shape 类的接口(它看起来不像标准的 java.awt.Shape,因为它是一个接口)。您的形状类确实以某种方式引用了父矩形以了解它应该移动的边界是什么,因此您应该在将子形状插入嵌套形状时将该父矩形设置为嵌套形状。从嵌套形状中删除形状时,您还应该删除该父子关系。

我需要有关形状类的更多信息以提供更详细的答案,但我相信这就是您要寻找的;)

于 2011-05-16T06:31:03.780 回答
0

必须使用和True-Shape-Nesting-algorithm

真实形状嵌套是一种使用更详细的嵌套算法将更多对象放入指定区域的功能。

于 2021-03-05T17:07:18.653 回答