英文:
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<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<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 > 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
	}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论