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

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

One time thread in libgdx after render loop starts

问题

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

  1. new Thread(new Runnable() {
  2. float time=0;
  3. @Override
  4. public void run() {
  5. while(redPos<10) {
  6. time += Gdx.graphics.getDeltaTime();
  7. redPos+=(int)time;
  8. }
  9. }
  10. }).start();

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

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

  1. float time = 0;
  2. void render(){
  3. if(redPos<10){
  4. time += Gdx.graphics.getDeltaTime();
  5. redPos+=(int)time;
  6. }
  7. batch.begin();
  8. batch.draw(ball, redPos, 5);
  9. batch.end();
  10. }

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

英文:

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:

  1. new Thread(new Runnable() {
  2. float time=0;
  3. @Override
  4. public void run() {
  5. while(redPos&lt;10) {
  6. time += Gdx.graphics.getDeltaTime();
  7. redPos+=(int)time;
  8. }
  9. }
  10. }).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-

  1. float time = 0;
  2. void render(){
  3. if(redPos&lt;10){
  4. time += Gdx.graphics.getDeltaTime();
  5. redPos+=(int)time;
  6. }
  7. batch.begin();
  8. batch.draw(ball, redPos, 5);
  9. batch.end();
  10. }

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

答案1

得分: 0

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

  1. public class MySprite extends Sprite {
  2. private boolean doScale;
  3. private float scaleBy;
  4. private float scaleTime;
  5. private float timeElapsed;
  6. private float progress;
  7. private float lastProgress;
  8. public MySprite(Texture texture) {
  9. super(texture);
  10. }
  11. public void scaleTo(float scaleTo, float time){
  12. scaleBy(scaleTo - getScaleX(), time);
  13. }
  14. public void scaleBy(float scaleBy, float time){
  15. this.scaleBy = scaleBy;
  16. doScale = true;
  17. scaleTime = time;
  18. timeElapsed = 0;
  19. lastProgress = 0;
  20. setOriginCenter();
  21. }
  22. @Override
  23. public void draw(Batch batch) {
  24. if (doScale) {
  25. timeElapsed += Gdx.graphics.getDeltaTime();
  26. progress = timeElapsed / scaleTime;
  27. progress = progress > 1 ? 1 : progress;
  28. float progressDelta = progress - lastProgress;
  29. float scaleBy = this.scaleBy * progressDelta;
  30. setScale(getScaleX() + scaleBy, getScaleY() + scaleBy);
  31. lastProgress = progress;
  32. if (progress == 1)
  33. doScale = false;
  34. }
  35. super.draw(batch);
  36. }
  37. }

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

  1. @Override
  2. public void create() {
  3. ...
  4. ...
  5. ...
  6. mySprite = new MySprite(texture);
  7. mySprite.scaleTo(2, 1); // 在1秒内缩放到200%
  8. }

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

  1. @Override
  2. public void create() {
  3. ...
  4. ...
  5. ...
  6. imageActor = new Image(texture);
  7. imageActor.addAction(Actions.scaleTo(2, 2, 1)); // 在1秒内缩放到200%
  8. }
英文:

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.

  1. public class MySprite extends Sprite {
  2. private boolean doScale;
  3. private float scaleBy;
  4. private float scaleTime;
  5. private float timeElapsed;
  6. private float progress;
  7. private float lastProgress;
  8. public MySprite(Texture texture) {
  9. super(texture);
  10. }
  11. public void scaleTo(float scaleTo, float time){
  12. scaleBy(scaleTo - getScaleX(),time);
  13. }
  14. public void scaleBy(float scaleBy, float time){
  15. this.scaleBy = scaleBy;
  16. doScale = true;
  17. scaleTime = time;
  18. timeElapsed = 0;
  19. lastProgress = 0;
  20. setOriginCenter();
  21. }
  22. @Override
  23. public void draw(Batch batch) {
  24. if(doScale){
  25. timeElapsed += Gdx.graphics.getDeltaTime();
  26. progress = timeElapsed/scaleTime;
  27. progress = progress &gt; 1?1: progress;
  28. float progressDelta = progress - lastProgress;
  29. float scaleBy = this.scaleBy *progressDelta;
  30. setScale(getScaleX()+scaleBy,getScaleY()+scaleBy);
  31. lastProgress = progress;
  32. if(progress == 1)
  33. doScale = false;
  34. }
  35. super.draw(batch);
  36. }
  37. }

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

  1. @Override
  2. public void create () {
  3. ...
  4. ...
  5. ...
  6. mySprite = new MySprite(texture);
  7. mySprite.scaleTo(2,1);//Scale to 200% in 1 seconds
  8. }

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

  1. @Override
  2. public void create () {
  3. ...
  4. ...
  5. ...
  6. imageActor = new Image(texture);
  7. imageActor.addAction(Actions.scaleTo(2,2,1));//Scale to 200% in 1 seconds
  8. }

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:

确定