added notes page, implemented bg music, fixed a couple of issues

This commit is contained in:
ad044 2021-03-08 19:51:03 +04:00
parent ec0e81378b
commit dc8c091c47
12 changed files with 607 additions and 113 deletions

272
package-lock.json generated
View file

@ -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",

View file

@ -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",

View file

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#000000" />
</head>
<body>

View file

@ -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: <MainScene />,
media: <MediaScene />,
idle_media: <IdleMediaScene />,
gate: <GateScene />,
boot: <BootScene />,
sskn: <SsknScene />,
polytan: <PolytanScene />,
tak: <TaKScene />,
change_disc: <ChangeDiscScene />,
end: <EndScene />,
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 (
<div className="game" style={{ width: width, height: height }}>
<Canvas
concurrent
gl={{ antialias: false }}
pixelRatio={window.devicePixelRatio}
className="main-canvas"
>
<Suspense fallback={null}>
<Preloader />
{dispatchScene[currentScene as keyof typeof dispatchScene]}
<InputHandler isMobile={isMobile} />
</Suspense>
</Canvas>
{["media", "idle_media", "tak", "end"].includes(currentScene) && (
<div style={{ marginTop: -height }}>
<MediaPlayer />
</div>
)}
</div>
<BrowserRouter>
<Switch>
<Route path={"/"} exact component={Notes} />
<Route path={"/game"} exact component={Game} />
</Switch>
</BrowserRouter>
);
};

View file

@ -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) {

View file

@ -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 (
<spriteMaterial
attach="material"
map={lainSpriteTexture}
map={lainSprite}
alphaTest={0.665}
color={0xffffff}
/>

View file

@ -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 && (

View file

@ -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:

115
src/dom-components/Game.tsx Normal file
View file

@ -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: <MainScene />,
media: <MediaScene />,
idle_media: <IdleMediaScene />,
gate: <GateScene />,
boot: <BootScene />,
sskn: <SsknScene />,
polytan: <PolytanScene />,
tak: <TaKScene />,
change_disc: <ChangeDiscScene />,
end: <EndScene />,
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 (
<div className="game" style={{ width: width, height: height }}>
<Canvas
concurrent
gl={{ antialias: false }}
pixelRatio={window.devicePixelRatio}
className="main-canvas"
>
<Suspense fallback={null}>
<Preloader />
{dispatchScene[currentScene as keyof typeof dispatchScene]}
<InputHandler isMobile={isMobile} />
</Suspense>
</Canvas>
{["media", "idle_media", "tak", "end"].includes(currentScene) && (
<div style={{ marginTop: -height }}>
<MediaPlayer />
</div>
)}
</div>
);
};
export default Game;

View file

@ -0,0 +1,157 @@
import React from "react";
import "../static/css/notes.css";
const Notes = () => {
return (
<>
<table className="main-table">
<tbody>
<tr>
<td>
<p>Performance</p>
</td>
<td>
<p>
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.
</p>
</td>
</tr>
<tr>
<td>
<p>Keyboard Controls</p>
</td>
<td>
<table className="control-table">
<tbody>
<tr>
<td>ArrowDown</td>
<td></td>
</tr>
<tr>
<td>ArrowLeft</td>
<td></td>
</tr>
<tr>
<td>ArrowUp</td>
<td></td>
</tr>
<tr>
<td>ArrowRight</td>
<td></td>
</tr>
<tr>
<td>x</td>
<td></td>
</tr>
<tr>
<td>z</td>
<td></td>
</tr>
<tr>
<td>d</td>
<td></td>
</tr>
<tr>
<td>e</td>
<td>L2</td>
</tr>
<tr>
<td>v</td>
<td>START</td>
</tr>
<tr>
<td>k</td>
<td>Upscale Game Window</td>
</tr>
<tr>
<td>j</td>
<td>Downscale Game Window</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>
<p>Mobile/Tablet Controls</p>
</td>
<td>
<table className="control-table">
<tbody>
<tr>
<td>Swipe Down</td>
<td></td>
</tr>
<tr>
<td>Swipe Left</td>
<td></td>
</tr>
<tr>
<td>Swipe Up</td>
<td></td>
</tr>
<tr>
<td>Swipe Right</td>
<td></td>
</tr>
</tbody>
</table>
<p>
The rest of the buttons are layed out on the game screen itself.
<br />
Also, please rotate the phone horizontally when playing, I don't
want feature creep because of psychopaths.
</p>
</td>
</tr>
<tr>
<td>
<p>Saving Progress</p>
</td>
<td>
<p>
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).
<br />
The state is stored in a minimized JSON format as a string
inside localStorage with the key "lainSaveState".
</p>
</td>
</tr>
<tr>
<td>
<p>Sound</p>
</td>
<td>
<p>
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.
<br />
If this becomes a huge problem later on, I'll try to implement
an alternative for it.
</p>
</td>
</tr>
</tbody>
</table>
<a href="/game">start</a>
<br />
</>
);
};
export default Notes;

View file

@ -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 (
<group position-z={3}>
<Suspense fallback={<Loading />}>
<LevelSelection />
<Popups />
<Pause />
<a.group visible={introFinished} position-y={bgState.posY}>
<a.group
visible={intro ? introFinished : true}
position-y={bgState.posY}
>
<MainSceneBackground />
</a.group>
<group visible={!paused}>

View file

@ -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;