diff --git a/.eslintrc.json b/.eslintrc.json
index 67c73009..42851225 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -16,7 +16,7 @@
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
- "project": ["./packages/*/tsconfig.json"]
+ "project": ["./examples/*/tsconfig.json", "./packages/*/tsconfig.json"]
},
"plugins": ["@typescript-eslint", "simple-import-sort"],
"rules": {
diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml
new file mode 100644
index 00000000..effd96fd
--- /dev/null
+++ b/.github/workflows/dist.yml
@@ -0,0 +1,16 @@
+name: Dist
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ compile:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/prepare
+ - run: yarn compile
+ - run: yarn dist
diff --git a/docs/Development.md b/docs/Development.md
index 321dfb3a..88da96f2 100644
--- a/docs/Development.md
+++ b/docs/Development.md
@@ -33,6 +33,7 @@ cd EightBittr
yarn
yarn lerna bootstrap
yarn run hydrate
+yarn lerna run dist
```
### Local Development
diff --git a/packages/eightbittr/docs/walkthrough/1. Package Setup.md b/docs/walkthrough/1. Package Setup.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/1. Package Setup.md
rename to docs/walkthrough/1. Package Setup.md
diff --git a/packages/eightbittr/docs/walkthrough/10. Data.md b/docs/walkthrough/10. Data.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/10. Data.md
rename to docs/walkthrough/10. Data.md
diff --git a/packages/eightbittr/docs/walkthrough/11. Text.md b/docs/walkthrough/11. Text.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/11. Text.md
rename to docs/walkthrough/11. Text.md
diff --git a/packages/eightbittr/docs/walkthrough/2. Actors.md b/docs/walkthrough/2. Actors.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/2. Actors.md
rename to docs/walkthrough/2. Actors.md
diff --git a/packages/eightbittr/docs/walkthrough/3. Instantiation.md b/docs/walkthrough/3. Instantiation.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/3. Instantiation.md
rename to docs/walkthrough/3. Instantiation.md
diff --git a/packages/eightbittr/docs/walkthrough/4. Physics.md b/docs/walkthrough/4. Physics.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/4. Physics.md
rename to docs/walkthrough/4. Physics.md
diff --git a/packages/eightbittr/docs/walkthrough/5. Inputs.md b/docs/walkthrough/5. Inputs.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/5. Inputs.md
rename to docs/walkthrough/5. Inputs.md
diff --git a/packages/eightbittr/docs/walkthrough/6. Players.md b/docs/walkthrough/6. Players.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/6. Players.md
rename to docs/walkthrough/6. Players.md
diff --git a/packages/eightbittr/docs/walkthrough/7. Controls.md b/docs/walkthrough/7. Controls.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/7. Controls.md
rename to docs/walkthrough/7. Controls.md
diff --git a/packages/eightbittr/docs/walkthrough/8. Collisions.md b/docs/walkthrough/8. Collisions.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/8. Collisions.md
rename to docs/walkthrough/8. Collisions.md
diff --git a/packages/eightbittr/docs/walkthrough/9. Events.md b/docs/walkthrough/9. Events.md
similarity index 100%
rename from packages/eightbittr/docs/walkthrough/9. Events.md
rename to docs/walkthrough/9. Events.md
diff --git a/packages/eightbittr/docs/walkthrough/README.md b/docs/walkthrough/README.md
similarity index 92%
rename from packages/eightbittr/docs/walkthrough/README.md
rename to docs/walkthrough/README.md
index e6cba699..1df25fd9 100644
--- a/packages/eightbittr/docs/walkthrough/README.md
+++ b/docs/walkthrough/README.md
@@ -3,7 +3,7 @@
This page will guide you through the steps to create a new game using the EightBittr game engine.
The game will feature a player avoiding boxes bouncing around a screen like an old screensaver and include a basic suite of tests.
-> Make sure you've read through the other documentation pages listed in the [EightBittr README.md](../../README.md) before reading this one!
+> Make sure you've read through the other documentation pages listed in the [README.md](./README.md) before reading this one!
## Preface
diff --git a/examples/FullScreenSaver/.npmignore b/examples/FullScreenSaver/.npmignore
new file mode 100644
index 00000000..bfe21769
--- /dev/null
+++ b/examples/FullScreenSaver/.npmignore
@@ -0,0 +1,6 @@
+node_modules/
+test/
+*.test.*
+npm-debug.log
+*.ts
+!*.d.ts
diff --git a/examples/FullScreenSaver/README.md b/examples/FullScreenSaver/README.md
new file mode 100644
index 00000000..fa8babd8
--- /dev/null
+++ b/examples/FullScreenSaver/README.md
@@ -0,0 +1,39 @@
+
+
+# FullScreenSaver
+
+[](https://prettier.io)
+
+[](http://badge.fury.io/js/fullscreensaver)
+[](https://gitter.im/FullScreenShenanigans/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+Example game with EightBittr tooling.
+
+
+
+## Usage
+
+Documentation coming soon™️!
+
+
+
+## Development
+
+This repository is a portion of the [EightBittr monorepo](https://raw.githubusercontent.com/FullScreenShenanigans/EightBittr).
+See its [docs/Development.md](../../docs/Development.md) for details on how to get started. 💖
+
+### Running Tests
+
+```shell
+yarn run test
+```
+
+Tests are written in [Mocha](https://github.com/mochajs/mocha) and [Chai](https://github.com/chaijs/chai).
+Their files are written using alongside source files under `src/` and named `*.test.ts?`.
+Whenever you add, remove, or rename a `*.test.t*` file under `src/`, `watch` will re-run `yarn run test:setup` to regenerate the list of static test files in `test/index.html`.
+You can open that file in a browser to debug through the tests, or run `yarn test:run` to run them in headless Chrome.
+
+
+
+
+
diff --git a/examples/FullScreenSaver/lib/index.css b/examples/FullScreenSaver/lib/index.css
new file mode 100644
index 00000000..d11b3218
--- /dev/null
+++ b/examples/FullScreenSaver/lib/index.css
@@ -0,0 +1,88 @@
+/* General elements */
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background: black;
+ color: #fafafa;
+ overflow-x: hidden;
+ overflow-y: scroll;
+}
+
+header {
+ font-family: "Press Start";
+ padding: 0.5rem;
+ overflow: hidden;
+ -ms-user-select: none;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+section {
+ clear: both;
+}
+
+a {
+ color: white;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+h1 {
+ margin: 0;
+ padding-bottom: 3px;
+ text-align: center;
+}
+
+/* General animations */
+
+.hoverable {
+ opacity: 0.84;
+ transition: 140ms opacity;
+}
+
+.hoverable:hover {
+ opacity: 1;
+}
+
+/* Game section */
+
+section#game {
+ min-height: 210px;
+ margin-bottom: 35px;
+}
+
+/* Text sections */
+
+section.section-text {
+ margin: auto;
+ padding: 21px 70px;
+ max-width: 910px;
+ font-size: 1.4em;
+ text-align: center;
+}
+
+.link-github {
+ color: #cfc;
+}
+
+@media (max-width: 350px) {
+ section.section-text {
+ padding: 14px 7px;
+ }
+}
+
+@font-face {
+ font-family: "Press Start";
+ src: url("theme/fonts/pressstart2p-webfont.eot?#iefix") format("embedded-opentype"),
+ url("theme/fonts/pressstart2p-webfont.woff") format("woff"),
+ url("theme/fonts/pressstart2p-webfont.ttf") format("truetype"),
+ url("theme/fonts/pressstart2p-webfont.svg") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
diff --git a/examples/FullScreenSaver/lib/index.html b/examples/FullScreenSaver/lib/index.html
new file mode 100644
index 00000000..f67c2c0c
--- /dev/null
+++ b/examples/FullScreenSaver/lib/index.html
@@ -0,0 +1,123 @@
+
+
+
+
+ FullScreenSaver
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You may
+ download the game for yourself
+ from GitHub, the location of FullScreenSaver's open source project.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/FullScreenSaver/lib/theme/Icon.gif b/examples/FullScreenSaver/lib/theme/Icon.gif
new file mode 100644
index 00000000..28047a94
Binary files /dev/null and b/examples/FullScreenSaver/lib/theme/Icon.gif differ
diff --git a/examples/FullScreenSaver/lib/theme/fonts/README.md b/examples/FullScreenSaver/lib/theme/fonts/README.md
new file mode 100644
index 00000000..bebf666e
--- /dev/null
+++ b/examples/FullScreenSaver/lib/theme/fonts/README.md
@@ -0,0 +1,3 @@
+TODO PUT LICENSING INFORMATION HERE
+I SET THIS FOLDER UP WHILE OFFLINE BUT DEFINITELY SHOULD INCLUDE SOMETHING ONCE ONLINE :)
+CREDIT TO FONT MAKERS OF COURSE
diff --git a/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.eot b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.eot
new file mode 100644
index 00000000..98aa442b
Binary files /dev/null and b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.eot differ
diff --git a/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.svg b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.svg
new file mode 100644
index 00000000..b1fb3f5c
--- /dev/null
+++ b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.svg
@@ -0,0 +1,243 @@
+
+
+
\ No newline at end of file
diff --git a/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.ttf b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.ttf
new file mode 100644
index 00000000..a6f43ac9
Binary files /dev/null and b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.ttf differ
diff --git a/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.woff b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.woff
new file mode 100644
index 00000000..5b574105
Binary files /dev/null and b/examples/FullScreenSaver/lib/theme/fonts/pressstart2p-webfont.woff differ
diff --git a/examples/FullScreenSaver/package.json b/examples/FullScreenSaver/package.json
new file mode 100644
index 00000000..d439be19
--- /dev/null
+++ b/examples/FullScreenSaver/package.json
@@ -0,0 +1,101 @@
+{
+ "browser": "./lib/index.js",
+ "bugs": {
+ "url": "https://github.com/FullScreenShenanigans/FullScreenSaver/issues"
+ },
+ "dependencies": {
+ "eightbittr": "^0.8.2",
+ "menugraphr": "^0.8.1",
+ "userwrappr": "^0.8.2"
+ },
+ "description": "Example game with EightBittr tooling.",
+ "devDependencies": {
+ "@babel/core": "^7.18.10",
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
+ "@babel/plugin-proposal-decorators": "^7.18.10",
+ "@babel/preset-react": "^7.18.6",
+ "@babel/preset-typescript": "^7.18.6",
+ "@types/chai": "^4.3.3",
+ "@types/mocha": "^9.1.1",
+ "@types/sinon": "^10.0.13",
+ "@types/sinon-chai": "^3.2.8",
+ "babel-loader": "8.2.5",
+ "chai": "^4.3.6",
+ "husky": "^8.0.1",
+ "lint-staged": "^13.0.3",
+ "mocha": "^10.0.0",
+ "mocha-headless-chrome": "^4.0.0",
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6",
+ "requirejs": "^2.3.6",
+ "shenanigans-manager": "^0.8.1",
+ "sinon": "^14.0.0",
+ "sinon-chai": "^3.7.0",
+ "webpack": "^5.74.0",
+ "webpack-cli": "^4.10.0"
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged"
+ }
+ },
+ "license": "MIT",
+ "lint-staged": {
+ "**/*.{css,js,json,md,ts,tsx}": [
+ "prettier --ignore-path .prettierignore --write"
+ ]
+ },
+ "name": "fullscreensaver",
+ "package": {
+ "type": "git",
+ "url": "ssh://git@github.com:FullScreenShenanigans/FullScreenSaver.git"
+ },
+ "scripts": {
+ "clean": "rm -rf lib *.tsbuildinfo",
+ "compile": "tsc -b",
+ "dist": "webpack",
+ "format": "prettier --ignore-path .prettierignore --check \"./**/*.{css,js,json,md,ts,tsx}\"",
+ "format:write": "yarn format --write",
+ "hydrate": "yarn shenanigans-manager hydrate",
+ "link": "yarn link",
+ "lint": "eslint --ignore-path .eslintignore \"./src/**/*.{ts,tsx}\"",
+ "publish:ci": "yarn shenanigans-manager publish-if-updated",
+ "test": "yarn run test:setup && yarn run test:run",
+ "test:run": "yarn mocha-headless-chrome --file test/index.html",
+ "test:setup": "yarn shenanigans-manager generate-tests"
+ },
+ "shenanigans": {
+ "dist": true,
+ "example": true,
+ "game": true,
+ "loading": {
+ "externals": [
+ {
+ "js": {
+ "dev": "react/umd/react.development",
+ "prod": "react/lib/react.production"
+ },
+ "name": "react"
+ },
+ {
+ "js": {
+ "dev": "react-dom/umd/react-dom.development",
+ "prod": "react-dom/lib/react-dom.production"
+ },
+ "name": "react-dom"
+ },
+ {
+ "js": {
+ "dev": "userwrappr/dist/UserWrappr-Delayed"
+ },
+ "name": "UserWrappr-Delayed",
+ "shenanigansPackage": true
+ }
+ ]
+ },
+ "name": "FullScreenSaver",
+ "web": true
+ },
+ "types": "./lib/index.d.ts",
+ "version": "0.0.1"
+}
\ No newline at end of file
diff --git a/examples/FullScreenSaver/src/Direction.ts b/examples/FullScreenSaver/src/Direction.ts
new file mode 100644
index 00000000..def4129a
--- /dev/null
+++ b/examples/FullScreenSaver/src/Direction.ts
@@ -0,0 +1,6 @@
+export enum Direction {
+ Top = 0,
+ Right = 1,
+ Bottom = 2,
+ Left = 3,
+}
diff --git a/examples/FullScreenSaver/src/FullScreenSaver.test.ts b/examples/FullScreenSaver/src/FullScreenSaver.test.ts
new file mode 100644
index 00000000..2db61abb
--- /dev/null
+++ b/examples/FullScreenSaver/src/FullScreenSaver.test.ts
@@ -0,0 +1,5 @@
+describe("FullScreenSaver", () => {
+ it("_", () => {
+ // TODO: Implement me!
+ });
+});
diff --git a/examples/FullScreenSaver/src/FullScreenSaver.ts b/examples/FullScreenSaver/src/FullScreenSaver.ts
new file mode 100644
index 00000000..915a0e94
--- /dev/null
+++ b/examples/FullScreenSaver/src/FullScreenSaver.ts
@@ -0,0 +1,99 @@
+import { factory, member } from "autofieldr";
+import { EightBittr, EightBittrConstructorSettings } from "eightbittr";
+import { MenuGraphr } from "menugraphr";
+
+import { createMenuGrapher } from "./creators/createMenuGrapher";
+import { Collisions } from "./sections/Collisions";
+import { Graphics } from "./sections/Graphics";
+import { Groups } from "./sections/Groups";
+import { Inputs } from "./sections/Inputs";
+import { Maintenance } from "./sections/Maintenance";
+import { Objects } from "./sections/Objects";
+import { Players } from "./sections/Players";
+import { Quadrants } from "./sections/Quadrants";
+import { Scoring } from "./sections/Scoring";
+import { Squares } from "./sections/Squares";
+
+/**
+ * Example game with EightBittr tooling
+ */
+export class FullScreenSaver extends EightBittr {
+ /**
+ * Text-based menu and dialog management system.
+ */
+ @factory(createMenuGrapher)
+ public readonly menuGrapher: MenuGraphr;
+
+ /**
+ * Checkers and callbacks for Actor collisions.
+ */
+ @member(Collisions)
+ public readonly collisions: Collisions;
+
+ /**
+ * Stores the visual appearance of Actors.
+ */
+ @member(Graphics)
+ public readonly graphics: Graphics;
+
+ /**
+ * Collection settings for Actor group names.
+ */
+ @member(Groups)
+ public readonly groups: Groups;
+
+ /**
+ * User input filtering and handling.
+ */
+ @member(Inputs)
+ public readonly inputs: Inputs;
+
+ /**
+ * Update logic for Actors in game ticks.
+ */
+ @member(Maintenance)
+ public readonly maintenance: Maintenance;
+
+ /**
+ * Raw ObjectMakr factory settings.
+ */
+ @member(Objects)
+ public readonly objects: Objects;
+
+ /**
+ * Creates and updates player Actors.
+ */
+ @member(Players)
+ public readonly players: Players;
+
+ /**
+ * Arranges game physics quadrants.
+ */
+ @member(Quadrants)
+ public readonly quadrants: Quadrants;
+
+ /**
+ * Keeps track of points and high scores.
+ */
+ @member(Scoring)
+ public readonly scoring: Scoring;
+
+ /**
+ * Creates square Actors in the game.
+ */
+ @member(Squares)
+ public readonly squares: Squares;
+
+ /**
+ * Initializes a new instance of the FullScreenSaver class.
+ *
+ * @param settings Settings to be used for initialization.
+ */
+ public constructor(settings: EightBittrConstructorSettings) {
+ super(settings);
+
+ this.quadsKeeper.resetQuadrants();
+
+ this.squares.addSquare(this.mapScreener.width / 2, this.mapScreener.height / 2, 2, -2);
+ }
+}
diff --git a/examples/FullScreenSaver/src/creators/createMenuGrapher.ts b/examples/FullScreenSaver/src/creators/createMenuGrapher.ts
new file mode 100644
index 00000000..c1b5049a
--- /dev/null
+++ b/examples/FullScreenSaver/src/creators/createMenuGrapher.ts
@@ -0,0 +1,19 @@
+import { MenuGraphr } from "menugraphr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+export const createMenuGrapher = (game: FullScreenSaver): MenuGraphr =>
+ new MenuGraphr({
+ game,
+ schemas: {
+ Score: {
+ height: 48,
+ position: {
+ vertical: "bottom",
+ },
+ textPaddingX: 8,
+ textPaddingY: 24,
+ width: game.mapScreener.width / 2,
+ },
+ },
+ });
diff --git a/examples/FullScreenSaver/src/index.ts b/examples/FullScreenSaver/src/index.ts
new file mode 100644
index 00000000..fc9dfe25
--- /dev/null
+++ b/examples/FullScreenSaver/src/index.ts
@@ -0,0 +1,12 @@
+import { UserWrappr } from "userwrappr";
+export * from "./FullScreenSaver";
+
+import { createUserWrapprSettings } from "./interface/InterfaceSettings";
+
+/**
+ * Creates a UserWrappr interface around a new FullScreenSaver game.
+ *
+ * @param container HTML element to create within.
+ */
+export const createFullScreenSaverInterface = async (container: HTMLElement): Promise =>
+ new UserWrappr(createUserWrapprSettings()).createDisplay(container);
diff --git a/examples/FullScreenSaver/src/interface/InterfaceSettings.ts b/examples/FullScreenSaver/src/interface/InterfaceSettings.ts
new file mode 100644
index 00000000..1f51fcd6
--- /dev/null
+++ b/examples/FullScreenSaver/src/interface/InterfaceSettings.ts
@@ -0,0 +1,157 @@
+import { GameWindow } from "eightbittr";
+import { AbsoluteSizeSchema, UserWrapprSettings, OptionType } from "userwrappr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Global scope around a game, such as a DOM window.
+ */
+export interface WrappingGameWindow extends GameWindow {
+ /**
+ * Game instance, once this has created it.
+ */
+ FSS?: FullScreenSaver;
+}
+
+export interface InterfaceSettingOverrides {
+ createGame?(size: AbsoluteSizeSchema): FullScreenSaver;
+ gameWindow?: WrappingGameWindow;
+}
+
+/**
+ * Friendly name of the default game size.
+ */
+const defaultSize = "Full";
+
+/**
+ * Sizes the game is allowed to be, keyed by friendly name.
+ */
+const sizes = {
+ [defaultSize]: {
+ width: "100%",
+ height: "100%",
+ },
+};
+
+/**
+ * Creates settings for an UserWrappr that will create and wrap a FullScreenSaver instance.
+ *
+ * @param gameWindow Global scope around the game interface, if not the global window.
+ */
+export const createUserWrapprSettings = ({
+ createGame = (size: AbsoluteSizeSchema) => new FullScreenSaver(size),
+ gameWindow = window,
+}: InterfaceSettingOverrides = {}): UserWrapprSettings => {
+ /**
+ * Game instance, once this has created it.
+ */
+ let game: FullScreenSaver;
+
+ return {
+ defaultSize: sizes[defaultSize],
+ createContents: (size: AbsoluteSizeSchema) => {
+ gameWindow.FSS = game = createGame(size);
+ game.inputs.initializeGlobalPipes(gameWindow);
+ game.frameTicker.play();
+
+ return game.container;
+ },
+ menus: [
+ {
+ options: [
+ {
+ action: (): void => {
+ game.utilities.takeScreenshot(`FullScreenSaver ${Date.now()}`);
+ },
+ title: "Screenshot",
+ type: OptionType.Action,
+ },
+ {
+ getInitialValue: (): string => "1x",
+ options: [".25x", ".5x", "1x", "2x", "5x", "10x", "20x"],
+ saveValue: (value: string): void => {
+ const multiplier = parseFloat(value.replace("x", ""));
+ game.frameTicker.setInterval(1000 / 60 / multiplier);
+ game.pixelDrawer.setFramerateSkip(multiplier);
+ },
+ title: "Speed",
+ type: OptionType.Select,
+ },
+ ],
+ title: "Options",
+ },
+ ],
+ styles: {
+ input: {
+ fontFamily: "Press Start",
+ minWidth: "117px",
+ padding: "3px",
+ },
+ inputButton: {
+ background: "#ffcc33",
+ fontFamily: "Press Start",
+ padding: "7px 3px",
+ },
+ inputButtonAction: {
+ padding: "11px 3px",
+ width: "100%",
+ },
+ inputButtonBoolean: {
+ padding: "7px 21px",
+ },
+ inputButtonOff: {
+ background: "#ccaa33",
+ },
+ inputSelect: {
+ minWidth: "35px",
+ padding: "3px 0",
+ },
+ option: {
+ alignItems: "center",
+ margin: "auto",
+ padding: "7px 0",
+ maxWidth: "calc(100% - 14px)",
+ },
+ options: {
+ left: "4px",
+ right: "4px",
+ width: "auto",
+ padding: "4px 3px 21px",
+ boxShadow: ["0 3px 7px black inset", "0 0 0 4px #99ccff", "0 0 14px black"].join(
+ ", "
+ ),
+ background: "#005599",
+ },
+ optionsList: {
+ marginBottom: "7px",
+ },
+ menu: {
+ maxWidth: "385px",
+ minWidth: "280px",
+ padding: "7px",
+ },
+ menusInnerArea: {
+ background: "black",
+ color: "white",
+ fontFamily: "Press Start",
+ transition: "700ms color",
+ },
+ menuTitle: {
+ fontSize: "16px",
+ },
+ menuTitleButton: {
+ alignItems: "center",
+ background: "none",
+ border: "none",
+ color: "white",
+ display: "flex",
+ fontFamily: "Press Start",
+ fontSize: "16px",
+ justifyContent: "center",
+ },
+ menuTitleButtonFake: {
+ color: "grey",
+ },
+ },
+ };
+};
diff --git a/examples/FullScreenSaver/src/main.ts b/examples/FullScreenSaver/src/main.ts
new file mode 100644
index 00000000..2dcdb217
--- /dev/null
+++ b/examples/FullScreenSaver/src/main.ts
@@ -0,0 +1,8 @@
+import { createFullScreenSaverInterface } from "./index";
+
+const container = document.getElementById("game")!;
+
+createFullScreenSaverInterface(container).catch((error: Error): void => {
+ console.error("An error happened while trying to instantiate FullScreenSaver!");
+ console.error("requirejs error:", error);
+});
diff --git a/examples/FullScreenSaver/src/sections/Collisions.ts b/examples/FullScreenSaver/src/sections/Collisions.ts
new file mode 100644
index 00000000..ecebcce4
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Collisions.ts
@@ -0,0 +1,41 @@
+import { Actor, Collisions as CollisionsBase } from "eightbittr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Checkers and callbacks for Actor collisions.
+ */
+export class Collisions extends CollisionsBase {
+ /**
+ * Names of groups that should be checked for collisions.
+ */
+ public readonly collidingGroupNames: string[] = ["Players"];
+
+ /**
+ * Function generators for checking whether two Actors are colliding.
+ */
+ public readonly hitCheckGenerators = {
+ Players: {
+ Squares: () => (player: Actor, solid: Actor) =>
+ player.right >= solid.left &&
+ player.left <= solid.right &&
+ player.bottom >= solid.top &&
+ player.top <= solid.bottom,
+ },
+ };
+
+ /**
+ * Function generators for reacting to two Actors colliding.
+ */
+ public readonly hitCallbackGenerators = {
+ Players: {
+ Squares: () => (player: Actor) => {
+ this.game.death.kill(player);
+
+ for (const square of this.game.groupHolder.getGroup("Squares").slice(1)) {
+ this.game.death.kill(square);
+ }
+ },
+ },
+ };
+}
diff --git a/examples/FullScreenSaver/src/sections/Graphics.ts b/examples/FullScreenSaver/src/sections/Graphics.ts
new file mode 100644
index 00000000..9c9af313
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Graphics.ts
@@ -0,0 +1,55 @@
+import { Graphics as EightBittrGraphics } from "eightbittr";
+import { Palette } from "pixelrendr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+export class Graphics extends EightBittrGraphics {
+ public readonly background = "black";
+
+ public readonly library = {
+ CharA: "x011,1x06,101x05,101000010001000x15,001x05,101x05,10",
+ CharB: "x08,x15,0001000010010000100x16,001x05,101x05,10x16,00",
+ CharC: "x010,111100010000101x07,1x07,1x08,100001000111100",
+ CharD: "x08,x15,000100001001x05,101x05,101x05,1010000100x15,000",
+ CharE: "x08,x17,01x07,1x07,x16,001x07,1x07,x17,0",
+ CharF: "x08,x17,01x07,1x07,x16,001x07,1x07,1",
+ CharG: "x010,111100010000101x07,100111101x05,100100001000111100",
+ CharH: "x08,1x05,101x05,101x05,10x17,01x05,101x05,101x05,10",
+ CharI: "x09,x15,x05,1x07,1x07,1x07,1x07,1x05,x15,00",
+ CharJ: "x09,x16,x05,1x07,1x07,1000100010001000100001110000",
+ CharK: "x08,1000010010001000100100001011000011001000100001001x05,10",
+ CharL: "x08,1x07,1x07,1x07,1x07,1x07,1x07,x17,0",
+ CharM: "x08,1x05,101100011010101010100100101x05,101x05,101x05,10",
+ CharN: "x08,1x05,1011000010101000101001001010001010100001101x05,10",
+ CharO: "x010,111000010001001x05,101x05,101x05,100100010000111000",
+ CharP: "x08,x16,001x05,101x05,10x16,001x07,1x07,1",
+ CharQ: "x010,111000010001001x05,101x05,10100010100100010000111010",
+ CharR: "x08,x16,001x05,101x05,10x16,0010001000100001001x05,10",
+ CharS: "x09,1111000100001001x08,x15,x08,101x05,100x15,00",
+ CharT: "x08,x17,00001x07,1x07,1x07,1x07,1x07,10000",
+ CharU: "x08,1x05,101x05,101x05,101x05,101x05,100100001000x15,0",
+ CharV: "x08,1x05,101x05,10010001000100010000101x05,101x06,10000",
+ CharW: "x08,1x05,1010010010101010101010101011000110110001101x05,10",
+ CharX: "x08,110001100100010000101x06,1x06,1010000100010011000110",
+ CharY: "x08,1x05,100100010000101x06,1x07,1x07,1x07,10000",
+ CharZ: "x08,x17,x06,1x06,1x06,1x06,1x06,1x06,x17,0",
+ Char0: "x018,1110000100110011000110110001100110010000111000",
+ Char1: "x018,11x05,111x06,11x06,11x06,110000x16,00",
+ Char2: "x017,x15,001100011x05,111001111000111x05,x17,0",
+ Char3: "x017,x16,x05,110000111x08,110110001100x15,00",
+ Char4: "x019,11100001111000110110011001100x17,x05,1100",
+ Char5: "x016,x16,0011x06,x16,x07,110110001100x15,00",
+ Char6: "x017,x15,0011x06,x16,0011000110110001100x15,00",
+ Char7: "x016,x17,01100011x05,11x05,11x05,11x06,110000",
+ Char8: "x017,x15,00110001100x15,0011000110110001100x15,00",
+ Char9: "x017,x15,0011000110110001100x16,x06,1100x15,00",
+ Player: "x21024,",
+ Square: "x14096,",
+ };
+
+ public readonly paletteDefault: Palette = [
+ [0, 0, 0, 0],
+ [255, 255, 255, 255],
+ [35, 255, 70, 255],
+ ];
+}
diff --git a/examples/FullScreenSaver/src/sections/Groups.ts b/examples/FullScreenSaver/src/sections/Groups.ts
new file mode 100644
index 00000000..4e9fcf52
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Groups.ts
@@ -0,0 +1,7 @@
+import { Groups as EightBittrGroups } from "eightbittr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+export class Groups extends EightBittrGroups {
+ public readonly groupNames = ["Players", "Squares", "Text"];
+}
diff --git a/examples/FullScreenSaver/src/sections/Inputs.ts b/examples/FullScreenSaver/src/sections/Inputs.ts
new file mode 100644
index 00000000..74152145
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Inputs.ts
@@ -0,0 +1,56 @@
+import { GameWindow, Inputs as InputsBase } from "eightbittr";
+import { TriggerContainer } from "inputwritr";
+
+import { Direction } from "../Direction";
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * User input filtering and handling.
+ */
+export class Inputs extends InputsBase {
+ /**
+ * Known, allowed aliases for input event triggers.
+ */
+ public readonly aliases = {
+ bottom: [40],
+ left: [37],
+ right: [39],
+ top: [38],
+ };
+
+ /**
+ * Mapping of events to their key codes, to their callbacks.
+ */
+ public readonly triggers: TriggerContainer = {
+ onkeydown: {
+ bottom: (event) => {
+ event?.preventDefault();
+ this.game.players.requestPlayer(Direction.Bottom);
+ },
+ left: (event) => {
+ event?.preventDefault();
+ this.game.players.requestPlayer(Direction.Left);
+ },
+ right: (event) => {
+ event?.preventDefault();
+ this.game.players.requestPlayer(Direction.Right);
+ },
+ top: (event) => {
+ event?.preventDefault();
+ this.game.players.requestPlayer(Direction.Top);
+ },
+ },
+ };
+
+ /**
+ * Adds InputWritr pipes as global event listeners.
+ */
+ public initializeGlobalPipes(gameWindow: GameWindow) {
+ super.initializeGlobalPipes(gameWindow);
+
+ gameWindow.addEventListener(
+ "keydown",
+ this.game.inputWriter.makePipe("onkeydown", "keyCode")
+ );
+ }
+}
diff --git a/examples/FullScreenSaver/src/sections/Maintenance.ts b/examples/FullScreenSaver/src/sections/Maintenance.ts
new file mode 100644
index 00000000..e64f76a5
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Maintenance.ts
@@ -0,0 +1,42 @@
+import { Actor, ActorMaintainer, Maintenance as MaintenanceBase } from "eightbittr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Update logic for Actors in game ticks.
+ */
+export class Maintenance extends MaintenanceBase {
+ /**
+ * Maintains a general Actor for a tick.
+ */
+ public readonly maintain = (actor: Actor) => {
+ this.game.physics.shiftBoth(actor, actor.xVelocity, actor.yVelocity);
+
+ if (actor.top < 0) {
+ actor.yVelocity *= -1;
+ this.game.physics.setTop(actor, -actor.top);
+ }
+
+ if (actor.bottom > this.game.mapScreener.height) {
+ actor.yVelocity *= -1;
+ this.game.physics.shiftVertical(actor, this.game.mapScreener.height - actor.bottom);
+ }
+
+ if (actor.left < 0) {
+ actor.xVelocity *= -1;
+ this.game.physics.setLeft(actor, -actor.left);
+ }
+
+ if (actor.right > this.game.mapScreener.width) {
+ actor.xVelocity *= -1;
+ this.game.physics.shiftHorizontal(actor, this.game.mapScreener.width - actor.right);
+ }
+
+ return undefined;
+ };
+
+ public readonly maintainers: [string, ActorMaintainer][] = [
+ ["Squares", this.maintain],
+ ["Players", this.maintain],
+ ];
+}
diff --git a/examples/FullScreenSaver/src/sections/Objects.ts b/examples/FullScreenSaver/src/sections/Objects.ts
new file mode 100644
index 00000000..0aecb9b0
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Objects.ts
@@ -0,0 +1,82 @@
+import { Objects as ObjectsBase } from "eightbittr";
+import { ClassInheritance, ClassProperties } from "objectmakr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Raw ObjectMakr factory settings.
+ */
+export class Objects extends ObjectsBase {
+ public readonly inheritance: ClassInheritance = {
+ Actor: {
+ Player: {},
+ Square: {},
+ Text: {
+ Char0: {},
+ Char1: {},
+ Char2: {},
+ Char3: {},
+ Char4: {},
+ Char5: {},
+ Char6: {},
+ Char7: {},
+ Char8: {},
+ Char9: {},
+ CharA: {},
+ CharB: {},
+ CharC: {},
+ CharD: {},
+ CharE: {},
+ CharF: {},
+ CharG: {},
+ CharH: {},
+ CharI: {},
+ CharJ: {},
+ CharK: {},
+ CharL: {},
+ CharM: {},
+ CharN: {},
+ CharO: {},
+ CharP: {},
+ CharQ: {},
+ CharR: {},
+ CharS: {},
+ CharT: {},
+ CharU: {},
+ CharV: {},
+ CharW: {},
+ CharX: {},
+ CharY: {},
+ CharZ: {},
+ Menu: {},
+ },
+ },
+ };
+
+ public readonly onMake = "onMake";
+
+ public readonly properties: ClassProperties = {
+ Actor: {
+ onMake: this.game.actors.process.bind(this.game.actors),
+ },
+ Menu: {
+ hidden: true,
+ },
+ Player: {
+ height: 32,
+ groupType: "Players",
+ width: 32,
+ },
+ Square: {
+ height: 64,
+ groupType: "Squares",
+ width: 64,
+ },
+ Text: {
+ groupType: "Text",
+ height: 8,
+ scale: 2,
+ width: 8,
+ },
+ };
+}
diff --git a/examples/FullScreenSaver/src/sections/Players.ts b/examples/FullScreenSaver/src/sections/Players.ts
new file mode 100644
index 00000000..a2a4c5c4
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Players.ts
@@ -0,0 +1,69 @@
+import { Section } from "eightbittr";
+
+import { Direction } from "../Direction";
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Raw speed player velocities will be based off of.
+ */
+const speed = 5;
+
+/**
+ * Horizontal and vertical player speeds for each possible direction.
+ */
+const directionVelocities = {
+ [Direction.Top]: {
+ xVelocity: 0,
+ yVelocity: -speed,
+ },
+ [Direction.Right]: {
+ xVelocity: speed,
+ yVelocity: 0,
+ },
+ [Direction.Bottom]: {
+ xVelocity: 0,
+ yVelocity: speed,
+ },
+ [Direction.Left]: {
+ xVelocity: -speed,
+ yVelocity: 0,
+ },
+};
+
+/**
+ * Creates and updates player Actors.
+ */
+export class Players extends Section {
+ /**
+ * Creates a new Player, if there wasn't one already.
+ */
+ public requestPlayer(direction: Direction) {
+ const existingPlayer = this.game.groupHolder.getActor("player1");
+ const velocities = directionVelocities[direction];
+
+ if (existingPlayer) {
+ Object.assign(existingPlayer, velocities);
+ return;
+ }
+
+ const square = this.game.groupHolder.getGroup("Squares")[0];
+
+ const newPlayer = this.game.actors.add([
+ "Player",
+ {
+ id: "player1",
+ ...directionVelocities[direction],
+ },
+ ]);
+
+ this.game.physics.setMidObj(newPlayer, square);
+ this.game.physics.shiftBoth(
+ newPlayer,
+ (newPlayer.xVelocity * square.width + 1) / speed,
+ (newPlayer.yVelocity * square.width + 1) / speed
+ );
+
+ this.game.squares.startAddingSquares(newPlayer);
+ this.game.scoring.start(newPlayer);
+ }
+}
diff --git a/examples/FullScreenSaver/src/sections/Quadrants.ts b/examples/FullScreenSaver/src/sections/Quadrants.ts
new file mode 100644
index 00000000..9bea9d82
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Quadrants.ts
@@ -0,0 +1,13 @@
+import { Quadrants as QuadrantsBase } from "eightbittr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Arranges game physics quadrants.
+ */
+export class Quadrants extends QuadrantsBase {
+ /**
+ * Groups that should have their quadrants updated.
+ */
+ public readonly activeGroupNames: string[] = ["Players", "Squares"];
+}
diff --git a/examples/FullScreenSaver/src/sections/Scoring.ts b/examples/FullScreenSaver/src/sections/Scoring.ts
new file mode 100644
index 00000000..889e368a
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Scoring.ts
@@ -0,0 +1,49 @@
+import { Actor, Section } from "eightbittr";
+
+import { FullScreenSaver } from "FullScreenSaver";
+
+/**
+ * Keeps track of points and high scores.
+ */
+export class Scoring extends Section {
+ /**
+ * Starts regularly increasing score for a player's run.
+ */
+ public start(player: Actor) {
+ this.game.itemsHolder.setItem("score", 0);
+ this.refreshDisplay();
+
+ this.game.timeHandler.addEventInterval(
+ () => {
+ if (player.removed) {
+ const score = this.game.itemsHolder.getItem("score");
+ const highScore = this.game.itemsHolder.getItem("highScore");
+
+ if (!highScore || score > highScore) {
+ this.game.itemsHolder.setItem("highScore", score);
+ this.game.itemsHolder.saveItem("highScore");
+ }
+
+ this.refreshDisplay();
+ return true;
+ }
+
+ this.game.itemsHolder.increase("score", 1);
+ this.refreshDisplay();
+ return false;
+ },
+ 50,
+ Infinity
+ );
+ }
+
+ /**
+ * Creates a Score menu to handle score and high score.
+ */
+ public refreshDisplay() {
+ const score = this.game.itemsHolder.getItem("score");
+ const highScore = this.game.itemsHolder.getItem("highScore") || 0;
+ this.game.menuGrapher.createMenu("Score");
+ this.game.menuGrapher.addMenuDialog("Score", `SCORE ${score}\nHIGHSCORE ${highScore}`);
+ }
+}
diff --git a/examples/FullScreenSaver/src/sections/Squares.ts b/examples/FullScreenSaver/src/sections/Squares.ts
new file mode 100644
index 00000000..ed2266c6
--- /dev/null
+++ b/examples/FullScreenSaver/src/sections/Squares.ts
@@ -0,0 +1,55 @@
+import { Actor, Section } from "eightbittr";
+
+import { FullScreenSaver } from "../FullScreenSaver";
+
+/**
+ * Creates square Actors in the game.
+ */
+export class Squares extends Section {
+ /**
+ * Maximum number of squares to stop spawning after.
+ */
+ private readonly maximumSquares =
+ Math.sqrt((this.game.mapScreener.height * this.game.mapScreener.width) / 2000) | 0;
+
+ /**
+ * Creates a new square in the game.
+ */
+ public addSquare(midX: number, midY: number, xVelocity: number, yVelocity: number) {
+ const square = this.game.actors.add(["Square", { xVelocity, yVelocity }]);
+
+ this.game.physics.setMid(square, midX, midY);
+ }
+
+ /**
+ * Starts spawning new squares while it still can.
+ */
+ public readonly startAddingSquares = (player: Actor) => {
+ this.game.timeHandler.addEventInterval(
+ () => {
+ if (player.removed) {
+ return true;
+ }
+
+ const solids = [...this.game.groupHolder.getGroup("Squares")];
+
+ for (const square of solids) {
+ if (solids.length >= this.maximumSquares) {
+ return true;
+ }
+
+ this.addSquare(
+ this.game.physics.getMidX(square),
+ this.game.physics.getMidY(square),
+ -square.xVelocity * 0.75,
+ -square.yVelocity * 0.75
+ );
+ }
+
+ return false;
+ },
+ 150,
+ Infinity
+ );
+ };
+}
diff --git a/examples/FullScreenSaver/tsconfig.json b/examples/FullScreenSaver/tsconfig.json
new file mode 100644
index 00000000..1e816178
--- /dev/null
+++ b/examples/FullScreenSaver/tsconfig.json
@@ -0,0 +1,29 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./src",
+ "declaration": true,
+ "declarationMap": true,
+ "experimentalDecorators": true,
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "react",
+ "module": "amd",
+ "moduleResolution": "node",
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitAny": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "outDir": "./lib",
+ "pretty": true,
+ "rootDir": "./src",
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "strictFunctionTypes": false,
+ "strictPropertyInitialization": false,
+ "target": "ES2021"
+ },
+ "exclude": ["**/*.d.ts", "**/lib"],
+ "include": ["./src/**/*.ts", "./src/**/*.tsx"]
+}
diff --git a/lerna.json b/lerna.json
index 7136d942..fa54ba7f 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,6 @@
{
"npmClient": "yarn",
- "packages": ["packages/*"],
+ "packages": ["examples/*", "packages/*"],
"useWorkspaces": true,
"version": "0.8.2"
}
diff --git a/package.json b/package.json
index f82eb43c..b2890b4a 100644
--- a/package.json
+++ b/package.json
@@ -47,14 +47,15 @@
"scripts": {
"clean": "lerna run clean",
"compile": "tsc -b",
+ "dist": "lerna run dist",
"format": "prettier --ignore-path .prettierignore .",
"format:write": "yarn format --write",
- "hydrate": "yarn lerna exec --scope shenanigans-manager tsc && lerna run hydrate && yarn run compile",
- "link": "lerna run link && yarn lerna exec yarn link shenanigans-manager",
+ "hydrate": "lerna exec --scope shenanigans-manager tsc && lerna run hydrate && yarn run compile",
+ "link": "lerna run link && lerna exec yarn link shenanigans-manager",
"lint": "eslint --ignore-path .eslintignore \"./packages/**/*.{js,ts,tsx}\"",
"lint:md": "yarn markdownlint \"**/*.md\" \".github/**/*.md\"",
"lint:spelling": "yarn cspell \"**\" \".github/**/*\"",
- "ncu:all": "yarn lerna exec \"ncu -u\" && yarn lerna run ncu:all",
+ "ncu:all": "lerna exec \"ncu -u\" && lerna run ncu:all",
"prepare": "husky install",
"publish:ci": "lerna run publish:ci",
"test": "lerna run test"
@@ -63,6 +64,7 @@
"repository": "https://github.com/FullScreenShenanigans/EightBittr",
"version": "0.8.2",
"workspaces": [
+ "examples/*",
"packages/*"
]
}
diff --git a/packages/eightbittr/README.md b/packages/eightbittr/README.md
index 4e54fe88..a660b6c2 100644
--- a/packages/eightbittr/README.md
+++ b/packages/eightbittr/README.md
@@ -34,7 +34,7 @@ See:
- **[docs/Consumption](./docs/Consumption.md)** for how to set up a game using EightBittr.
- **[docs/Testing](./docs/Testing.md)** for how to test a game set up with EightBittr.
- **[docs/Runtime](./docs/Runtime.md)** for a detailed play-by-play of what happens each game frame.
-- **[docs/Walkthrough](./docs/walkthrough/README.md)** for step-by-step instructions on how to set up a game with EightBittr.
+- **[../../docs/Walkthrough](../../docs/walkthrough/README.md)** for step-by-step instructions on how to set up a game with EightBittr.
- **[docs/FAQs](./docs/FAQs.md)**
diff --git a/packages/eightbittr/src/sections/Maintenance.ts b/packages/eightbittr/src/sections/Maintenance.ts
index 39fbedfd..e5bcaae6 100644
--- a/packages/eightbittr/src/sections/Maintenance.ts
+++ b/packages/eightbittr/src/sections/Maintenance.ts
@@ -3,8 +3,9 @@ import { Actor } from "../types";
import { Section } from "./Section";
/**
- * TODO EXPLAIN
+ * Maintains and prunes an Actor for a game tick.
*
+ * @param actor The actor to be maintained.
* @returns Whether to remove the Actor from its group.
*/
export type ActorMaintainer = (actor: Actor) => boolean | undefined;
diff --git a/packages/eightbittr/src/sections/Physics.test.ts b/packages/eightbittr/src/sections/Physics.test.ts
index 9a084577..526acf4a 100644
--- a/packages/eightbittr/src/sections/Physics.test.ts
+++ b/packages/eightbittr/src/sections/Physics.test.ts
@@ -397,7 +397,7 @@ describe("Physics", () => {
const amount = 7;
// Act
- physics.shiftHoriz(actor, amount);
+ physics.shiftHorizontal(actor, amount);
// Assert
expect(actor.left).to.be.equal(left + amount);
@@ -412,7 +412,7 @@ describe("Physics", () => {
const bottom = actor.bottom;
// Act
- physics.shiftHoriz(actor, 7);
+ physics.shiftHorizontal(actor, 7);
// Assert
expect(actor.top).to.be.equal(top);
@@ -430,7 +430,7 @@ describe("Physics", () => {
const amount = 7;
// Act
- physics.shiftVert(actor, amount);
+ physics.shiftVertical(actor, amount);
// Assert
expect(actor.top).to.be.equal(top + amount);
@@ -445,7 +445,7 @@ describe("Physics", () => {
const right = actor.right;
// Act
- physics.shiftVert(actor, 7);
+ physics.shiftVertical(actor, 7);
// Assert
expect(actor.left).to.be.equal(left);
diff --git a/packages/eightbittr/src/sections/Physics.ts b/packages/eightbittr/src/sections/Physics.ts
index 357fa716..b47ffd27 100644
--- a/packages/eightbittr/src/sections/Physics.ts
+++ b/packages/eightbittr/src/sections/Physics.ts
@@ -222,8 +222,8 @@ export class Physics extends Section {
return;
}
- this.shiftHoriz(actor, dx);
- this.shiftVert(actor, dy);
+ this.shiftHorizontal(actor, dx);
+ this.shiftVertical(actor, dy);
}
/**
@@ -231,7 +231,7 @@ export class Physics extends Section {
*
* @param dx How far to shift the Actor horizontally.
*/
- public shiftHoriz(actor: Actor, dx: number): void {
+ public shiftHorizontal(actor: Actor, dx: number): void {
actor.left += dx;
actor.right += dx;
@@ -255,7 +255,7 @@ export class Physics extends Section {
*
* @param dy How far to shift the Actor vertically.
*/
- public shiftVert(actor: Actor, dy: number): void {
+ public shiftVertical(actor: Actor, dy: number): void {
actor.top += dy;
actor.bottom += dy;
@@ -289,13 +289,13 @@ export class Physics extends Section {
/**
* Shifts An Actor horizontally by its xVelocity and vertically by its yVelocity, using
- * shiftHoriz and shiftVert.
+ * shiftHorizontal and shiftVertical.
*
* @param actor
*/
public updatePosition(actor: Actor): void {
- this.shiftHoriz(actor, actor.xVelocity);
- this.shiftVert(actor, actor.yVelocity);
+ this.shiftHorizontal(actor, actor.xVelocity);
+ this.shiftVertical(actor, actor.yVelocity);
}
/**
@@ -339,9 +339,9 @@ export class Physics extends Section {
const midx = this.getMidX(actor);
if (midx < dx) {
- this.shiftHoriz(actor, Math.min(maxDistance, dx - midx));
+ this.shiftHorizontal(actor, Math.min(maxDistance, dx - midx));
} else {
- this.shiftHoriz(actor, Math.max(-maxDistance, dx - midx));
+ this.shiftHorizontal(actor, Math.max(-maxDistance, dx - midx));
}
}
@@ -358,9 +358,9 @@ export class Physics extends Section {
const midy = this.getMidY(actor);
if (midy < dy) {
- this.shiftVert(actor, Math.min(maxDistance, dy - midy));
+ this.shiftVertical(actor, Math.min(maxDistance, dy - midy));
} else {
- this.shiftVert(actor, Math.max(-maxDistance, dy - midy));
+ this.shiftVertical(actor, Math.max(-maxDistance, dy - midy));
}
}
@@ -385,7 +385,7 @@ export class Physics extends Section {
}
/**
- * Shifts An Actor's top up, then sets the bottom (similar to a shiftVert and
+ * Shifts An Actor's top up, then sets the bottom (similar to a shiftVertical and
* a setTop combined).
*
* @param actor The Actor to be shifted vertically.
@@ -399,7 +399,7 @@ export class Physics extends Section {
}
/**
- * Shifts An Actor's right, then sets the left (similar to a shiftHoriz and a
+ * Shifts An Actor's right, then sets the left (similar to a shiftHorizontal and a
* setRight combined).
*
* @param actor The Actor to be shifted horizontally.
@@ -414,7 +414,7 @@ export class Physics extends Section {
/**
* Shifts An Actor's bottom down, then sets the bottom (similar to a
- * shiftVert and a setBottom combined).
+ * shiftVertical and a setBottom combined).
*
* @param actor The Actor to be shifted vertically.
* @param dy How far to shift the Actor vertically (by default, 0).
@@ -427,7 +427,7 @@ export class Physics extends Section {
}
/**
- * Shifts An Actor's left, then sets the right (similar to a shiftHoriz and a
+ * Shifts An Actor's left, then sets the right (similar to a shiftHorizontal and a
* setLeft combined).
*
* @param actor The Actor to be shifted horizontally.
diff --git a/packages/menugraphr/src/MenuGraphr.ts b/packages/menugraphr/src/MenuGraphr.ts
index 40b72450..4246e56c 100644
--- a/packages/menugraphr/src/MenuGraphr.ts
+++ b/packages/menugraphr/src/MenuGraphr.ts
@@ -510,7 +510,7 @@ export class MenuGraphr {
optionChild.actors.push(character);
if (!schema.position) {
- this.game.physics.shiftVert(character, y - menu.top);
+ this.game.physics.shiftVertical(character, y - menu.top);
}
}
}
@@ -1175,11 +1175,11 @@ export class MenuGraphr {
}
if (offset.top) {
- this.game.physics.shiftVert(actor, offset.top);
+ this.game.physics.shiftVertical(actor, offset.top);
}
if (offset.left) {
- this.game.physics.shiftHoriz(actor, offset.left);
+ this.game.physics.shiftHorizontal(actor, offset.left);
}
if (!skipAdd) {
@@ -1234,7 +1234,7 @@ export class MenuGraphr {
* @returns Whether the character was deleted.
*/
private scrollCharacterUp(character: Actor, menu: Menu, speed: number): boolean {
- this.game.physics.shiftVert(character, -speed);
+ this.game.physics.shiftVertical(character, -speed);
if (character.top < menu.top + ((menu.textYOffset || 0) - speed)) {
this.game.death.kill(character);
@@ -1416,7 +1416,7 @@ export class MenuGraphr {
option.y += offset;
for (j = 0; j < optionChild.actors.length; j += 1) {
- this.game.physics.shiftVert(optionChild.actors[j], offset);
+ this.game.physics.shiftVertical(optionChild.actors[j], offset);
optionChild.actors[j].hidden = !!(
i < menu.scrollingVisualOffset ||
i >= (menu.scrollingItems || 1) + menu.scrollingVisualOffset
diff --git a/packages/shenanigans-manager/setup/external/tsconfig.json b/packages/shenanigans-manager/setup/external/tsconfig.json
index fd5d25d0..1e816178 100644
--- a/packages/shenanigans-manager/setup/external/tsconfig.json
+++ b/packages/shenanigans-manager/setup/external/tsconfig.json
@@ -6,7 +6,6 @@
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react",
- "lib": ["dom", "es2015"],
"module": "amd",
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
diff --git a/packages/shenanigans-manager/setup/package-game.json b/packages/shenanigans-manager/setup/package-game.json
index b1f796d5..8673ac61 100644
--- a/packages/shenanigans-manager/setup/package-game.json
+++ b/packages/shenanigans-manager/setup/package-game.json
@@ -1,30 +1,31 @@
{
"dependencies": {
- "eightbittr": "^0.9.0",
- "userwrappr": "^0.9.0"
+ "eightbittr": "^0.8.2",
+ "userwrappr": "^0.8.2"
},
"shenanigans": {
"loading": {
"externals": [
{
"js": {
- "dev": "../node_modules/react/umd/react.development",
- "prod": "../node_modules/react/lib/react.production"
+ "dev": "react/umd/react.development",
+ "prod": "react/lib/react.production"
},
"name": "react"
},
{
"js": {
- "dev": "../node_modules/react-dom/umd/react-dom.development",
- "prod": "../node_modules/react-dom/lib/react-dom.production"
+ "dev": "react-dom/umd/react-dom.development",
+ "prod": "react-dom/lib/react-dom.production"
},
"name": "react-dom"
},
{
"js": {
- "dev": "../node_modules/userwrappr/dist/UserWrappr-Delayed"
+ "dev": "userwrappr/dist/UserWrappr-Delayed"
},
- "name": "UserWrappr-Delayed"
+ "name": "UserWrappr-Delayed",
+ "shenanigansPackage": true
}
]
}
diff --git a/packages/shenanigans-manager/setup/web/lib/index.html b/packages/shenanigans-manager/setup/web/lib/index.html
index 97b0b9bb..7b5d1779 100644
--- a/packages/shenanigans-manager/setup/web/lib/index.html
+++ b/packages/shenanigans-manager/setup/web/lib/index.html
@@ -38,7 +38,7 @@
{{shenanigans.web.sections.legal}}
-
+