简体   繁体   中英

Projectiles in my ArrayList are not changed individually upon collision, how can I fix this?

I am trying to make a game. I want the projectiles (balls) that I shoot to each have their own individual collisions with objects and the margins of the game screen, but right now when one ball collides with the game screen margins, every balls' velocity.x or velocity.y is multiplied by -1 to simulate collision rather than just the individual ball that hit's velocity being modified. (When one ball hits, all balls' velocities are affected). The projectiles are stored in an ArrayList in the GameWorld class and are all given an identical velocity when they are shot. You pick a direction to shoot in, then balls are shot every 0.3s in that direction until all balls are shot.

Here is the code from my Projectiles class:

package com.trimble.gameobjects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.trimble.gameworld.GameWorld;

public class Projectile {
    private Vector2 velocity, acceleration;
    private Vector2 position;
    private final float RADIUS = 3f;
    private boolean active, shot;
    private GameWorld world;
    private float theta;

    public Projectile(float x, GameWorld world) {
        this.world = world;
        this.position = new Vector2();
        this.position.x = x;
        this.position.y = world.getGameRect().y - 3;
        // hitbox = new Circle(position, 3f);
        this.velocity = new Vector2();
        this.acceleration = new Vector2(0, 0.5f);
        this.active = false;
        this.shot = false;
    }

    public void update(float delta) {
        if (active) {
            position.add(velocity.cpy().scl(delta));
            velocity.add(acceleration.cpy().scl(delta));

            // left
            if (this.position.x <= 3) {
                Gdx.app.log("hit", " left");
                this.position.x = 3;
                this.velocity.x *= -1;
            }
            // right
            else if (this.position.x >= world.getGameRect().width - 3) {
                Gdx.app.log("hit", " right");
                this.position.x = world.getGameRect().width - 3;
                this.velocity.x *= -1;
            }
            // top
            if (this.position.y < world.getGameRect().y + world.getGameRect().height + 3) {
                Gdx.app.log("hit", " top");
                this.position.y = world.getGameRect().y + world.getGameRect().height + 3;
                this.velocity.y *= -1;
            }
            // bottom
            else if (this.position.y > world.getGameRect().y - 3 && velocity.y > 0) {
                Gdx.app.log("hit", " bottom");
                if (!this.world.hasTouched()) {
                    this.world.getBaseCircle().setPositionX(position.x);
                    this.world.setTouched(true);
                }
                zeroVelocity();
                this.active = false;
                this.position = world.getBaseCirclePos();
                this.world.addInactive();
            }
        }    
    }

    public Vector2 getVelocity() {
        return velocity;
    }

    public float getVelocityX() {
        return velocity.x;
    }

    public float getVelocityY() {
        return velocity.y;
    }

    public void setVelocity(Vector2 velocity) {
        this.velocity = velocity;
    }

    public void setVelocityX(float x) {
        this.velocity.x = x;
    }

    public void setVelocityY(float y) {
        this.velocity.y = y;
    }

    public float getTheta() {
        return theta;
    }

    public void setTheta(float theta) {
        this.theta = theta;
    }

    public void zeroVelocity() {
        this.velocity.x = 0;
        this.velocity.y = 0;
    }

    public Vector2 getPosition() {
        return position;
    }

    public void setPositionY(float y) {
        this.position.y = y;
    }

    public void setPositionX(float x) {
        this.position.x = x;
    }

    public void setPosition(Vector2 position) {
        this.position = position;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public float getR() {
        return RADIUS;
    }

    public boolean wasShot() {
        return shot;
    }

    public void setShot(boolean shot) {
        this.shot = shot;
    }
}

Here is the code in GameWorld which is called when the player shoots:

public void transitionHasShot() {
    if (currentState == GameState.READY) {
        currentState = GameState.HASSHOT;

        velocity.y = (float) (-165 * Math.sin(theta));
        velocity.x = (float) (165 * Math.cos(theta));

        baseCircle.setActive(false);
        for (Projectile p : projectiles) {
            p.setVelocity(velocity);
        }
        projectiles.get(0).setActive(true);
    }
}

Let me know if you need any more info.

I solved the problem by changing the code in transitionHasShot():

change

for (Projectile p : projectiles) {
            p.setVelocity(velocity);
}

to:

 for (Projectile p : projectiles) {
            p.setVelocity(velocity.cpy());
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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