From dc8c091c47046771ea197cf85dc304c657cbd980 Mon Sep 17 00:00:00 2001 From: ad044 Date: Mon, 8 Mar 2021 19:51:03 +0400 Subject: [PATCH] added notes page, implemented bg music, fixed a couple of issues --- package-lock.json | 272 ++++++++++++++++++ package.json | 2 + public/index.html | 2 +- src/App.tsx | 114 +------- src/components/LainSpeak.tsx | 2 +- src/components/MainScene/Lain.tsx | 6 +- src/components/MainScene/Popups/About.tsx | 18 +- .../AudioVisualizer/AudioVisualizer.tsx | 2 +- src/dom-components/Game.tsx | 115 ++++++++ src/dom-components/Notes.tsx | 157 ++++++++++ src/scenes/MainScene.tsx | 29 +- src/store.ts | 1 - 12 files changed, 607 insertions(+), 113 deletions(-) create mode 100644 src/dom-components/Game.tsx create mode 100644 src/dom-components/Notes.tsx diff --git a/package-lock.json b/package-lock.json index e544121..d6985c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,11 @@ "@types/node": "^12.12.54", "@types/react": "^16.9.47", "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.7", "@types/three": "^0.126.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0", "react-scripts": "^4.0.0", "react-three-fiber": "^4.2.20", "react-use-gesture": "^9.0.4", @@ -2772,6 +2774,11 @@ "@types/node": "*" } }, + "node_modules/@types/history": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", + "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==" + }, "node_modules/@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -2868,6 +2875,25 @@ "@types/react": "^16" } }, + "node_modules/@types/react-router": { + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.12.tgz", + "integrity": "sha512-0bhXQwHYfMeJlCh7mGhc0VJTRm0Gk+Z8T00aiP4702mDUuLs9SMhnd2DitpjWFjdOecx2UXtICK14H9iMnziGA==", + "dependencies": { + "@types/history": "*", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz", + "integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==", + "dependencies": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, "node_modules/@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -9214,6 +9240,19 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -9224,6 +9263,19 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -12193,6 +12245,19 @@ "node": ">=4" } }, + "node_modules/mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + }, + "peerDependencies": { + "prop-types": "^15.0.0", + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -15310,6 +15375,61 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/react-router/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/react-router/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-scripts": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", @@ -16116,6 +16236,11 @@ "node": ">=4" } }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -18462,6 +18587,16 @@ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" }, + "node_modules/tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -19084,6 +19219,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -23283,6 +23423,11 @@ "@types/node": "*" } }, + "@types/history": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", + "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==" + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -23379,6 +23524,25 @@ "@types/react": "^16" } }, + "@types/react-router": { + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.12.tgz", + "integrity": "sha512-0bhXQwHYfMeJlCh7mGhc0VJTRm0Gk+Z8T00aiP4702mDUuLs9SMhnd2DitpjWFjdOecx2UXtICK14H9iMnziGA==", + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react-router-dom": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz", + "integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==", + "requires": { + "@types/history": "*", + "@types/react": "*", + "@types/react-router": "*" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", @@ -28415,6 +28579,19 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -28425,6 +28602,21 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -30738,6 +30930,15 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -33247,6 +33448,57 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "react-scripts": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", @@ -33838,6 +34090,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -35732,6 +35989,16 @@ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -36219,6 +36486,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index 4cd1ffe..81a7f57 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,11 @@ "@types/node": "^12.12.54", "@types/react": "^16.9.47", "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.7", "@types/three": "^0.126.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0", "react-scripts": "^4.0.0", "react-three-fiber": "^4.2.20", "react-use-gesture": "^9.0.4", diff --git a/public/index.html b/public/index.html index e38b61b..77cdd50 100644 --- a/public/index.html +++ b/public/index.html @@ -3,7 +3,7 @@ - + diff --git a/src/App.tsx b/src/App.tsx index 26a99fb..cc86e2d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,115 +1,21 @@ -import React, { - Suspense, - useCallback, - useEffect, - useMemo, - useState, -} from "react"; -import MainScene from "./scenes/MainScene"; +import React, { useEffect } from "react"; import "./static/css/page.css"; -import { Canvas } from "react-three-fiber"; -import MediaPlayer from "./components/MediaPlayer"; -import MediaScene from "./scenes/MediaScene"; -import { useStore } from "./store"; -import GateScene from "./scenes/GateScene"; -import BootScene from "./scenes/BootScene"; -import SsknScene from "./scenes/SsknScene"; -import PolytanScene from "./scenes/PolytanScene"; -import TaKScene from "./scenes/TaKScene"; -import ChangeDiscScene from "./scenes/ChangeDiscScene"; -import EndScene from "./scenes/EndScene"; -import IdleMediaScene from "./scenes/IdleMediaScene"; -import InputHandler from "./components/InputHandler"; -import mobileAndTabletCheck from "./utils/mobileAndTabletCheck"; -import Preloader from "./components/Preloader"; +import Game from "./dom-components/Game"; +import { BrowserRouter, Route, Switch } from "react-router-dom"; +import Notes from "./dom-components/Notes"; const App = () => { - const currentScene = useStore((state) => state.currentScene); - useEffect(() => { document.title = "< index >"; }, []); - const dispatchScene = useMemo( - () => ({ - main: , - media: , - idle_media: , - gate: , - boot: , - sskn: , - polytan: , - tak: , - change_disc: , - end: , - null: <>, - }), - [] - ); - - const [width, setWidth] = useState((window.screen.height / 1.8) * 1.3); - const [height, setHeight] = useState(window.screen.height / 1.8); - - const [isMobile, setIsMobile] = useState(false); - - const handleGameResize = useCallback((event) => { - switch (event.key) { - case "k": - setWidth((prevWidth) => prevWidth * 1.1); - setHeight((prevHeight) => prevHeight * 1.1); - break; - case "j": - setWidth((prevWidth) => prevWidth / 1.1); - setHeight((prevHeight) => prevHeight / 1.1); - } - }, []); - - const handleScreenResize = useCallback(() => { - const isMobile = mobileAndTabletCheck(); - if (!isMobile) { - const h = window.screen.height / 1.8; - setWidth(h * 1.3); - setHeight(h); - setIsMobile(false); - } else { - const h = window.screen.height / 1.05; - setHeight(h); - setWidth(h * 1.3); - setIsMobile(true); - } - }, []); - - useEffect(() => { - if (!isMobile) window.addEventListener("keydown", handleGameResize); - - window.addEventListener("resize", handleScreenResize); - - return () => { - window.removeEventListener("keydown", handleGameResize); - window.removeEventListener("resize", handleScreenResize); - }; - }, [handleGameResize, handleScreenResize, isMobile]); - return ( -
- - - - {dispatchScene[currentScene as keyof typeof dispatchScene]} - - - - {["media", "idle_media", "tak", "end"].includes(currentScene) && ( -
- -
- )} -
+ + + + + + ); }; diff --git a/src/components/LainSpeak.tsx b/src/components/LainSpeak.tsx index 89c40c5..f9fb687 100644 --- a/src/components/LainSpeak.tsx +++ b/src/components/LainSpeak.tsx @@ -44,7 +44,7 @@ const LainSpeak = (props: LainTaKProps) => { useFrame(() => { if (audioAnalyser) { - const freq = parseInt(String(audioAnalyser.getAverageFrequency())); + const freq = audioAnalyser.getAverageFrequency() * 1.2; if (mouthRef.current) { if (freq >= 50) { diff --git a/src/components/MainScene/Lain.tsx b/src/components/MainScene/Lain.tsx index e6557f8..c21f7ec 100644 --- a/src/components/MainScene/Lain.tsx +++ b/src/components/MainScene/Lain.tsx @@ -44,11 +44,11 @@ type LainConstructorProps = { }; export const LainConstructor = (props: LainConstructorProps) => { - const lainSpriteTexture: any = useLoader(THREE.TextureLoader, props.sprite); + const lainSprite: any = useLoader(THREE.TextureLoader, props.sprite); const [animator] = useState(() => { const anim = new PlainSingularAnimator( - lainSpriteTexture, + lainSprite, props.framesHorizontal, props.framesVertical, props.frameCount, @@ -67,7 +67,7 @@ export const LainConstructor = (props: LainConstructorProps) => { return ( diff --git a/src/components/MainScene/Popups/About.tsx b/src/components/MainScene/Popups/About.tsx index 55b359b..479ce15 100644 --- a/src/components/MainScene/Popups/About.tsx +++ b/src/components/MainScene/Popups/About.tsx @@ -1,8 +1,9 @@ -import React, { useRef } from "react"; +import React, { useEffect, useRef } from "react"; import aboutBg from "../../../static/sprites/main/about_background.png"; import { useFrame, useLoader } from "react-three-fiber"; import * as THREE from "three"; import { useStore } from "../../../store"; +import { aboutSceneMusic } from "../../../static/sfx"; const About = () => { const showingAbout = useStore((state) => state.showingAbout); @@ -20,6 +21,21 @@ const About = () => { } }); + useEffect(() => { + const play = () => { + aboutSceneMusic.currentTime = 1; + aboutSceneMusic.volume = 0.5; + aboutSceneMusic.loop = true; + aboutSceneMusic.play(); + }; + + if (showingAbout) play(); + + return () => { + aboutSceneMusic.pause(); + }; + }, [showingAbout]); + return ( <> {showingAbout && ( diff --git a/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx b/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx index 00f8cd5..9f8a76d 100644 --- a/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx +++ b/src/components/MediaScene/AudioVisualizer/AudioVisualizer.tsx @@ -29,7 +29,7 @@ const AudioVisualizer = memo(() => { // we up it by 1.2 just so it becomes a bit more noticable, otherwise // the visualizer is a bit too "calm" - const currentFrequency = frequencyData[32 * idx] * 1.2; + const currentFrequency = frequencyData[16 * idx] * 1.2; switch (true) { case currentFrequency >= 255: diff --git a/src/dom-components/Game.tsx b/src/dom-components/Game.tsx new file mode 100644 index 0000000..889b482 --- /dev/null +++ b/src/dom-components/Game.tsx @@ -0,0 +1,115 @@ +import { useStore } from "../store"; +import React, { + Suspense, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; +import MainScene from "../scenes/MainScene"; +import MediaScene from "../scenes/MediaScene"; +import IdleMediaScene from "../scenes/IdleMediaScene"; +import GateScene from "../scenes/GateScene"; +import BootScene from "../scenes/BootScene"; +import SsknScene from "../scenes/SsknScene"; +import PolytanScene from "../scenes/PolytanScene"; +import TaKScene from "../scenes/TaKScene"; +import ChangeDiscScene from "../scenes/ChangeDiscScene"; +import EndScene from "../scenes/EndScene"; +import mobileAndTabletCheck from "../utils/mobileAndTabletCheck"; +import { Canvas } from "react-three-fiber"; +import Preloader from "../components/Preloader"; +import InputHandler from "../components/InputHandler"; +import MediaPlayer from "../components/MediaPlayer"; + +const Game = () => { + const currentScene = useStore((state) => state.currentScene); + + useEffect(() => { + document.title = "< index >"; + }, []); + + const dispatchScene = useMemo( + () => ({ + main: , + media: , + idle_media: , + gate: , + boot: , + sskn: , + polytan: , + tak: , + change_disc: , + end: , + null: <>, + }), + [] + ); + + const [width, setWidth] = useState((window.screen.height / 1.8) * 1.3); + const [height, setHeight] = useState(window.screen.height / 1.8); + + const [isMobile, setIsMobile] = useState(false); + + const handleGameResize = useCallback((event) => { + switch (event.key) { + case "k": + setWidth((prevWidth) => prevWidth * 1.1); + setHeight((prevHeight) => prevHeight * 1.1); + break; + case "j": + setWidth((prevWidth) => prevWidth / 1.1); + setHeight((prevHeight) => prevHeight / 1.1); + } + }, []); + + const handleScreenResize = useCallback(() => { + const isMobile = mobileAndTabletCheck(); + if (!isMobile) { + const h = window.screen.height / 1.8; + setWidth(h * 1.3); + setHeight(h); + setIsMobile(false); + } else { + const h = window.screen.height / 1.05; + setHeight(h); + setWidth(h * 1.3); + setIsMobile(true); + } + }, []); + + useEffect(() => { + if (!isMobile) window.addEventListener("keydown", handleGameResize); + + window.addEventListener("resize", handleScreenResize); + + return () => { + window.removeEventListener("keydown", handleGameResize); + window.removeEventListener("resize", handleScreenResize); + }; + }, [handleGameResize, handleScreenResize, isMobile]); + + return ( +
+ + + + {dispatchScene[currentScene as keyof typeof dispatchScene]} + + + + {["media", "idle_media", "tak", "end"].includes(currentScene) && ( +
+ +
+ )} +
+ ); +}; + +export default Game; diff --git a/src/dom-components/Notes.tsx b/src/dom-components/Notes.tsx new file mode 100644 index 0000000..e770416 --- /dev/null +++ b/src/dom-components/Notes.tsx @@ -0,0 +1,157 @@ +import React from "react"; +import "../static/css/notes.css"; + +const Notes = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + +
+

Performance

+
+

+ The game performs best on chromium-based browsers. Chromium, + Chrome, Edge, Brave, Opera, Iridium, Vivaldi, etc. It's highly + recommended that you use one of those for an optimal experience. + This is especially true if you're using a bad setup, and even + more true if you're using Linux on a bad setup, since Firefox's + WebGL implementation on it has had issues for a while now. +

+
+

Keyboard Controls

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArrowDown
ArrowLeft
ArrowUp
ArrowRight
x
z
d
eL2
vSTART
kUpscale Game Window
jDownscale Game Window
+
+

Mobile/Tablet Controls

+
+ + + + + + + + + + + + + + + + + + + +
Swipe Down
Swipe Left
Swipe Up
Swipe Right
+

+ The rest of the buttons are layed out on the game screen itself. +
+ Also, please rotate the phone horizontally when playing, I don't + want feature creep because of psychopaths. +

+
+

Saving Progress

+
+

+ There is no auto-save feature just like the original game, so + progress must be saved manually. This can be done by navigating + to "Save" inside the pause menu in-game, which can be accessed + by pressing ▲ (d key on keyboard). +
+ The state is stored in a minimized JSON format as a string + inside localStorage with the key "lainSaveState". +

+
+

Sound

+
+

+ The game assumes that your browser volume is set to 100% (via + the sound mixer on your operating system). It uses the Web Audio + API to display the audio visualizer and animate Lain's mouth + movements inside some media files. Both of those things depend + on the browser's output volume, therefore, if you want to lower + the game's volume, it is recommended you do so by lowering the + system volume itself, as opposed to muting the browser + tab/lowering the browser volume directly. Otherwise, the two + functionalities mentioned above won't work properly. +
+ If this becomes a huge problem later on, I'll try to implement + an alternative for it. +

+
+ start +
+ + ); +}; + +export default Notes; diff --git a/src/scenes/MainScene.tsx b/src/scenes/MainScene.tsx index afdfd5f..aa29d4a 100644 --- a/src/scenes/MainScene.tsx +++ b/src/scenes/MainScene.tsx @@ -18,6 +18,7 @@ import usePrevious from "../hooks/usePrevious"; import MainSceneBackground from "../components/MainScene/Site/MainSceneBackground"; import { a, useSpring } from "@react-spring/three"; import Pause from "../components/MainScene/Pause/Pause"; +import { mainSceneMusic } from "../static/sfx"; const MainScene = () => { const intro = useStore((state) => state.intro); @@ -26,6 +27,7 @@ const MainScene = () => { const prevData = usePrevious({ subscene }); const wordSelected = useStore((state) => state.wordSelected); + const showingAbout = useStore((state) => state.showingAbout); const setWordSelected = useStore((state) => state.setWordSelected); const setInputCooldown = useStore((state) => state.setInputCooldown); const wordNotFound = useStore((state) => state.wordNotFound); @@ -115,13 +117,38 @@ const MainScene = () => { } }); + useEffect(() => { + const play = () => { + mainSceneMusic.currentTime = 0; + mainSceneMusic.volume = 0.5; + mainSceneMusic.loop = true; + mainSceneMusic.play(); + }; + + if (intro) { + if (introFinished) play(); + } else { + play(); + } + + if (showingAbout) { + mainSceneMusic.pause(); + } + + return () => { + mainSceneMusic.pause(); + }; + }, [intro, introFinished, showingAbout]); return ( }> - + diff --git a/src/store.ts b/src/store.ts index 7720675..03c1796 100644 --- a/src/store.ts +++ b/src/store.ts @@ -423,7 +423,6 @@ export const saveUserProgress = (state: UserSaveState) => localStorage.setItem("lainSaveState", JSON.stringify(state)); export const playAudio = (audio: HTMLAudioElement) => { - audio.currentTime = 0; audio.currentTime = 0; audio.volume = 0.5; audio.loop = false;