In this tutorial, we'll walk through the creation of a simple physics-based doll using the Pixalo game engine. We will cover each part of the code step by step, explaining its purpose and functionality.
1. Importing Pixalo
First, we need to import the Pixalo engine into our project. This can be done through a CDN link. Here's how we do it:
import Pixalo from 'https://cdn.jsdelivr.net/gh/pixalo/pixalo/dist/pixalo.esm.js';
2. Initializing the Game
Next, we'll create a new instance of the Pixalo engine and set up our game canvas. We define the dimensions and background color, as well as the physics properties (in this case, gravity).
const game = new Pixalo('#canvas', {
width: window.innerWidth,
height: window.innerHeight,
background: '#031C1B',
physics: { gravity: { y: 800 } }
});
game.start();
- #canvas: The ID of the HTML element where the game will be rendered.
- width & height: Set to the window's dimensions.
- background: The game background color.
- gravity: Gravity is set to 800 units in the y-direction.
3. Creating a Static Ground
Now, let's create a static ground object that will serve as the base for our doll. This ground will be immovable.
game.append('ground', {
x: 0,
y: game.baseHeight - 40,
width: game.baseWidth,
height: 40,
backgroundColor: '#268985',
physics: { bodyType: 'static' }
});
- We set its position, dimensions, and color, and define it as a static body using
bodyType: 'static'.
4. Defining Body Part Dimensions
Next, we need to define the dimensions of the different body parts of our doll. This includes the head, torso, arms, and legs.
const HEAD_D = 44; // head diameter
const TORSO_W = 35, TORSO_H = 70; // torso
const ARM_W = 45, ARM_H = 10; // upper arms
const LEG_W = 14, LEG_H = 65; // upper legs
These constants will help us position and size the body parts accurately.
5. Factory Function for Body Parts
We create a helper function called part to simplify creating draggable body parts.
function part(id, opts) {
opts.draggable = true; // Pixalo flag
return game.append(id, opts); // returns the sprite
}
This function sets the draggable property and appends a new part to the game.
6. Assembling the Doll
Now we can assemble the doll using the part function to create each body part. All parts will be positioned initially to look connected before physics kicks in.
const head = part('head', {
shape: 'circle', width: HEAD_D, height: HEAD_D,
backgroundColor: '#F3A71A',
physics: { density: 1, friction: 0.3, restitution: 0.2 },
x: (game.baseWidth - HEAD_D) / 2,
y: 50,
text: '> <\n_', // Face
lineHeight: 0.1
});
const torso = part('torso', {
width: TORSO_W, height: TORSO_H,
backgroundColor: '#268985',
borderRadius: 6,
physics: { density: 1, friction: 0.3, restitution: 0.1 },
x: (game.baseWidth - TORSO_W) / 2,
y: head.y + HEAD_D // Top edge = bottom edge of head
});
const armL = part('armL', {
width: ARM_W, height: ARM_H,
backgroundColor: '#F3A71A',
borderRadius: 6,
physics: { density: 0.8, friction: 0.3 },
x: torso.x - ARM_W, // Right edge = left edge of trunk
y: torso.y + 25
});
const armR = part('armR', {
width: ARM_W, height: ARM_H,
backgroundColor: '#F3A71A',
borderRadius: 6,
physics: { density: 0.8, friction: 0.3 },
x: torso.x + TORSO_W, // Left edge = right edge of trunk
y: torso.y + 25
});
const legL = part('legL', {
width: LEG_W, height: LEG_H,
backgroundColor: '#268985',
borderRadius: 6,
physics: { density: 1, friction: 0.3 },
x: torso.x,
y: torso.y + TORSO_H
});
const legR = part('legR', {
width: LEG_W, height: LEG_H,
backgroundColor: '#268985',
borderRadius: 6,
physics: { density: 1, friction: 0.3 },
x: torso.x + TORSO_W - LEG_W,
y: torso.y + TORSO_H
});
Each body part is created with specific colors, physics properties (density, friction, and restitution), and initial positions calculated to center them horizontally.
7. Setting Joint Stiffness
Next, we establish a joint stiffness variable to control the flexibility of the doll.
const stiffness = 6; // 0-100 scale
This variable will affect the joints between body parts.
8. Helper Function for Joints
We will create revolute joints that connect two body parts together this way:
function join(entityA, entityB, anchorX, anchorY, lowerAngle = -45, upperAngle = 45) {
const config = {
type: 'revolute',
anchor: { x: anchorX, y: anchorY },
collideConnected: false
};
// Configure limits and motor based on stiffness
if (stiffness > 5) {
config.limits = { lower: lowerAngle, upper: upperAngle };
}
if (stiffness > 2) {
config.motor = { speed: 0, torque: stiffness * 0.6 };
}
return game.physics.joint(entityA, entityB, config);
}
This function sets up the constraints and motors for the joints based on the stiffness level.
9. Wiring the Skeleton
In this step, we use the join function to connect all body parts together once the physics bodies are ready.
game.one('update', () => {
join(head, torso, head.x + HEAD_D / 2, head.y + HEAD_D, -25, 25);
join(torso, armL, torso.x, torso.y + 25, -70, 40);
join(torso, armR, torso.x + TORSO_W, torso.y + 25, -40, 70);
join(torso, legL, torso.x + LEG_W / 2, torso.y + TORSO_H, -30, 20);
join(torso, legR, torso.x + TORSO_W - LEG_W / 2, torso.y + TORSO_H, -20, 30);
});
10. Adding Interactivity
Let's add keyboard controls so we can reset the doll or toggle gravity.
game.on('keydown', (e) => {
switch (e.key) {
case 'r':
// Reset doll position
head.style({ x: (game.baseWidth - HEAD_D) / 2, y: 50 });
torso.style({ x: (game.baseWidth - TORSO_W) / 2, y: head.y + HEAD_D });
break;
case 'g':
// Toggle gravity
const currentGravity = game.physics.world.GetGravity();
if (currentGravity.y === 0) {
game.physics.setGravity(0, 800);
} else {
game.physics.setGravity(0, 0);
}
break;
}
});
The keydown event allows us to reset the doll's position and control gravity dynamically.
11. Displaying Instructions
Lastly, we will add a set of instructions for the player.
game.append('instructions', {
x: 100, y: 20,
text: 'Drag body parts around!\nPress R to reset\nPress G to toggle gravity',
fontSize: 16,
color: '#FFF'
});
Conclusion
Congratulations! You've successfully created a simple physics-based doll using the Pixalo engine. This project illustrates how to work with physics, joints, and interactivity. Feel free to modify the stiffness or play around with the body's parts to create your own unique characters!
๐ Website: https://pixalo.xyz
๐ GitHub: https://github.com/pixalo/pixalo
Happy coding!
Top comments (0)