我有以下问题。我想创建一个太空射击游戏,我正在使用Stage类,并且我有一个名为SpaceShip的演员扩展了Group类。现在我想向SpaceShip组中添加另一个名为LaserBeam的演员,但我不能获取我想要的激光束与不属于太空船群行小行星和游戏中敌人的角色之间的碰撞检测的坐标。LaserBeam使用的动画纹理在LaserBeam构造函数中的尺寸最大为width:1000和height:90我将LaserBeam添加到了SpaceShip演员中。 当我尝试使用激光束时(我将其设置为可见,然后可能 检测我的代码中的冲突),激光恰好位于我的空间顶部 船上的演员,但是包围激光束的边界多边形仍然保留在其他坐标系中,至少我是这样认为的。据了解,群体演员具有自己的与舞台坐标分离的坐标系,所以我想知道是否存在易于使用边界多边形检测组中的演员与舞台上的演员之间的碰撞。 我使用ShapeRenderer在演员周围绘制了多边形的线,如您所见,激光束多边形不在应有的位置。
如果有更简便的方法将激光武器对准我的太空飞船演员,请分享。
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;
}
}