Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Improvement on examples #454

Merged
merged 6 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const player = add([
anchor("center"), // anchor() component defines the pivot point (defaults to "topleft")
]);

// .onUpdate() is a method on all game objects, it registers an event that runs every frame
// .onUpdate() is a method that's found in all game objects, it registers an event that runs every frame
player.onUpdate(() => {
// .angle is a property provided by rotate() component, here we're incrementing the angle by 120 degrees per second, dt() is the time elapsed since last frame in seconds
player.angle += 120 * dt();
Expand Down
8 changes: 5 additions & 3 deletions examples/ai.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Use state() component to handle basic AI

// Start kaboom
// Start kaplay
kaplay();

// Load assets
Expand Down Expand Up @@ -54,17 +54,19 @@ enemy.onStateEnter("attack", async () => {
]);
}

// Waits 1 second to make the enemy enter in "move" state
await wait(1);
enemy.enterState("move");
});

// When we enter "move" state, we stay there for 2 sec and then go back to "idle"
enemy.onStateEnter("move", async () => {
await wait(2);
enemy.enterState("idle");
});

// Like .onUpdate() which runs every frame, but only runs when the current state is "move"
// Here we move towards the player every frame if the current state is "move"
// .onStateUpdate() will run every frame, but only when the current state is "move"
// We move the enemy in the direction of the player
enemy.onStateUpdate("move", () => {
if (!player.exists()) return;
const dir = player.pos.sub(enemy.pos).unit();
Expand Down
51 changes: 35 additions & 16 deletions examples/animation.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// @ts-check

// Start kaboom
// Start kaplay
kaplay();

loadSprite("bean", "sprites/bean.png");
loadSprite("bag", "sprites/bag.png");
// We use the default function to load the bean sprite
loadBean();

// Rotating
// We add a bean that rotates with the animate component
const rotatingBean = add([
sprite("bean"),
pos(50, 50),
Expand All @@ -15,22 +15,24 @@ const rotatingBean = add([
animate(),
]);

// Trying sprite change
rotatingBean.sprite = "bag";

// We use the 'animate()' function provided by the animate component
// This will rotate the bean from 0 to 360 degrees in 2 seconds
// The direction "forwards" means it will go back to 0 when it ends, which makes this a loop
rotatingBean.animate("angle", [0, 360], {
duration: 2,
direction: "forward",
});

// Moving right to left using ping-pong
// Now we'll move this bean from left to right
const movingBean = add([
sprite("bean"),
pos(50, 150),
anchor("center"),
animate(),
]);

// This will animate the bean from left to right in 2 seconds
// The direction "ping-pong" means that when it goes to the right, it will move back to the left
movingBean.animate("pos", [vec2(50, 150), vec2(150, 150)], {
duration: 2,
direction: "ping-pong",
Expand All @@ -44,12 +46,14 @@ const secondMovingBean = add([
animate({ relative: true }),
]);

// The fact that is relative, means that instead of setting the bean to these positions (vec2(50, 150), vec2(150, 150))
// It will ADD those positions to the position the bean was spawned in
secondMovingBean.animate("pos", [vec2(50, 150), vec2(150, 150)], {
duration: 2,
direction: "ping-pong",
});

// Changing color using a color list
// We'll change the color of the bean using a list of colors
const coloringBean = add([
sprite("bean"),
pos(50, 300),
Expand All @@ -58,11 +62,14 @@ const coloringBean = add([
animate(),
]);

// It will animate the color the bean color from white to red to green to blue to white
// In 8 seconds, and when it's over i'll start over again
coloringBean.animate("color", [WHITE, RED, GREEN, BLUE, WHITE], {
duration: 8,
direction: "forward",
});

// Changing opacity using an opacity list
// We'll change the opacity of the bean using a list of opacities
const opacitingBean = add([
sprite("bean"),
pos(150, 300),
Expand All @@ -71,19 +78,22 @@ const opacitingBean = add([
animate(),
]);

// We'll animate the opacity from 1, to 0, to 1 during 8 seconds
// This time, we'll be using an easing!
opacitingBean.animate("opacity", [1, 0, 1], {
duration: 8,
easing: easings.easeInOutCubic,
});

// Moving in a square like motion
// We'll move this bean in a square shape
const squaringBean = add([
sprite("bean"),
pos(50, 400),
anchor("center"),
animate(),
]);

// Passing an array of keyframes (the positions) it'll move in a square shape
squaringBean.animate(
"pos",
[
Expand All @@ -96,14 +106,16 @@ squaringBean.animate(
{ duration: 8 },
);

// Moving in a square like motion, but with custom spaced keyframes
// We'll move the bean in a square shape again, but this time we'll be using timing
const timedSquaringBean = add([
sprite("bean"),
pos(50, 400),
anchor("center"),
animate(),
]);

// This will move the bean in the same positions as before in the same time
// But the timings will make the movement from one keyframe to another quicker or slower
timedSquaringBean.animate(
"pos",
[
Expand All @@ -125,6 +137,7 @@ timedSquaringBean.animate(
},
);

// We'll move this bean in a curve
// Using spline interpolation to move according to a smoothened path
const curvingBean = add([
sprite("bean"),
Expand All @@ -134,6 +147,7 @@ const curvingBean = add([
rotate(0),
]);

// This will move bean in these positions, but using a different interpolation
curvingBean.animate(
"pos",
[
Expand All @@ -146,37 +160,42 @@ curvingBean.animate(
{ duration: 8, direction: "ping-pong", interpolation: "spline" },
);

// We'll animate a little bean to rotate around the curvingBean!
// Here we're creating a pivot
const littleBeanPivot = curvingBean.add([
animate(),
rotate(0),
named("littlebeanpivot"),
]);

// And animating the pivot, you know this!
littleBeanPivot.animate("angle", [0, 360], {
duration: 2,
direction: "reverse",
});

// We'll animate a little bean to rotate around the pivot
const littleBean = littleBeanPivot.add([
sprite("bean"),
pos(50, 50),
anchor("center"),
scale(0.25),
animate(),
rotate(0),
named("littlebean"),
]);

// And here we animate the little bean
littleBean.animate("angle", [0, 360], {
duration: 2,
direction: "forward",
});

console.log(JSON.stringify(serializeAnimation(curvingBean, "root"), "", 2));
// We'll the serialize an animation and log it to the console so we can see all the current animation channels
console.log(JSON.stringify(serializeAnimation(curvingBean, "root"), null, 2));

// Debug piece of code that draws a line in the curve that the curving bean goes through, don't mind it
/*onDraw(() => {
drawCurve(t => evaluateCatmullRom(
vec2(200, 400),\
vec2(200, 400),
vec2(250, 500),
vec2(300, 400),
vec2(350, 500), t), { color: RED })
Expand Down
4 changes: 3 additions & 1 deletion examples/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
// audio playback & control

kaplay({
// Don't pause audio when tab is not active
// This makes it so the audio doesn't pause when the tab is changed
backgroundAudio: true,
background: [0, 0, 0],
});

// Loads the bell sound, and OtherworldlyFoe sound
loadSound("bell", "/examples/sounds/bell.mp3");
loadSound("OtherworldlyFoe", "/examples/sounds/OtherworldlyFoe.mp3");

Expand Down Expand Up @@ -51,6 +52,7 @@ onKeyPressRepeat("left", () => music.speed -= 0.1);
onKeyPressRepeat("right", () => music.speed += 0.1);
onKeyPress("m", () => music.seek(4.24));

// We store some keys in a string
const keyboard = "awsedftgyhujk";

// Simple piano with "bell" sound and the second row of a QWERTY keyboard
Expand Down
5 changes: 4 additions & 1 deletion examples/bench.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// @ts-config

// bench marking sprite rendering performance
// Bench marking sprite rendering performance
// We use this example to test and bench the performance of kaplay rendering

kaplay();

loadSprite("bean", "sprites/bean.png");
loadSprite("bag", "sprites/bag.png");

// Adds 5 thousand objects which can be a bean or a bag in random positions
for (let i = 0; i < 5000; i++) {
add([
sprite(i % 2 === 0 ? "bean" : "bag"),
Expand All @@ -17,6 +19,7 @@ for (let i = 0; i < 5000; i++) {

onDraw(() => {
drawText({
// You can get the current fps with debug.fps()
text: debug.fps(),
pos: vec2(width() / 2, height() / 2),
anchor: "center",
Expand Down
75 changes: 43 additions & 32 deletions examples/binding.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,69 @@
// @ts-check

// You can set the input bindings for your game!
kaplay({
buttons: {
"jump": {
gamepad: ["south"],
keyboard: ["up", "w"],
mouse: "left",
},
"inspect": {
gamepad: "east",
keyboard: "f",
mouse: "right",
},
},
buttons: {
// Buttons for jumping
"jump": {
// When using a gamepad the button for jumping will be south
gamepad: ["south"],
// When using a keyboard the button will be "up" or "w"
keyboard: ["up", "w"],
// When using a mouse the button will be "left"
mouse: "left",
},
// Buttons for inspecting
"inspect": {
gamepad: "east",
keyboard: "f",
mouse: "right",
},
},
});

loadSprite("bean", "/sprites/bean.png");
loadBean()

// Set the gravity acceleration (pixels per second)
setGravity(1600);

// Add player game object
const player = add([
sprite("bean"),
pos(center()),
area(),
// body() component gives the ability to respond to gravity
body(),
sprite("bean"),
pos(center()),
area(),
// body() component gives the ability to respond to gravity
body(),
]);

// Add a platform to hold the player
add([
rect(width(), 48),
outline(4),
area(),
pos(0, height() - 48),
// Give objects a body() component if you don't want other solid objects pass through
body({ isStatic: true }),
rect(width(), 48),
outline(4),
area(),
pos(0, height() - 48),
// Give objects a body() component if you don't want other solid objects pass through
body({ isStatic: true }),
]);

// Adds an object with a text
add([
text("Press jump button", { width: width() / 2 }),
pos(12, 12),
text("Press jump button", { width: width() / 2 }),
pos(12, 12),
]);

// This runs when the button for "jump" is pressed (will be on any input device)
onButtonPress("jump", () => {
debug.log(getLastInputDeviceType());
// You can get the type of device that the last input was inputted in!
debug.log(getLastInputDeviceType());

if (player.isGrounded()) {
// .jump() is provided by body()
player.jump();
}
// Now we'll check if the player is on the ground to make it jump
if (player.isGrounded()) {
// .jump() is provided by body()
player.jump();
}
});

// When the button for inspecting is pressed we will log in the debug console for our game the text "inspecting"
onButtonDown("inspect", () => {
debug.log("inspecting");
debug.log("inspecting");
});
2 changes: 1 addition & 1 deletion examples/burp.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ add([
]);

// burp() on click / tap for our friends on mobile
onClick(burp);
onClick(() => burp());
Loading