📜 ⬆️ ⬇️

Combining Easel.js and Box2d on Canvas

One of the most difficult aspects of creating our game was to combine two very cool libraries: Easel.js and Box2dWeb . In this article we will look at the basics of creating the main game objects of the game so that you can convert box2d dimensions to the X, Y system, and the parameters for rotating the items on the display at easel.

Before embarking on this article, it is assumed that you have a basic knowledge of how box2d and easel work. If you are not familiar with the work of the box2d world, please read the box2d materials from Seth Lad. If you are not familiar with the work of easel, then you need to familiarize yourself with the documentation so that you understand how to add objects to the scene and learn the entire display hierarchy (hint: it has several common aspects with Flash programming).

Well, let's get into the details. We are going to create a simple demonstration of falling pink birds.

View in browser - Download source code
')
Since we already understand the basics of working with Easel and Box2d, we will skip the installation code and delve into the process of combining the two libraries. If you want to recall the information, simply download the demo zip archive or view the source code on the demo page.

Now in Easel it is easy enough to add an object to the scene in a certain position. This is how we add birds to the screen based on the cyclic function.

Notice that all the code inserts from the following are non-functional excerpts from demo.js. To get a working code, you need to download a zip archive .

var tick = function(dt, paused) { birdDelayCounter++; if(birdDelayCounter % 10 === 0) { // ,       birdDelayCounter = 0; birds.spawn(); } } 


 var spawn = function() { var birdBMP = new Bitmap("images/bird.png"); birdBMP.x = Math.round(Math.random()*500); birdBMP.y = -30; birdBMP.regX = 25; //        birdBMP.regY = 25; stage.addChild(birdBMP); } 


This seems quite familiar. With this code, the bird is added to the scene at a randomly selected X position at the top of the canvas. The object itself is quite versatile. You can copy its position, shift it, etc. However, if you want to apply physical laws to your object, you need to send it to box2d.

regX and regY (starting points) are important when you bind the easel object to box2d. This is due to the fact that box2d objects have an initial position in the center, in contrast to the position at the upper left of easel objects.

So, our objects have already been added to the scene, it's time to send them to box2d for further impressive actions.

 box2d.createBird(birdBMP); 


 var createBird = function(skin) { var birdFixture = new b2FixtureDef; birdFixture.density = 1; birdFixture.restitution = 0.6; birdFixture.shape = new b2CircleShape(24 / SCALE); //  bird.png       var birdBodyDef = new b2BodyDef; birdBodyDef.type = b2Body.b2_dynamicBody; birdBodyDef.position.x = skin.x / SCALE; //  skin x  y  box2d      birdBodyDef.position.y = skin.y / SCALE; var bird = world.CreateBody(birdBodyDef); bird.CreateFixture(birdFixture); bodies.push(bird); } 


Using the above code, a round box2d body is created in the same position and size as the bitmap. Unfortunately, the image of the bird is not tied to the box2d object. Without debug canvas, you cannot see a round box2d object, and the bird will remain fixed. How do we make the image follow box2d's position?

... Actors! Actors are the main part of a visual box2d demonstration. Basically, they are forced to move during the game cycle and translate the metric positions of box2d bodies back to pixel coordinates. Let's create it.

 var actor = new actorObject(bird, skin); bird.SetUserData(actor); //  actor     ,       ,    

 var actorObject = function(body, skin) { this.body = body; this.skin = skin; this.update = function() { //  box2d    this.skin.rotation = this.body.GetAngle() * (180 / Math.PI); this.skin.x = this.body.GetWorldCenter().x * SCALE; this.skin.y = this.body.GetWorldCenter().y * SCALE; } actors.push(this); } 


This is a basic example of actor objects, if you wanted, you could extend it with almost any indicators (identifiers, etc.). We defined a participant for the box2d object and we need to update it during the physical loop.

 //  world.step for(var i=0, l=actors.length; i<l; i++) { actors<i>.update(); } 


The image now displays everything that the box2d body does as part of the modeling of physical processes.

If you want to remove the body and its image at a certain point, you can add the body to the array. Bodies must be removed before each step.

 //  world.step for(var i=0, l=bodiesToRemove.length; i<l; i++) { removeActor(bodiesToRemove<i>.GetUserData()); // get the actor object in the user data of the body and send to removeActor function bodiesToRemove<i>.SetUserData(null); world.DestroyBody(bodiesToRemove<i>); } //  world.step if(bodies.length > 30) { bodiesToRemove.push(bodies[0]); bodies.splice(0,1); } 


 var removeActor = function(actor) { stage.removeChild(actor.skin); actors.splice(actors.indexOf(actor),1); } 


Finally we did it! You can do a lot of significant things if you understand how box2d filters work during a collision, overshoot detection, etc. I hope that we will learn more about this material in the future.

View in browser - Download source code

Author Justin Schrader
www.luxanimals.com/blog/article/combining_easel_box2d

Source: https://habr.com/ru/post/192288/


All Articles