2

The only thing that I do inside the animation loop is update the x and y coordinates but the circle is still not moving as smoothly as it should. This is the fiddle. I am using CraftyJS to animate the circle. Here is the code that does the animation:

.bind("EnterFrame", function (eventData) {
     this.x += this.xDirection;
     this.y += this.yDirection;
     if (this.x < 0) this.xDirection *= -1;
     if (this.y < 0) this.yDirection *= -1;
     if (this.x > (0.96*gWidth)) this.xDirection *= -1;
     if (this.y > (0.96*gHeight)) this.yDirection *= -1;
});

Rest of the calculations are done just once and I don't think just a bunch of multiplications should make the animation lag. Any help on how to make the animation smooth will be appreciated.

I failed to mention earlier that xDirection is equal to 0.005*gWidthand yDirection is equal to 0.005*gHeight. If gWidth is 600 the ball is still moving just 3px. Is it really that fast? I don't want to specify the width in pixels (gWidth is the screen size) because then the gameplay will be different on different devices. Is there some way to move the circle quickly while still keeping the animation smooth?

Neena Vivek
  • 667
  • 7
  • 19
  • this is because the minimum distance which the circle moves is too big. Try making it less – It's a trap Sep 10 '16 at 09:27
  • Rachit is correct... Start with minimum distance(1 px) – Rayon Sep 10 '16 at 09:27
  • This would make it twice as smooth "this.x += this.xDirection / 2; this.y += this.yDirection / 2;" , at the same time twice as slow – Velimir Tchatchevsky Sep 10 '16 at 09:31
  • I will definitely try that but I also want the circle to move quickly. Can it be both smooth and quick at the same time? – Neena Vivek Sep 10 '16 at 09:34
  • You should be able to move the circle the distance you have and have it smooth. I looked at the time between frames, and you are all over the place 45 to 16 ms and that is inconsistent with about 1 in 4 frames being more than a whole frame slow. I see you are using some Lib. I cant help you, but consider the built in API rather than 3rd party (as that is awful for a circle (not blaming you, blaming the lib)) – Blindman67 Sep 10 '16 at 09:40
  • @Blindman67 The framerate is about `50`. Should it be `60` instead? Actually, I am trying to create a few games and using a library will significantly reduce development time. Do you have any suggestions for some other libraries that will give more optimal performance? – Neena Vivek Sep 10 '16 at 09:43
  • @Rayon @Rachit Setting the movement speed to be `1px` did not help. – Neena Vivek Sep 10 '16 at 09:44
  • Why do you need a library?? Everything you need is comes with the browser, and using the Built in API will give better performance, But if you must use a lib try http://phaser.io/ its well made – Blindman67 Sep 10 '16 at 09:50
  • @Blindman67 I was looking for libraries to do stuff like collision detection etc. – Neena Vivek Sep 10 '16 at 10:07
  • Fair enough. Just don't overcook the game, you can find many simple JS module that will suit any number of game requirements, some of the "Game" libs out there try to be everything for everyone and the code base underneath is excessively complex with features that are seldom used. Small and simple modules are best. If you use a lib don't be afraid to go in and make changes (its also a great way to learn). Good luck and have fun. – Blindman67 Sep 10 '16 at 10:35
  • @Blindman67 I was also looking for something that would be very lightweight without extra bloat, that's why I gave craftyjs a shot. :). I have one question. How did you come up with `I looked at the time between frames, and you are all over the place 45 to 16 ms and that is inconsistent with about 1 in 4 frames being more than a whole frame slow.`? – Neena Vivek Sep 10 '16 at 12:04
  • I added a timer to the `EnterFrame` event listener and a var to keep the time of the last call. `var lastTime` as global then in event function `console.log( performance.now()-lastTime); lastTime = performance.now();` which gave me the number milliseconds since it was last called. – Blindman67 Sep 10 '16 at 13:09
  • I like to use `console.time("label") ... console.timeEnd("label")` to get the amount of milliseconds between the two, as it's usually a cleaner way to do it. Also, if all you need is collision, it might be best to write your own little library for your game. Collision detection between two circles or two squares is relatively simple, and when you write your own library, you learn to code better and you know exactly what might be killing the 10 frames per second. – Howzieky Sep 10 '16 at 17:23
  • 1
    You may get better results by fiddling with [Crafty.timer](http://craftyjs.com/api/Crafty-timer.html). [This fiddle](https://jsfiddle.net/8ugqxz3z/8/) runs a bit smoother for me. – mucaho Apr 01 '17 at 01:39

1 Answers1

1

Changing from 'fixed' to 'variable' steptype smoothed things out for me. After Crafty.init, call Crafty.timer.steptype():

const _step = 20;
Crafty.init(gWidth, gHeight, document.getElementById('game'));
Crafty.timer.steptype('variable', _step);
// ...

You may also want to update your EnterFrame to take in to account time elapsed since the last frame:

.bind("EnterFrame", function (eventData) {
    let dt = eventData.dt;
    this.x += this.xDirection * dt / _step;
    this.y += this.yDirection * dt / _step;
    // ...
John Harper
  • 135
  • 1
  • 7