一个时间线程在libgdx中在渲染循环启动后。

huangapple go评论78阅读模式
英文:

One time thread in libgdx after render loop starts

问题

有没有可能在渲染方法后立即运行一个线程,只在渲染循环调用它一次,因为渲染循环会在每次迭代中调用它。这是我的线程:

new Thread(new Runnable() {
    float time=0;
    @Override
    public void run() {
        while(redPos<10) {
            time += Gdx.graphics.getDeltaTime();
            redPos+=(int)time;
        }
    }
}).start();

我对线程不是很熟悉,所以不知道正确的做法。如果我做错了,请纠正我。

更新:我通过将 redPos 增量移动到渲染方法中使其正常工作,如下所示:

float time = 0;
void render(){
    if(redPos<10){
        time += Gdx.graphics.getDeltaTime();
        redPos+=(int)time;
    }
    batch.begin();
    batch.draw(ball, redPos, 5);
    batch.end();
}

为精灵使用线程来进行动画处理是一个不好的主意,因为它会与渲染线程不同步。

英文:

Is it possible to run a thread just after render method only once since render loop will call it in every iteration. This is my thread:

    new Thread(new Runnable() {
        float time=0;
        @Override
        public void run() {
            while(redPos&lt;10) {
                time += Gdx.graphics.getDeltaTime();
                redPos+=(int)time;
            }
        }
    }).start();

I am not very much acquainted with threads so dont know proper way of doing it.
Please correct me if I am going wrong

Update: I got it working by shifting redPos increment to render method like this-

float time = 0;
void render(){
    if(redPos&lt;10){
        time += Gdx.graphics.getDeltaTime();
        redPos+=(int)time;
    }
    batch.begin();
    batch.draw(ball, redPos, 5);
    batch.end();
}

Using Thread for animating sprite was a bad idea as it will be desynced with render thread.

答案1

得分: 0

你可能希望避免在这个任务中使用线程。您可以创建一个继承自Sprite的类,并编写一些代码,以在draw方法中逐渐改变Sprite的缩放。

public class MySprite extends Sprite {

    private boolean doScale;
    private float scaleBy;
    private float scaleTime;
    private float timeElapsed;
    private float progress;
    private float lastProgress;

    public MySprite(Texture texture) {
        super(texture);
    }

    public void scaleTo(float scaleTo, float time){
        scaleBy(scaleTo - getScaleX(), time);
    }

    public void scaleBy(float scaleBy, float time){
        this.scaleBy = scaleBy;
        doScale = true;
        scaleTime = time;
        timeElapsed = 0;
        lastProgress = 0;

        setOriginCenter();
    }

    @Override
    public void draw(Batch batch) {
        if (doScale) {
            timeElapsed += Gdx.graphics.getDeltaTime();
            progress = timeElapsed / scaleTime;
            progress = progress > 1 ? 1 : progress;

            float progressDelta = progress - lastProgress;
            float scaleBy = this.scaleBy * progressDelta;
            setScale(getScaleX() + scaleBy, getScaleY() + scaleBy);

            lastProgress = progress;

            if (progress == 1)
                doScale = false;
        }
        super.draw(batch);
    }
}

然后在MySprite中使用scaleTo()scaleBy()方法...

@Override
public void create() {
    ...
    ...
    ...

    mySprite = new MySprite(texture);
    mySprite.scaleTo(2, 1); // 在1秒内缩放到200%
}

虽然libGDX已经为此提供了Actions,但您可能要考虑使用Actor

@Override
public void create() {
    ...
    ...
    ...

    imageActor = new Image(texture);
    imageActor.addAction(Actions.scaleTo(2, 2, 1)); // 在1秒内缩放到200%
}
英文:

You may wan't to avoid threads for this task. You can create a class that extends Sprite and write some code that changes the scale of the Sprite progressively in the draw method.

public class MySprite extends Sprite {


    private boolean doScale;
    private float   scaleBy;
    private float   scaleTime;
    private float   timeElapsed;
    private float   progress;
    private float   lastProgress;

    public MySprite(Texture texture) {
        super(texture);
    }

    public void scaleTo(float scaleTo, float time){
        scaleBy(scaleTo - getScaleX(),time);
    }

    public void scaleBy(float scaleBy, float time){
        this.scaleBy = scaleBy;
        doScale = true;
        scaleTime = time;
        timeElapsed = 0;
        lastProgress = 0;

        setOriginCenter();
    }

    @Override
    public void draw(Batch batch) {
        if(doScale){
            timeElapsed += Gdx.graphics.getDeltaTime();
            progress = timeElapsed/scaleTime;
            progress = progress &gt; 1?1: progress;

            float progressDelta = progress - lastProgress;
            float scaleBy =  this.scaleBy *progressDelta;
            setScale(getScaleX()+scaleBy,getScaleY()+scaleBy);

            lastProgress = progress;

            if(progress == 1)
                doScale = false;
        }
        super.draw(batch);
    }
}

Then use the method scaleTo() or scaleBy() in MySprite...

    @Override
	public void create () {
        ...
        ...
        ...

		mySprite = new MySprite(texture);
		mySprite.scaleTo(2,1);//Scale to 200% in 1 seconds
	}

Although libGdx already provide Actions for this, you may want to consider the use of an Actor

    @Override
	public void create () {
        ...
        ...
        ...

        imageActor = new Image(texture);
		imageActor.addAction(Actions.scaleTo(2,2,1));//Scale to 200% in 1 seconds
	}

huangapple
  • 本文由 发表于 2020年4月11日 09:30:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/61151012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定