Как использовать актера из группы для обнаружения столкновений в libGDX - PullRequest
0 голосов
/ 04 октября 2018

У меня следующая проблема. Я хочу создать космический шутер, я использую класс Stage и у меня есть актер SpaceShip, расширяющий класс Group. Теперь я хочу добавить еще одного актера LaserBeam в группу SpaceShip, но не могуполучить координаты, которые я хочу для обнаружения столкновений между лазерным лучом и актерами, которые не являются частью астероидов и врагов группы космических кораблей в игре. LaserBeam использует анимацию текстур, размеры которых меняются до ширины: 1000 и высоты: 90 в конструкторе LaserBeamи я добавил LaserBeam к актеру космического корабля.Когда я пытаюсь использовать лазерный луч (я устанавливаю его видимым, а затем в моем коде можно обнаружить столкновения), лазер приятно центрируется поверх моего актера космического корабля, но граничный многоугольник, который окружал лазерный луч, остается в какой-то другой системе координатПо крайней мере, я так думаю. Из того, что понимаю, у актеров группы есть свои собственные системы координат, которые отделены от координат этапа, поэтому я хочу знать, есть ли какая-либо легкая обнаруживаемая коллизия между акторами в группе и той, что на сцене, используяграничные полигоны.Я использовал ShapeRenderer, чтобы нарисовать линии многоугольника вокруг актеров, и, как вы можете видеть, мой полигон лазерного луча находится не там, где он должен быть.

Если есть какой-либо более простой способ центрировать оружие лазерного луча на моем пространствеактер корабля, поделитесь пожалуйста.

image1 image2

public class SpaceShip extends MainActor {
private Array<Laser> lasers;//spaceship lasers
private int laserCounter;//laser counter
private float rotationSpeed;//rotation speed of the spaceship
private LaserBeam laserBeam;//laser beam of the spaceship
public SpaceShip(float x, float y, Stage stage) {
    super(x, y, stage);
    loadTexture("spacecrafts/blueship.png");
    //set to smaller size
    setSize(120, 90);
    setOrigin(getWidth()/2, getHeight()/2);

    setBoundaryPolygon(8);
    setAcceleration(300);
    setMaxSpeed(200);
    setDeceleration(30);
    rotateBy(90);

    // initialize variables
    lasers = new Array<>();
    laserBeam = new LaserBeam(0, 0, stage);
    laserCounter = 0;
    rotationSpeed = 110;


    laserBeam.setPosition(laserBeam.getX() + getHeight(), laserBeam.getY());
    addActor(laserBeam);
}

public void act(float delta) {
    super.act(delta);
    desktopControls(delta);
    applyPhysics(delta);
    boundToWorld();
}

/**
 * Keyboards controls.
 * @param delta time since the last render.
 * */
private void desktopControls(float delta) {
    //forward thruster
    if(Gdx.input.isKeyPressed(Input.Keys.UP)) {
        accelerateAtAngle(getRotation());
    }
    //backward thruster
    if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
        accelerateBackwards();
    }
    //thruster left
    if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
        rotateBy(rotationSpeed * delta);
    }
    //thruster right
    if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
        rotateBy(-(rotationSpeed * delta));
    }
}

/**
 * It creates and fires lasers at a frequency set by the parameter.
 * This method adds new lasers to the list of lasers until the list
 * size equals the frequency value.At that point it is assumed the list
 * is full,and lasers previously added to the list will be retrieved
 * and used again.This way there is far less impact on the game
 * performance than constantly adding and removing new lasers from
 * the stage.
 * @param laserFrequency maximum number of lasers that can appear on the
 * screen at the same time while shooting(also the max number of lasers
 * on a stage).
 * @return laser just fired with all parameters set.
 * */
public Laser fireLaser(int laserFrequency) {
    Laser laser;
    if(lasers.size < laserFrequency) {
        laser = new Laser(0,0, getStage());
        lasers.add(laser);
    } else {
        if(laserCounter == lasers.size) {
            laserCounter = 0;
        }
        laser = lasers.get(laserCounter++);
    }
    laser.setLaserParameters(this, 1000);
    return laser;
}

/**
 * Fires laser beam for this spaceship.
 * @return laser beam object for this spaceship
 * */
public LaserBeam fireLaserBeam() {
    laserBeam.start();
    return laserBeam;
}

}

public class LaserBeam extends MainActor {
public LaserBeam(float x, float y, Stage stage) {
    super(x, y, stage);
    loadAnimationFromFiles(frames(), 0.2f, false);

    //set to smaller size
    setSize(1000, 90);

    setName("LaserBeam");
    setBoundaryPolygon(8, 20, 20);
    setAnimationPaused(true);
    setVisible(false);
}

public void act(float delta) {
    super.act(delta);

    if(isAnimationFinished()) {
        reset();
    }
}

/**
 * Resets the laser beam animation,pauses the animation and sets the
 * visibility to false.
 * */
private void reset() {
    resetAnimation();
    setAnimationPaused(true);
    setVisible(false);
}

/**
 * Starts the laser beam animation and sets the visibility
 * to true.
 * */
public void start() {
    setAnimationPaused(false);
    setVisible(true);
}

/**
 * Returns the array of frames that can be used in the animation.
 * @return array of frames stored in the assets folder of this
 * project.
 * */
private String[] frames() {
    String[]paths = new String[6];
    for(int i = 0; i < paths.length; i++) {
        paths[i] = "lasers/Beam" +(i+1) + ".png";
    }
    return paths;
}

}

...