Java射击游戏删除子弹对象

时间:2012-10-12 14:46:14

标签: java arrays object

我有一个射击游戏,当按下空格键时,会创建一个子弹对象。当子弹对象在屏幕之外时,我想删除对象,这样我可以拍摄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;
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

ArrayList.remove(int index)

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

此外,如果你只想要10,你可以设置10的容量,只需监控大小以确保它不会过去。

答案 1 :(得分: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();
}