简体   繁体   English

Java射击游戏删除子弹对象

[英]Java Shooting Game Removing Bullet Object

I have a shooting game and when the spacebar is pressed, a bullet object is created. 我有一个射击游戏,当按下空格键时,会创建一个项目符号对象。 When the bullet object is outside of the screen, I want to delete the object so I can shoot more than 10 times. 当子弹对象在屏幕之外时,我想删除该对象,以便可以拍摄10次以上。

Instantiation: 实例化:

Shot[] shot = new Shot[10];

Spacebar code: 空格键代码:

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;
        }
    }
}

Drawing code: 绘图代码:

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

Where I want to delete the shot: 我要删除镜头的地方:

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;
    }
}

I tried to do shots--; 我试着shots--; but when one shot leaves the screen, all shots currently on the screen are deleted. 但是当一张照片离开屏幕时,屏幕上当前的所有照片都会被删除。 Any suggestions? 有什么建议么?

Here is the shot[i].outOfBounds() code 这是shot[i].outOfBounds()代码

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

Use an ArrayList instead so you can remove it from the list when it goes out of bounds? 请改用ArrayList,以便在超出范围时可以将其从列表中删除?

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

ArrayList.remove(int index) ArrayList.remove(int索引)

You shouldn't remove while iterating over, so you might have to store the index of the objects (or the objects themselves) and remove them after finding the bullets to remove. 迭代时不应该删除,因此您可能必须存储对象(或对象本身)的索引,并在找到要删除的项目符号之后将其删除。

Also if you only want 10, you can set a capacity of 10, and just monitor the size to make sure it doesn't go over. 另外,如果只需要10个,则可以将容量设置为10,并仅监视大小以确保不会超过容量。

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM