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--;たが、1 ショットが画面を離れると、現在画面に表示されているすべてのショットが削除されます。助言がありますか?

ここに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 インデックス)

反復中に削除するべきではないため、オブジェクト (またはオブジェクト自体) のインデックスを保存し、削除する箇条書きを見つけた後に削除する必要がある場合があります。

また、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 に答える