On this topic: | | Part 3 | | | Part 1 Part 2 Part 4 Part 5 Part 6 The was a bit long so we’re going to move forward in smaller increments. last article Let’s start with a discussion on how works in games. The 18th century Swiss mathematician, physicist, astronomer, logician and (quite a resume) Leonhard Euler devised a way for us to predict where an object’s going to be based on two things: its current position and its speed. We actually used it in our in the method of our class: movement engineer previous article update() Square this.x += 1 * movementMultiplier;this.y += 1.5 * movementMultiplier; Euler integration works wonders in games where speed is and it’s also very easy on the processor; unfortunately you’ll quickly find out it’s not quite enough if you’re planning on building a physics engine… it becomes highly inaccurate. Let’s visualize this: constant Euler integration In the image above, the distance between two peaks on the grid is ~30px, the speed of our ball is 60px every frame and we’re running this for 10 frames (at 60fps that’s 1/6 of a second). This seems fine… the movement is constant so it should be easy to work with, right?… well, not really; let’s add a wall in there: Between frames 5 and 6 you can see an impressively drawn wall; what’s even more impressive is that with the current logic, that ball will pass through the wall like it’s not even there. This might be cool if you’re trying to achieve teleportation, not so much if you’re reaching for collision. In a game were detecting multiple object collisions is necessary, if you take into account that each object has it’s own trajectory, speed and external forces acting on it… Euler integration proves insufficient. Another way would be using one of the but they can put a strain on the processor; it’s perfect for precision physics calculations but probably overkill for our purposes. Runge–Kutta methods The go to method in most games would be to use the equations of the French physicist Loup Verlet, specifically . The main difference is that with Verlet integration you’re calculating the speed of an object and not its position in the next frame. You do this by subtracting the previous position from the current position. Verlet integration I keep saying speed so I’m going to correct myself; . The difference between speed an velocity matters to us, because speed is ignorant of direction, whereas velocity is a vector quantity and it is direction aware; it’s a really small and hugely important distinction. we’re actually calculating velocity let velocity = currentPosition - previousPosition;position += velocity; Does this mean our collision problem goes away? Not really but it makes it easier to rectify; we can calculate the next state based on our current and previous states, enabling us to resolve any conflicts before we render. We’ll create a in the game engine and this will allow for other objects to use it if needed; for now it should: VerletModel expose getters and setters for the x and y velocities expose getters and setters for the x and y position values engine/models/VerletModel.js This model could potentially hold variables for other things like: , , and so on or it could be extended by another class that adds these features. The reasoning behind this is simple: all games have movement but not all games need complex physics. gravity friction rotation Let’s see an example; we’ll create another square that moves as described above and add a bit of acceleration and friction logic to our model. A classic MVC approach should do the trick: class which will extend : it will store all data related to our square as well as an method which will overwrite the default one in . SquareModel VerletModel update() VerletModel verletSquare/square/SquareModel.js You can see we’re using the , , and setters and getters from to calculate friction which we then add to the acceleration. x y vx vy VerletModel class which will extend **Scene (**for now; as this should extend , which we don’t have yet) SquareView DisplayObject verletSquare/square/SquareView.js The receives an instance of the and which it updates in its own method. You’ll also see that we’re storing a scene reference on the model, as this is needed to properly wrap the square to its parent scene. This is annoying and should be done automatically but we won’t worry about that yet. SquareView SquareModel SquareCtrl update() class which will extend SquareCtrl Keyboard verletSquare/square/SquareCtrl.js The has one job: to change the acceleration based on the currently pressed key. When we release a key, the friction is set to 0.94. This value will be multiplied with our velocity and the result added to our acceleration. SquareCtrl In the end we’ll get a friction effect which slows down the object on every frame. The acceleration increases by 0.5 on every frame if we keep the key pressed. We do have a bit of code duplication in our method but it’s fine for the purposes of this demo. update() Let’s put everything together: verletSquare/index.js Here’s a demo of this in action (use the arrow keys): Source code: _game-physx - A small utility for JavaScript game making_github.com raduGaspar/game-physx At this point you might be thinking: Well yes, the complexity is increasing; some of it can’t be avoided and part of it is due to our MVC approach. Aren’t we just adding more complexity to our code? As always, there are improvements to be made here; for starters, the way the scene reference is added on the model is suboptimal, we also have code duplication in our controller and quite a bit of logic in our MVC. We’ll slowly move away from MVC and go towards a Flux architecture as these articles progress but all things considered we did learn more about how movement works in games. Next time we’ll create a class and cover: sprite sheets, sprites, animated sprites and frame rate control. DisplayObject