0

我有一个射击游戏,当按下空格键时,会创建一个子弹对象。当子弹对象在屏幕之外时,我想删除该对象,以便可以射击 10 次以上。

实例化:

Shot[] shot = new Shot[10];

空格条码:

if (key == KeyEvent.VK_SPACE) {
    if (shots < maxShots) {
        if (canShoot) {
            shot[shots] = new Shot(player.x, player.y, player.width, player.height, shotDir);
            shots++;
            canShoot = false;
        }
    }
}

绘图代码:

for (int i = 0; i < shots; i++) {
    if (shot[i].active) {
        shot[i].drawShot(g);
    }
}

我要删除镜头的地方:

for (int i = 0; i < shots; i++) {
    shot[i].shotLoop();
    if (shot[i].outOfBounds(WINDOW_SIZE.width, WINDOW_SIZE.height)) {
        // Delete Bullet
        shot[i].active = false;
    }
}

我试图这样做,shots--;但是当一个镜头离开屏幕时,当前屏幕上的所有镜头都被删除。有什么建议么?

这是shot[i].outOfBounds()代码

public boolean outOfBounds(int screenx, int screeny) {
    if (x < 0 || x > screenx || y < 0 || y > screeny) {
        return true;
    } else {
        return false;
    }
}
4

2 回答 2

1

改用ArrayList以便在超出范围时将其从列表中删除?

ArrayList<Shot> shot = new ArrayList<Shot>();

ArrayList.remove(int index)

您不应该在迭代时删除,因此您可能必须存储对象(或对象本身)的索引并在找到要删除的项目符号后删除它们。

此外,如果您只想要 10 个,您可以将容量设置为 10 个,并监控大小以确保它不会超出。

于 2012-10-12T14:53:33.870 回答
0
class Weapon
{
    private ArrayList<Shot> magazine;

    private int maxShots;

    private double rotationAngle = 90;
    private double rotationSpeed = 1.5;

    public Weapon(int maxShots)
    {
        this.maxShots = maxShots;

        magazine = new ArrayList<Shot>(maxShots);
    }

    public void rotate(int direction)
    {
        // no need to create hashamp etc to hold "left" or "right"
        // when passing keyPressed, KeyeEvent.getKeyCode is enough.

        // i see alot of people having separate if statements,
        // why, i dont know when you can only go in one
        // direction at a time!

        // also of note, most people wrongly assume that
        // either left or right will be passed, hence, if/else
        // statements.  use "if/else if" to guarantee only 
        // left or right

        if (direction == KeyEvent.VK_LEFT)
        {
            angle-=speed;
        }
        else if (direction == KeyEvent.VK_RIGHT) 
        {
            angle+=speed;
        }
    }

    public void draw(Graphics2D g2, Dimension boundary)
    {
        // do NOT check if shot is out of bounds here,
        // the only thing that should be done in draw,
        // is draw!
    }

    public Iterator<Shot> getMagazine()
    {
        // by returning the iterator, you guarantee
        // concurrency i.e preventing concurrent modifications
        // to data, for example, drawing shots, moving shots
        // and removing them

        return magazine.iterator();
    }

    public void shoot()
    {
        double radian = Math.toRadians(-angle); // invert angle

        double x = [center x] + ([length of weapon] * Math.cos(radian))-[your shot diameter];
        double y = [center y] + ([length of weapon] * Math.sin(radian))-[your shot diameter];

        if (magazine.size() < capacity)
        {
            magazine.add(new Shot(x,y,radian));
        }
    }
}

class Shot extends Ellipse2D.Double
{
    Point2D.Double point;
    Point2D.Double velocity;

    double shotSpeed = 10;

    public Shot(Point2D.Double origin, double radian)
    {
        velocity = new Point2D.Double(Math.cos(radian)*shotSpeed,Math.sin(radian)*shotSpeed);

        point = new Point2D.Double(origin.x+velocity.x,origin.y+velocity.y);

        setFrame(point.x,point.y,[shot diameter],[shot diameter]);
    }

    public void draw(Graphics2D g2)
    {
        g2.setColor(Color.pink);
        g2.fill(this);
    }

    public void move()
    {
        point.x+=velocity.x;
        point.y+=velocity.y;

        setFrame(point.x,point.y,[shot diameter],[shot diameter]);
    }
}


// use javax.swing.Timer to update/paint instead is 
// while(true) with a Thread.sleep.  it allows for stopping and 
// restarting without creating additional objects

public void actionPerformed(ActionEvent event)
{
    // check for rotation......

    // check for shots fired....


    // iterator is faster than conditional loops
    Iterator<Shot> iterator = weapon.getMagazine();

    while(iterator.hasNext())
    {
        Shot shot = iterator.next();

        // getBounds() is the bounds of your panel
        // shot.getBounds() is an inherited method of
        // Ellipse2D.Double

        // use java.awt.geom.RectangleShape.contains(Rectangle) method
        if (getBounds().contains(shot.getBounds()))
        {
            // if the shot is within the rectangle, move it
            shot.move(); 
        }
        else
        {
            iterator.remove();
        }
    }

    // collision detection etc...

    repaint();
}
于 2014-11-01T13:43:14.130 回答