{"id":16020455,"url":"https://github.com/leoncvlt/itto","last_synced_at":"2025-10-28T11:38:51.882Z","repository":{"id":78007784,"uuid":"474378903","full_name":"leoncvlt/itto","owner":"leoncvlt","description":"🕹️ An itty bitty javascript game engine","archived":false,"fork":false,"pushed_at":"2023-01-27T23:02:45.000Z","size":379,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T11:50:05.222Z","etag":null,"topics":["canvas","game-engine","javascript","minimalist"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leoncvlt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-26T14:55:38.000Z","updated_at":"2024-03-15T00:47:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"709e0d76-9c2e-4d3f-8192-ee7390942501","html_url":"https://github.com/leoncvlt/itto","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoncvlt%2Fitto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoncvlt%2Fitto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoncvlt%2Fitto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoncvlt%2Fitto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leoncvlt","download_url":"https://codeload.github.com/leoncvlt/itto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284914,"owners_count":20913691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canvas","game-engine","javascript","minimalist"],"created_at":"2024-10-08T17:40:36.100Z","updated_at":"2025-10-28T11:38:46.825Z","avatar_url":"https://github.com/leoncvlt.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `itto`\n\nAn itty bitty javascript game engine\n\n## ⬇️ Install \u0026 Usage\n\n### Global Object\n\n`\u003cscript src=\"https://unpkg.com/itto/itto.js\"\u003e\u003c/script\u003e`\n\n`const { game } = itto`\n\n### ES Module\n\n`\u003cscript type=\"module\" src=\"https://unpkg.com/itto/itto.mjs\"\u003e\u003c/script\u003e`\n\n`import { game } from \"itto\"`\n\n### Bundler\n\n`npm i itto`\n\n`import { game } from \"itto\"`\n\n## 🚀 Quick start\n\nCall `game.play` to initialize the game loop. The function takes on object with 4 named parameters:\n\n* `settings` - an `object` containing the game settings. See [game settings](#%EF%B8%8F-game-settings)\n* `init` - a `function` which runs once, on game start\n* `tick` - a `function` which runs on every game tick (by default, game runs at 60 ticks per second)\n* `draw` - a `function` which runs on every animation frame (always tries to target 60 frames per second)\n\n```js\nimport { game, clear, circle } from \"itto\";\n\nlet x, y;\nlet dx = Math.sign(Math.random() - 0.5) * 2;\nlet dy = Math.sign(Math.random() - 0.5) * 2;\nconst r = 8;\n\ngame.play({\n  settings: {\n    size: [360, 96],\n  },\n  init: () =\u003e {\n    x = game.width / 2;\n    y = game.height / 2;\n  },\n  tick: () =\u003e {\n    x = x + dx * game.delta;\n    y = y + dy * game.delta;\n\n    if (x \u003e game.width - r / 2 || x \u003c 0) {\n      dx = -dx;\n    }\n    if (y \u003e game.height - r / 2 || y \u003c 0) {\n      dy = -dy;\n    }\n  },\n  draw: () =\u003e {\n    clear(13);\n    circle(x, y, r, 14);\n  },\n});\n```\n\n## 💾 Examples\n\n* [benchmark](https://leoncvlt.github.io/itto/benchmark)\n* [breakout](https://leoncvlt.github.io/itto/breakout)\n* [hello](https://leoncvlt.github.io/itto/hello)\n* [snake](https://leoncvlt.github.io/itto/snake)\n\n## ⚙️ Game settings\n\nThe following properties can be passed to the `settings` parameter of the `game.play` function:\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| [canvas] | \u003ccode\u003eHTMLElement\u003c/code\u003e | \u003ccode\u003edocument.querySelector(\u0026quot;canvas\u0026quot;)\u003c/code\u003e | The canvas element. Defaults to the first canvas in the page. |\n| [size] | \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | \u003ccode\u003e[240, 236]\u003c/code\u003e | `[x, y]` tuple defining the width and height of the game |\n| resize | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e\u0026quot;integer\u0026quot;\u003c/code\u003e | The resizing behaviour - `itto` will attempt to resize the canvas to fill up its parent, while keeping the aspect ratio. \"integer\" will scale the canvas in integer increments (2x, 3x, etc). \"linear\" will always scale it to the max size. \"none\" or `null` will disable the automatic scaling, leaving you to sort out the canvas sizing manually |\n| [offset] | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | The amount of pixels to keep around the game area when resizing it. Pass a number for the same amount across all dimensions, or a `[x, y]` tuple to have different offset for the sides and the top/bottom |\n| [supersampling] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | Scale the game's graphics up by this amount, before rendering them on the canvas. Can make text / shapes sharper (especially on Chrome) at the expense of worse performance |\n| [assets] | \u003ccode\u003eobject\u003c/code\u003e | \u003ccode\u003e{}\u003c/code\u003e | An ojbect containing ID/Urls pairs for the external resources you want to preload and use in the game. See [Loading Assets](#-loading-assets) |\n| [palette] | \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | \u003ccode\u003e[sweetie16]\u003c/code\u003e | An array containing colors whose index can be passed to drawing functions (such as `clear` or `rect`. Defaults to the [Sweetie 16](https://lospec.com/palette-list/sweetie-16) palette) |\n\n\n\n## 🧩 Game properties\n\nInside `init`, `tick` or `draw` methods you can query different parameters from the `game` object to get specific properties of the game currently running:\n\n* [`game`](#game)\n    * [`.canvas`](#game.canvas) : \u003ccode\u003eHTMLElement\u003c/code\u003e\n    * [`.context`](#game.context) : \u003ccode\u003eCanvasContext\u003c/code\u003e\n    * [`.width`](#game.width) : \u003ccode\u003enumber\u003c/code\u003e\n    * [`.height`](#game.height) : \u003ccode\u003enumber\u003c/code\u003e\n    * [`.delta`](#game.delta) : \u003ccode\u003enumber\u003c/code\u003e\n    * [`.elapsed`](#game.elapsed) : \u003ccode\u003enumber\u003c/code\u003e\n    * [`.ready`](#game.ready) : \u003ccode\u003eboolean\u003c/code\u003e\n    * [`.palette`](#game.palette) : \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e\n    * [`.assets`](#game.assets) : \u003ccode\u003eobject\u003c/code\u003e\n\n\u003ca name=\"game.canvas\"\u003e\u003c/a\u003e\n\n#### `game.canvas` : \u003ccode\u003eHTMLElement\u003c/code\u003e\nThe canvas element the game is being drawn in\n\n\u003ca name=\"game.context\"\u003e\u003c/a\u003e\n\n#### `game.context` : \u003ccode\u003eCanvasContext\u003c/code\u003e\nDrawing context of the canvas element the game is being drawn in\n\n\u003ca name=\"game.width\"\u003e\u003c/a\u003e\n\n#### `game.width` : \u003ccode\u003enumber\u003c/code\u003e\nWidth of the game area, in pixels\n\n\u003ca name=\"game.height\"\u003e\u003c/a\u003e\n\n#### `game.height` : \u003ccode\u003enumber\u003c/code\u003e\nHeight of the game area, in pixels\n\n\u003ca name=\"game.delta\"\u003e\u003c/a\u003e\n\n#### `game.delta` : \u003ccode\u003enumber\u003c/code\u003e\nDelta time since last frame\n\n\u003ca name=\"game.elapsed\"\u003e\u003c/a\u003e\n\n#### `game.elapsed` : \u003ccode\u003enumber\u003c/code\u003e\nTime elapsed since the game start, in ticks (1 second = 60 ticks)\n\n\u003ca name=\"game.ready\"\u003e\u003c/a\u003e\n\n#### `game.ready` : \u003ccode\u003eboolean\u003c/code\u003e\nWhether the game assets have finished loading or not\n\n\u003ca name=\"game.palette\"\u003e\u003c/a\u003e\n\n#### `game.palette` : \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e\nAn array of colors as defined in the game settings\n\n\u003ca name=\"game.assets\"\u003e\u003c/a\u003e\n\n#### `game.assets` : \u003ccode\u003eobject\u003c/code\u003e\nThe external game assets, as defined in the game settings\n\n\n\n## 📦 Loading assets\n\nIn the game settings, you can use the `assets` object to map specific IDs to external resources you'd want to use during the game (for example, images to draw with the `image` function, or sounds to play with the `sound` function). The assets will be preloaded and processed accordingly. The `game.ready` variable will be set to `true` as soon as all assets are loaded, allowing you to create loading screens. \n\n```js\nimport { game, image, text } from \"itto\";\n\ngame.play({\n  settings: {\n    assets: {\n      logo: \"/assets/logo.png\"\n    }\n  },\n  draw: () =\u003e {\n    if (itto.ready) {\n     clear(0);\n     text(\"Loading...\", 8, 8)\n    }\n    clear(1);\n    image(logo, 16, 16);\n  },\n});\n```\n\nAssets are processed based on their extension:\n\n| Extension | Processed as  |\n| :--       | :-- |\n| `.jpg` `.jpeg` `.png` | [`HTMLImageElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image)\n| `.wav` `.mp3` `.ogg` | [`AudioBuffer`](https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer)\n| everything else | Raw URL of the asset\n\nWhile assets are normally used by passing their IDs to specific functions, they can also be accessed at any time inside `game` by accessing `game.assets[id]`, provided they are loaded (if not, it will return a promise).\n\n## ✨ Functions\n\nThe library offers a barebone set of functions to build your game with. All methods are named imports from the `\"itto\"` namespace or the global `itto` object.\n\n### 🎨 Drawing \n\n\u003cdl\u003e\n\u003cdt\u003e\u003ca href=\"#clear\"\u003e`clear(color)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eFills the screen with a solid color\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#line\"\u003e`line(x0, y0, x1, y1, color)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eDraws a line\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#rect\"\u003e`rect(x, y, w, h, color, border)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eDraws a rectangle\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#circle\"\u003e`circle(x, y, r, color, border)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eDraws a circle\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#image\"\u003e`image(id, x, y, sx, sy, w, h, options)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eDraws an image\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#text\"\u003e`text(text, x, y, color, options)`\u003c/a\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eDraws text on screen\u003c/p\u003e\n\u003c/dd\u003e\n\u003c/dl\u003e\n\n\u003ca name=\"clear\"\u003e\u003c/a\u003e\n\n### `clear(color)`\nFills the screen with a solid color\n\n\n| Param | Type | Description |\n| --- | --- | --- |\n| color | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e | the color to fill the screen with. Omit to use a transparent color |\n\n\u003ca name=\"line\"\u003e\u003c/a\u003e\n\n### `line(x0, y0, x1, y1, color)`\nDraws a line\n\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| x0 | \u003ccode\u003enumber\u003c/code\u003e |  | x coordinate of the line start point |\n| y0 | \u003ccode\u003enumber\u003c/code\u003e |  | y coordinate of the line start point |\n| x1 | \u003ccode\u003enumber\u003c/code\u003e |  | x coordinate of the line end point |\n| y1 | \u003ccode\u003enumber\u003c/code\u003e |  | y coordinate of the line end point |\n| color | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | the line color |\n\n\u003ca name=\"rect\"\u003e\u003c/a\u003e\n\n### `rect(x, y, w, h, color, border)`\nDraws a rectangle\n\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| x | \u003ccode\u003enumber\u003c/code\u003e |  | the x coordinate of the rectangle top-left corner |\n| y | \u003ccode\u003enumber\u003c/code\u003e |  | the y coordinate of the rectangle top-left corner |\n| w | \u003ccode\u003enumber\u003c/code\u003e |  | the width of the rectangle |\n| h | \u003ccode\u003enumber\u003c/code\u003e |  | the height of the rectangle |\n| color | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | the color of the rectangle |\n| border | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | whether to draw the border only or a filled shape |\n\n\u003ca name=\"circle\"\u003e\u003c/a\u003e\n\n### `circle(x, y, r, color, border)`\nDraws a circle\n\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| x | \u003ccode\u003enumber\u003c/code\u003e |  | the x coordinate of the circle center |\n| y | \u003ccode\u003enumber\u003c/code\u003e |  | the y coordinate of the circle center |\n| r | \u003ccode\u003enumber\u003c/code\u003e |  | the circle radius |\n| color | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | the circle color |\n| border | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | whether to draw the border only or a filled shape |\n\n\u003ca name=\"image\"\u003e\u003c/a\u003e\n\n### `image(id, x, y, sx, sy, w, h, options)`\nDraws an image\n\n\n| Param | Type | Description |\n| --- | --- | --- |\n| id | \u003ccode\u003estring\u003c/code\u003e | id of the asset of the image to draw |\n| x | \u003ccode\u003enumber\u003c/code\u003e | x coordinate to draw the image at |\n| y | \u003ccode\u003enumber\u003c/code\u003e | y coordinate to draw the image at |\n| sx | \u003ccode\u003enumber\u003c/code\u003e | top-left x coordinate of the portion of the source image to draw |\n| sy | \u003ccode\u003enumber\u003c/code\u003e | top-left y coordinate of the portion of the source image to draw |\n| w | \u003ccode\u003eobject\u003c/code\u003e | width of the portion of the source image to draw.  If undefined, defaults to the natural width of the image. |\n| h | \u003ccode\u003enumber\u003c/code\u003e | height of the portion of the source image to draw.  If undefined, defaults to the natural height of the image. |\n| options | \u003ccode\u003eobject\u003c/code\u003e | additional options |\n| options.origin | \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | `[x, y]` tuple of the coordinates of the origin.  Defaults to the top left corner `[0, 0]` |\n| options.anchor | \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | `[x, y]` tuple of the coordinates to apply scale / rotation from |\n| options.scale | \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e | `[x, y]` tuple of the scale factor values |\n| options.angle | \u003ccode\u003enumber\u003c/code\u003e | angle to rotate the image by |\n\n\u003ca name=\"text\"\u003e\u003c/a\u003e\n\n### `text(text, x, y, color, options)`\nDraws text on screen\n\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| text | \u003ccode\u003estring\u003c/code\u003e |  | the text to draw |\n| x | \u003ccode\u003enumber\u003c/code\u003e |  | x coordinate to draw the text at |\n| y | \u003ccode\u003enumber\u003c/code\u003e |  | y coordinate to draw the text at |\n| color | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | text color |\n| options | \u003ccode\u003eobject\u003c/code\u003e |  | additional options |\n| options.size | \u003ccode\u003enumber\u003c/code\u003e |  | text size, in px |\n| options.align | \u003ccode\u003estring\u003c/code\u003e |  | horizontal text alignment  (`left` / `center` / `right`, defaults to `left`) |\n| options.font | \u003ccode\u003estring\u003c/code\u003e |  | id of the font asset to use |\n\n\n\n### 🕹️ Input\n\nWhen querying an input with the `input` function, the inputs IDs map is as follows (IDs are case-insensitive):\n\n| ID            | Input  |\n| :--           | :----- |\n| `up`          | Up Arrow\n| `down`        | Down Arrow\n| `left`        | Left Arrow\n| `right`       | Right Arrow\n| `a`           | Z\n| `b`           | X\n| `c`           | A\n| `d`           | S\n| `mouse`       | Left Mouse Button\n| `mouseright`  | Right Mouse Button\n| `mousemid`    | Middle Mouse Button\n| `touch`       | One-finger touch\n| `touchtwo`    | Two-fingers touch\n| `touchthree`  | Three-fingers touch\n\n\u003cdl\u003e\n\u003cdt\u003e\u003ca href=\"#input\"\u003e`input(id, period)`\u003c/a\u003e ⇒ \u003ccode\u003eboolean\u003c/code\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eChecks if an input (keyboard / gamepad / mouse / touchscreen) is or has been pressed.\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003ca href=\"#pointer\"\u003e`pointer()`\u003c/a\u003e ⇒ \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e\u003c/dt\u003e\n\u003cdd\u003e\u003cp\u003eChecks the current pointer position\u003c/p\u003e\n\u003c/dd\u003e\n\u003c/dl\u003e\n\n\u003ca name=\"input\"\u003e\u003c/a\u003e\n\n### `input(id, period)` ⇒ \u003ccode\u003eboolean\u003c/code\u003e\nChecks if an input (keyboard / gamepad / mouse / touchscreen) is or has been pressed.\n\n**Returns**: \u003ccode\u003eboolean\u003c/code\u003e - whether the queried input is pressed or not  \n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| id | \u003ccode\u003enumber\u003c/code\u003e |  | the id of the input |\n| period | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e1\u003c/code\u003e | if the input is held down,the time in game ticks before the function    returns `true` again. If omitted defaults to an interval of `1`, checking every tick.    Pass `false` or `0` to check for a single press only. |\n\n**Example**  \n```js\ninput(\"up\") // returns true as long as the arrow up key is pressed\ninput(\"a\", 60) // if Z is pressed, returns true every 60 ticks (1 seconds), otherwise false\ninput(\"mouse\", 0) // returns true if the left mouse button has just been pressed, otherwise false\ninput() // returns true if any input is being pressed\n```\n\u003ca name=\"pointer\"\u003e\u003c/a\u003e\n\n### `pointer()` ⇒ \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e\nChecks the current pointer position\n\n**Returns**: \u003ccode\u003eArray.\u0026lt;number\u0026gt;\u003c/code\u003e - `[x, y]` tuple containing the current x and y pointer coordinates  \n\n\n### 🔊 Sound\n\n### `sound`\nPlays a sound\n\n\n| Param | Type | Description |\n| --- | --- | --- |\n| id | \u003ccode\u003estring\u003c/code\u003e | id of the asset of the sound file to play |\n| options | \u003ccode\u003eobject\u003c/code\u003e | additional options |\n| options.channel | \u003ccode\u003enumber\u003c/code\u003e | the channel to play the sound in.  Playing a sound in a specific channel stops other sounds playing in that same channel.  Call this method with a `null` src and a channel to stop the sound playing in that channel. |\n| options.volume | \u003ccode\u003enumber\u003c/code\u003e | volume to play the sound at |\n| options.loop | \u003ccode\u003eboolean\u003c/code\u003e | whether to loop the sound or not |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoncvlt%2Fitto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleoncvlt%2Fitto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoncvlt%2Fitto/lists"}