Skip to content

Commit

Permalink
feat: contributors, faster
Browse files Browse the repository at this point in the history
  • Loading branch information
lajbel committed Nov 7, 2024
1 parent 574df70 commit f08efee
Show file tree
Hide file tree
Showing 18 changed files with 2,805 additions and 459 deletions.
4 changes: 3 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { defineConfig } from "astro/config";
import { defineConfig, passthroughImageService } from "astro/config";
import rehypeKatex from "rehype-katex";
import remarkMath from "remark-math";
import { rehypeKAPLAY } from "./plugins/rehypeKAPLAY";

// https://astro.build/config
export default defineConfig({
Expand Down Expand Up @@ -42,7 +43,8 @@ export default defineConfig({
remarkMath,
],
rehypePlugins: [
rehypeKatex,
[rehypeKatex, {}],
[rehypeKAPLAY, {}],
],
},
});
135 changes: 82 additions & 53 deletions guides/en/1_getting_started/3_components.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
title: Components
title: Components & Tags
description: Learn how to create and use components in KAPLAY, the HTML5 Game Engine for JavaScript and TypeScript.
url: components
---

# Components

As we said, components are the building blocks of game objects. They define the
behavior of the object, like how it moves, how it looks, and how it interacts
with other objects.
Components are the building blocks of game objects. They define the behavior of
the object, like how it moves, how it looks, and how it interacts with other
objects.

This guide covers:

Expand All @@ -22,65 +22,117 @@ The components system of KAPLAY (the `C` of ECS) is powerful and flexible.
## What is a Component?

A component is a piece of code that defines a specific behavior of a game
object. It can return a set of properties and methods that are attached to the
game object.
object. It usually return a set of **properties** and **methods** that are
attached to the game object.

For example, the `pos()` component returns the `pos` property and the `move()`
method.
For example, the [`pos()`](/doc/ctx/pos) component returns the `pos` property
and the `move()` method:

```js
const player = add([
pos(80, 80),
]);

player.move(100, 0); // move the player 100 pixels to the right
console.log(player.pos); // { x: 180, y: 80 }
player.move(100, 0); // move the player 100 pixels to the right, this is a method
console.log(player.pos); // { x: 180, y: 80 }, this is a property
```

## Using Components
There are a lot of useful components in KAPLAY like:

To assign a component to a game object, we usually do it on the initialization
time of the object. For example, in a **Butterfly** game object, we can assign a
`sprite()` component.
- [`sprite()`](/doc/ctx/sprite) for rendering images
- [`area()`](/doc/ctx/area) for collision detection, with methods like
[`onCollide()`](/doc/AreaComp#AreaComp-onCollide)
- [`rect()`](/doc/ctx/rect) for rendering rectangles
- [`text()`](/doc/ctx/text) for rendering text
- [`scale()`](/doc/ctx/scale) for scaling the game object

You can see all the components in the [API Reference](/doc/ctx/pos).

## What is a tag?

Tags are names, labels or keywords that group game objects, such as enemies,
friends, etc.

For example, these objects could be tagged as an enemy:

```js
const ghosty = add([
sprite("ghosty"),
"enemy",
]);

const bobo = add([
sprite("bobo"),
"enemy",
]);
```

There are many functions that use tags.

For example [`get()`](/doc/ctx/get), to _get_ all game objects with a certain
tag:

```js
const enemies = get("enemy"); // ghosty and bobo
```

## Adding Components and tags

To assign a component or tag to an object, we usually do it on the object's
creation.

For example, in a **player** game object, we can assign a `sprite()` component
and the `friend` tag:

```js
loadSprite("butterfly", "sprites/butterfly.png");

const player = add([
sprite("butterfly"),
"friend",
]);
```

### Dynamic Components
## Dynamic Components and tags

Usually, you want to assign a component in real time, for example, when the
player picks up a power-up. You can use the `GameObjRaw.use()` method
player picks up a power-up.

You can use the [`GameObjRaw.use()`](/doc/GameObjRaw#GameObjRaw-use) method,
passing the component or tag you want to assign.

For example, to change the sprite of the player to a big butterfly and add the
`big` tag:

```js
const player = add([
// original sprite
sprite("butterfly"),
pos(80, 80),
"normal",
]);

// new sprite
player.use(sprite("big-butterfly"));
// new tag
player.use("big");
```

Use is a **use**ful method, but what if you want to remove a component? You can
use the `GameObjRaw.unuse()` method, passing the component id (the name):
Use is a **use**ful method, but what if you want to remove a component/tag? You
can use the `GameObjRaw.unuse()` method, passing the component id or tag name.

```js
player.unuse("sprite");
player.unuse("sprite"); // removes the sprite component
player.unuse("big"); // removes the big tag
```

## Getting Components

When you assign a component, the game object will be updated with new methods
and properties that are specific to that component.
When you assign a component, the game object will be updated with new
**methods** and **properties** that are specific to that component.

For example, when you assign a `pos()`, you can access the `pos` property of the
game object. But also the methods of `move()` and `scale()`.
game object. But also the methods of `move()` or `moveTo()`.

```js
const player = add([
Expand Down Expand Up @@ -108,46 +160,23 @@ const player = add([
console.log(player.c("pos")); // all related state to pos()
```

## Tags

Tags are a special kind of component that are used to identify groups of game
objects, like the player, the enemies, the bullets, etc. In fact, all components
are tags too, for example, the `sprite()` component is a `sprite` tag.

To create a tag, you only have to pass a string to the `add()` method.

```js
const enemy = add([
sprite("bee"),
area(),
"enemy",
]);
```

There's many functions that uses tags, for example `onClick()` to detect clicks
on game objects with an `area()` component.

```js
onClick("enemy", (enemy) => {
destroy(enemy);
});
```

### Getting Tags
## Getting Tags

You can also check if a game object has a tag using the `is()` method.
You can check if a game object has a tag using the `is()` method.

```js
if (player.is("enemy")) {
// do something
debug.log("It is an enemy!");
}
```

This function also works with components.
This function also works with components, passing the id (the name) of the
component.

```js
if (player.is("sprite")) {
// do something
// check if it has a sprite component or a rect component
if (player.is("sprite") || player.is("rect")) {
debug.log("It is visible!");
}
```

Expand Down
16 changes: 13 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
"scripts": {
"install": "git submodule init && cd kaplay && pnpm i",
"dev": "npm run doc && astro dev",
"start": "npm run doc && astro dev",
"start": "npm run doc && npm run contributors && astro dev",
"build": "npm run doc && astro check && astro build && pnpm run pagefind:build",
"preview": "astro preview",
"astro": "astro",
"doc": "node scripts/buildDoc.js",
"markdoc": "node scripts/markdownDoc.js",
"contributors": "node scripts/contributors.js",
"fmt": "dprint fmt",
"build:publish": "npm run build && wrangler pages deploy dist",
"cf:deploy": "npm run build && wrangler pages deploy dist",
Expand All @@ -21,6 +22,8 @@
},
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/cloudflare": "^11.2.0",
"@astrojs/markdown-remark": "^5.3.0",
"@astrojs/mdx": "^3.1.8",
"@astrojs/sitemap": "^3.2.1",
"@astrojs/tailwind": "^5.1.2",
Expand All @@ -32,28 +35,35 @@
"@fontsource/ibm-plex-sans": "^5.1.0",
"@kaplayjs/crew": "^1.6.1",
"@lunariajs/core": "^0.1.1",
"@nanostores/persistent": "^0.10.2",
"@qwikdev/astro": "^0.6.3",
"@types/node": "^20.16.10",
"astro": "^4.16.7",
"astro-meta-tags": "^0.3.1",
"astro-pagefind": "^1.6.0",
"astro-robots-txt": "^1.0.0",
"dprint": "^0.47.2",
"i": "^0.3.7",
"github-contributors": "^0.4.1",
"hast": "^1.0.0",
"marked": "^13.0.3",
"nanostores": "^0.10.3",
"pnpm": "^9.12.0",
"rehype": "^13.0.2",
"rehype-attr": "^3.0.3",
"rehype-katex": "^7.0.1",
"rehype-mathjax": "^6.0.0",
"remark-attr": "^0.11.1",
"remark-math": "^6.0.0",
"sharp": "^0.33.5",
"tailwindcss": "^3.4.13",
"typescript": "^5.6.2"
"typescript": "^5.6.2",
"unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@kaplayjs/dprint-config": "^1.1.0",
"@shikijs/transformers": "^1.21.0",
"@tailwindcss/typography": "^0.5.15",
"@types/hast": "^3.0.4",
"clsx": "^2.1.1",
"daisyui": "^4.12.12",
"dts-bundle-generator": "^9.5.1",
Expand Down
48 changes: 48 additions & 0 deletions plugins/rehypeKAPLAY.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { RehypePlugin } from "@astrojs/markdown-remark";
import type { Element } from "hast";
import { visit } from "unist-util-visit";

export const rehypeKAPLAY: RehypePlugin = () => {
console.log("ffeasa");
return (tree) => {
visit(tree, (node) => {
if (node.type != "element") {
return;
}

const element = node as Element;

if (!isAnchor(element)) {
return;
}

const url = getUrl(element);

if (isDoc(url)) {
element.properties!["data-astro-reload"] = "all";
}
});
};
};

const isAnchor = (element: Element) =>
element.tagName == "a" && element.properties
&& "href" in element.properties;

const getUrl = (element: Element) => {
if (!element.properties) {
return "";
}

const url = element.properties["href"];

if (!url) {
return "";
}

return url.toString();
};

const isDoc = (url: string) => {
return url.startsWith("/doc");
};
Loading

0 comments on commit f08efee

Please sign in to comment.