【问题标题】:libgdx won't draw sprite or animationlibgdx 不会绘制精灵或动画
【发布时间】:2014-06-07 00:33:46
【问题描述】:

好像我无法让 draw 方法工作??? 好像是 bullet.draw(batcher) 不起作用,我不明白为什么子弹是精灵。 我制作了一个 Sprite[] 并将它们添加为动画。 会这样吗?

我试过了

batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(), bullet.getY(), bullet.getOriginX() / 2, bullet.getOriginY() / 2, bullet.getWidth(), bullet.getHeight(), 1, 1, bullet.getRotation());

但这不起作用,它绘制的唯一方法是这个

batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(), bullet.getY());

下面是代码。

// 这是在一个资产类中

texture = new Texture(Gdx.files.internal("SpriteN1.png"));
texture.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

bullet1 = new Sprite(texture, 380, 350, 45, 20);
bullet1.flip(false, true);

bullet2 = new Sprite(texture, 425, 350, 45, 20);
bullet2.flip(false, true);

Sprite[] bullets = { bullet1, bullet2 };
bulletAnimation = new Animation(0.06f, bullets);
bulletAnimation.setPlayMode(Animation.PlayMode.LOOP);

// 这是 GameRender 类

public class GameRender() {
private Bullet bullet;
private Ball ball;

public GameRenderer(GameWorld world) {
myWorld = world;
cam = new OrthographicCamera();
cam.setToOrtho(true, 480, 320);

batcher = new SpriteBatch();
// Attach batcher to camera
batcher.setProjectionMatrix(cam.combined);

shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(cam.combined);

// Call helper methods to initialize instance variables
initGameObjects();
initAssets();
}

private void initGameObjects() {
ball = GameWorld.getBall();
bullet = myWorld.getBullet();
scroller = myWorld.getScroller();
}

private void initAssets() {
ballAnimation = AssetLoader.ballAnimation;
bulletAnimation = AssetLoader.bulletAnimation;
}

public void render(float runTime) {

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

batcher.begin();
// Disable transparency 
// This is good for performance when drawing images that do not require
// transparency.
batcher.disableBlending();

// The ball needs transparency, so we enable that again.
batcher.enableBlending();


batcher.draw(AssetLoader.ballAnimation.getKeyFrame(runTime), ball.getX(), ball.getY(),         ball.getWidth(), ball.getHeight());

batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(),     bullet.getY());

// End SpriteBatch
batcher.end();
}
}

// 这是游戏世界类

public class GameWorld {

public static Ball ball;
private Bullet bullet;
private ScrollHandler scroller;

public GameWorld() {
ball = new Ball(480, 273, 32, 32);
bullet = new Bullet(10, 10);
scroller = new ScrollHandler(0);
}

public void update(float delta) {
ball.update(delta);
bullet.update(delta);
scroller.update(delta);
}

public static Ball getBall() {
return ball;
}

public ScrollHandler getScroller() {
return scroller;
}

public Bullet getBullet() { 
return bullet;
}
}

无论如何让精灵工作?

我正在添加子弹类,看看那里是否有问题。

public class Bullet extends Sprite {

public static final float BULLET_HOMING = 6000;
public static final float BULLET_SPEED = 300;
private Vector2 velocity;
private float lifetime;

public Bullet(float x, float y) {
    velocity = new Vector2(0, 0);
    setPosition(x, y);
}

public void update(float delta) {
    float targetX = GameWorld.getBall().getX();
    float targetY = GameWorld.getBall().getY();
    float dx = targetX - getX();
    float dy = targetY - getY();

    float distToTarget = (float) Math.sqrt(dx * dx + dy * dy);
    dx /= distToTarget;
    dy /= distToTarget;
    dx *= BULLET_HOMING;
    dy *= BULLET_HOMING;
    velocity.x += dx * delta;
    velocity.y += dy * delta;

    float vMag = (float) Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
    velocity.x /= vMag;
    velocity.y /= vMag;
    velocity.x *= BULLET_SPEED;
    velocity.y *= BULLET_SPEED;

    Vector2 v = velocity.cpy().scl(delta);
    setPosition(getX() + v.x, getY() + v.y);
    setOriginCenter();
    setRotation(velocity.angle());
    lifetime += delta;
    setRegion(AssetLoader.bulletAnimation.getKeyFrame(lifetime));
}
}

【问题讨论】:

  • 你也能发图片吗?
  • 在哪里发布图片?在游戏中?那么是的,但它们是 TextureRegions,你不能旋转 textureRegions。有办法,但对我来说太难了。

标签: java android libgdx draw


【解决方案1】:

您的关键帧保存在一个称为子弹的数组中,但是当您调用动画构造函数时,您将传递一个名为“目标”的东西作为第二个参数。您应该尝试传递“子弹”,如:

bulletAnimation = new Animation(0.06f,bullets);

我认为使用 Sprite[] 应该没有问题,因为 Sprite 类扩展了 TextureRegion。

------ OP 修正了错字,仍然没有工作------

我认为问题出在batcher.draw()call 的原始参数上。 Sprite 的位置是相对于 SpriteBatch 坐标系的原点,而 Sprite 的原点是相对于这个位置(即 Sprite 矩形的左下角)。为了在 Sprite 的中心获得一个原点,我认为 originX 应该是宽度/2,而 originY 应该是高度/2。所以试试:

batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime),bullet.getX(),bullet.getY(), bullet.getWidth()/2,bullet.getHeight()/2,bullet.getWidth(),bullet.getHeight(),1,1,bullet.getRotation());

因为如果您的 getOriginX/Y 方法返回相对于 SpriteBatcher 坐标系(屏幕坐标)的原点,那么您的 Sprite 可能会围绕某个荒谬的原点旋转和缩放,最终被绘制到屏幕外。

我希望我是对的,问题已经解决了。

-- OP 发布了更多代码,'bullet' 类--

当您在 draw 方法中调用 bullet.getWidth()bullet.getHeight() 时,它们将返回 0.0f,因为您没有为它们指定值。请记住,您实际绘制的 Sprite 是 AssetLoader 类中的 bullet1 和 bullet2。尝试设置子弹的宽度和高度:

setSize(AssetLoader.bullet1.getWidth(), AssetLoader.bullet1.getHeight());

在你的子弹构造函数中。

我认为您也不需要在子弹类中使用 setRegion(),因为您实际绘制的 Sprite 是子弹 1 和 2。

手指交叉。

【讨论】:

  • 对不起,这是一个错字,我正在传递子弹,但如果我使用 bullet.draw(batcher),它仍然不会绘制;
  • 我也不知道你用 bullet.getOriginX/Y 做了什么,为什么你把这个值减半?该函数肯定会首先返回缩放/旋转的原点吗?这些函数返回什么?
  • 我不知道我被告知要尝试,但即使没有它也不会绘制。
  • 谢谢你的回复,我试过这个方法,子弹不会在画布上绘制。我尝试只使用一个单独的 png 精灵,但它仍然不会旋转,因此它要么没有正确地绘制在屏幕上,要么它们在子弹类中丢失了一些东西。如何通过数学旋转图像是解决方案。再次感谢您
  • 嗨,ArthurBrown,我添加了子弹类,也许那里有什么东西可能导致这种情况????
【解决方案2】:

尝试将更新方法更改为此

Vector2 target = new Vector2(GameWorld.getBall().getX(), GameWorld.getBall().getY());
    target.sub(getX(), getY());
    target.nor().scl(BULLET_HOMING);
    velocity.add(target.scl(delta));
    velocity.nor().scl(BULLET_SPEED);

    Vector2 v = velocity.cpy().scl(delta);
    translate(v.x, v.y);

    setOriginCenter();
    setRotation(velocity.angle());

这应该会稍微清理你的代码

【讨论】: