diff --git a/.vscode/settings.json b/.vscode/settings.json index 2100726d..b96ddc67 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -92,6 +92,7 @@ "WASD", "winbox", "worker", + "worldbounds", "xlink", "yandex" ], diff --git a/locales/de/translation.json b/locales/de/translation.json index a859f2cc..1f2e3e64 100644 --- a/locales/de/translation.json +++ b/locales/de/translation.json @@ -13,6 +13,7 @@ "AS_ACTION_TEXT": "als Aktion Text", "AS_ARCADE_SPRITE": "als Arcade Sprite", "AS_AUDIO": "als Ton", + "AS_BACKGROUND": "als Hintergrund", "AS_BALL": "als Ball", "AS_CEILING": "als Decke", "AS_DYNAMIC_TEXT": "als dynamischen Text", @@ -79,6 +80,7 @@ "BLOCKS_PHASER_DEBUG_POINTER": "Debug Zeiger", "BLOCKS_PHASER_DEBUG_SPRITE": "Debug Sprite", "BLOCKS_PHASER_DYNAMIC_TEXT_ADD_HIGHSCORE": "als Highscore", + "BLOCKS_PHASER_EVENT": "Ereignisse", "BLOCKS_PHASER_EXAMPLE_FILES": "Beispiel Dateien", "BLOCKS_PHASER_EXAMPLE_FILES_BACKGROUND": "Hintergrundbilder", "BLOCKS_PHASER_EXAMPLE_FILES_BALL": "Ballbilder", @@ -111,6 +113,7 @@ "BLOCKS_PHASER_MOUSE_KEYS": "Maus Tasten", "BLOCKS_PHASER_NO_AUTOSTART": "nicht automatisch starten", "BLOCKS_PHASER_ON_CREATE": "beim Erstellen", + "BLOCKS_PHASER_ON_EVENT": "bei Ereignis", "BLOCKS_PHASER_ON_INPUT": "bei Eingabe", "BLOCKS_PHASER_ON_OUT_OF_BOUNDS": "beim Verlassen des Spielfelds", "BLOCKS_PHASER_ON_PRELOAD": "beim Vorausladen", @@ -144,10 +147,13 @@ "BLOCKS_PHASER_TIME_EVENT": "nach", "BLOCKS_PHASER_TIME_LOOP_EVENT": "wiederhole alle", "BLOCKS_PHASER_UPDATE": "Aktualisieren", + "BLOCKS_PHASER_VARIABLE_AUDIO": "Audio", "BLOCKS_PHASER_VARIABLE_TEXT": "Text", "BLOCKS_PHASER_VARIABLE_GROUP": "Gruppe", "BLOCKS_PHASER_VARIABLE_INPUT": "Eingabe", "BLOCKS_PHASER_VARIABLE_SPRITE": "Sprite", + "BLOCKS_PHASER_VARIABLE_TILE_SPRITE": "Tile Sprite", + "BLOCKS_PHASER_VARIABLE_ARCADE_SPRITE": "Arcade Sprite", "BLOCKS_PHASER_WITH_THE_SIZE": "mit der Größe", "BLOCKS_PHASER_WORLD": "Welt", "BLOCKS_PHASER_WORLD_ARCADE_PHYSICS": "Welt Arcade-Physik", @@ -272,6 +278,8 @@ "VELOCITY_X": "Geschwindigkeit x", "VELOCITY_Y": "Geschwindigkeit y", "VISIBLE": "Sichtbar", + "WARNING.NO_VARIABLE_DEFINED": "Keine Variable definiert", + "WARNING.RESERVED_VARIABLE_NAME": "Reservierter Variablename", "WITH_AUTOSCROLL": "mit automatisches Scrollen", "WITH_DIMENSION": "mit Abmessung", "WITH_GROUP": "mit Gruppe", diff --git a/locales/en/translation.json b/locales/en/translation.json index a6d403a0..26e6dbce 100644 --- a/locales/en/translation.json +++ b/locales/en/translation.json @@ -13,6 +13,7 @@ "AS_ACTION_TEXT": "as action text", "AS_ARCADE_SPRITE": "as arcade sprite", "AS_AUDIO": "as audio", + "AS_BACKGROUND": "as background", "AS_BALL": "as ball", "AS_CEILING": "as ceiling", "AS_DYNAMIC_TEXT": "as dynamic text", @@ -80,6 +81,7 @@ "BLOCKS_PHASER_DEBUG_SPRITE": "debug sprite", "BLOCKS_PHASER_DYNAMIC_TEXT_ADD_HIGHSCORE": "as highscore", "BLOCKS_PHASER_INPUT_LOGIC": "Input Logic", + "BLOCKS_PHASER_EVENT": "Events", "BLOCKS_PHASER_EXAMPLE_FILES": "Example Files", "BLOCKS_PHASER_EXAMPLE_FILES_BACKGROUND": "Backgroud Images", "BLOCKS_PHASER_EXAMPLE_FILES_BALL": "Ball Images", @@ -112,6 +114,7 @@ "BLOCKS_PHASER_MOUSE_KEYS": "mouse keys", "BLOCKS_PHASER_NO_AUTOSTART": "no autostart", "BLOCKS_PHASER_ON_CREATE": "on create", + "BLOCKS_PHASER_ON_EVENT": "on event", "BLOCKS_PHASER_ON_INPUT": "on input", "BLOCKS_PHASER_ON_OUT_OF_BOUNDS": "on out of bounds", "BLOCKS_PHASER_ON_PRELOAD": "on preload", @@ -145,10 +148,13 @@ "BLOCKS_PHASER_TIME_LOOP_EVENT": "repeat every", "BLOCKS_PHASER_UPDATE": "Update", "BLOCKS_PHASER_WITH_THE_SIZE": "with the size", + "BLOCKS_PHASER_VARIABLE_AUDIO": "Audio", "BLOCKS_PHASER_VARIABLE_TEXT": "Text", "BLOCKS_PHASER_VARIABLE_GROUP": "Group", "BLOCKS_PHASER_VARIABLE_INPUT": "Input", "BLOCKS_PHASER_VARIABLE_SPRITE": "Sprite", + "BLOCKS_PHASER_VARIABLE_TILE_SPRITE": "Tile Sprite", + "BLOCKS_PHASER_VARIABLE_ARCADE_SPRITE": "Arcade Sprite", "BLOCKS_PHASER_WORLD": "World", "BLOCKS_PHASER_WORLD_ARCADE_PHYSICS": "world arcade physics", "BLOCKS_PHASER_WORLD_ARCADE_PHYSICS_CHANGE": "change world arcade physics", @@ -272,6 +278,8 @@ "VELOCITY_X": "velocity x", "VELOCITY_Y": "velocity y", "VISIBLE": "visible", + "WARNING.NO_VARIABLE_DEFINED": "No variable defined", + "WARNING.RESERVED_VARIABLE_NAME": "Reserved variable name", "WITH_AUTOSCROLL": "with autoscroll", "WITH_DIMENSION": "with dimension", "WITH_GROUP": "with group", diff --git a/package-lock.json b/package-lock.json index 7dc01c75..fe80531c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coding-with-chrome", - "version": "10.3.3", + "version": "10.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coding-with-chrome", - "version": "10.3.3", + "version": "10.4.0", "license": "Apache-2.0", "devDependencies": { "@babel/cli": "^7.23.9", @@ -19,21 +19,21 @@ "@babel/register": "^7.23.7", "@codemirror/commands": "^6.3.3", "@codemirror/lang-html": "^6.4.8", - "@codemirror/lang-javascript": "^6.2.1", - "@codemirror/state": "^6.4.0", + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/state": "^6.4.1", "@emotion/styled": "^11.11.0", "@jsdevtools/coverage-istanbul-loader": "^3.0.5", "@lhci/cli": "^0.13.0", "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", - "@mui/styled-engine": "^5.15.9", + "@mui/styled-engine": "^5.15.11", "@playwright/test": "^1.41.2", "@svgr/webpack": "^8.1.0", - "@types/react": "^18.2.55", + "@types/react": "^18.2.58", "@types/serviceworker-webpack-plugin": "^1.0.7", - "@typescript-eslint/eslint-plugin": "^7.0.1", - "@typescript-eslint/parser": "^7.0.1", - "@uiw/react-codemirror": "^4.21.21", + "@typescript-eslint/eslint-plugin": "^7.0.2", + "@typescript-eslint/parser": "^7.0.2", + "@uiw/react-codemirror": "^4.21.23", "babel-loader": "^9.1.3", "clean-webpack-plugin": "^4.0.0", "compression-webpack-plugin": "^11.0.0", @@ -41,7 +41,7 @@ "cross-env": "^7.0.3", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", - "emoji-picker-react": "^4.7.17", + "emoji-picker-react": "^4.8.0", "eslint": "^8.56.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^9.1.0", @@ -52,9 +52,9 @@ "gh-pages": "^6.1.1", "html-minimizer-webpack-plugin": "^5.0.0", "html-webpack-plugin": "^5.6.0", - "i18next": "^23.8.2", + "i18next": "^23.10.0", "i18next-browser-languagedetector": "^7.2.0", - "i18next-http-backend": "^2.4.3", + "i18next-http-backend": "^2.5.0", "json-minimizer-webpack-plugin": "^5.0.0", "karma": "^6.4.2", "karma-chrome-launcher": "^3.2.0", @@ -69,7 +69,7 @@ "material-icons": "^1.13.12", "mini-css-extract-plugin": "^2.8.0", "npm": "^10.4.0", - "phaser": "^3.70.0", + "phaser": "^3.80.0", "playwright": "^1.41.2", "prettier": "^3.2.5", "react": "^18.2.0", @@ -79,8 +79,8 @@ "react-mosaic-component": "^6.1.0", "react-router-dom": "^6.22.0", "react-winbox": "^1.5.0", - "sass": "^1.70.0", - "sass-loader": "^14.1.0", + "sass": "^1.71.1", + "sass-loader": "^14.1.1", "style-loader": "^3.3.4", "styled-components": "^6.1.8", "terser-webpack-plugin": "^5.3.10", @@ -88,7 +88,7 @@ "uglify-js": "^3.17.4", "url-loader": "^4.1.1", "uuid": "^9.0.1", - "webpack": "^5.90.1", + "webpack": "^5.90.3", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.0", "webpack-merge": "^5.10.0", @@ -2090,9 +2090,9 @@ } }, "node_modules/@codemirror/lang-javascript": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.1.tgz", - "integrity": "sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", + "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==", "dev": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -2141,9 +2141,9 @@ } }, "node_modules/@codemirror/state": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz", - "integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==", "dev": true }, "node_modules/@codemirror/theme-one-dark": { @@ -2159,9 +2159,9 @@ } }, "node_modules/@codemirror/view": { - "version": "6.24.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.24.0.tgz", - "integrity": "sha512-zK6m5pNkdhdJl8idPP1gA4N8JKTiSsOz8U/Iw+C1ChMwyLG7+MLiNXnH/wFuAk6KeGEe33/adOiAh5jMqee03w==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.24.1.tgz", + "integrity": "sha512-sBfP4rniPBRQzNakwuQEqjEuiJDWJyF2kqLLqij4WXRoVwPPJfjx966Eq3F7+OPQxDtMt/Q9MWLoZLWjeveBlg==", "dev": true, "dependencies": { "@codemirror/state": "^6.4.0", @@ -2887,9 +2887,9 @@ "dev": true }, "node_modules/@lezer/css": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.7.tgz", - "integrity": "sha512-7BlFFAKNn/b39jJLrhdLSX5A2k56GIJvyLqdmm7UU+7XvequY084iuKDMAEhAmAzHnwDE8FK4OQtsIUssW91tg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz", + "integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==", "dev": true, "dependencies": { "@lezer/common": "^1.2.0", @@ -2907,9 +2907,9 @@ } }, "node_modules/@lezer/html": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.8.tgz", - "integrity": "sha512-EXseJ3pUzWxE6XQBQdqWHZqqlGQRSuNMBcLb6mZWS2J2v+QZhOObD+3ZIKIcm59ntTzyor4LqFTb72iJc3k23Q==", + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.9.tgz", + "integrity": "sha512-MXxeCMPyrcemSLGaTQEZx0dBUH0i+RPl8RN5GwMAzo53nTsd/Unc/t5ZxACeQoyPUM5/GkPLRUs2WliOImzkRA==", "dev": true, "dependencies": { "@lezer/common": "^1.2.0", @@ -2986,9 +2986,9 @@ } }, "node_modules/@mdn/browser-compat-data": { - "version": "5.5.10", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.10.tgz", - "integrity": "sha512-s2GGND9oLhEuksOFtICYOBZdMWPANBXTMqAXh89q6g1Mi3+OuWEmp9WFzw2v/nmS175vqeewpC1kDJA7taaxyA==", + "version": "5.5.11", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.11.tgz", + "integrity": "sha512-4o1ZaGmvqoDx3QLyEAcZvGDKmdVXLB0aiANuPDumgue/7iH67KUBsKejLX7wrdxEdyNYfXUKtjFQYhGwVUBXGw==", "dev": true }, "node_modules/@mui/base": { @@ -3024,9 +3024,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.10", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.10.tgz", - "integrity": "sha512-qPv7B+LeMatYuzRjB3hlZUHqinHx/fX4YFBiaS19oC02A1e9JFuDKDvlyRQQ5oRSbJJt0QlaLTlr0IcauVcJRQ==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz", + "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==", "dev": true, "funding": { "type": "opencollective", @@ -3105,13 +3105,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.9", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.9.tgz", - "integrity": "sha512-/aMJlDOxOTAXyp4F2rIukW1O0anodAMCkv1DfBh/z9vaKHY3bd5fFf42wmP+0GRmwMinC5aWPpNfHXOED1fEtg==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz", + "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==", "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.15.9", + "@mui/utils": "^5.15.11", "prop-types": "^15.8.1" }, "engines": { @@ -3132,9 +3132,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.9", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.9.tgz", - "integrity": "sha512-NRKtYkL5PZDH7dEmaLEIiipd3mxNnQSO+Yo8rFNBNptY8wzQnQ+VjayTq39qH7Sast5cwHKYFusUrQyD+SS4Og==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", @@ -3218,9 +3218,9 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.9.tgz", - "integrity": "sha512-yDYfr61bCYUz1QtwvpqYy/3687Z8/nS4zv7lv/ih/6ZFGMl1iolEvxRmR84v2lOYxlds+kq1IVYbXxDKh8Z9sg==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz", + "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==", "dev": true, "dependencies": { "@babel/runtime": "^7.23.9", @@ -3636,9 +3636,9 @@ "dev": true }, "node_modules/@sindresorhus/merge-streams": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.2.1.tgz", - "integrity": "sha512-255V7MMIKw6aQ43Wbqp9HZ+VHn6acddERTLiiLnlcPLU9PdTq9Aijl12oklAgUEblLWye+vHLzmqBx6f2TGcZw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, "engines": { "node": ">=18" @@ -3988,9 +3988,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", - "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "version": "8.56.3", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.3.tgz", + "integrity": "sha512-PvSf1wfv2wJpVIFUMSb+i4PvqNYkB9Rkp9ZDO3oaWzq4SKhsQk4mrMBr3ZH06I0hKrVGLBacmgl8JM4WVjb9dg==", "dev": true, "dependencies": { "@types/estree": "*", @@ -4111,9 +4111,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -4153,9 +4153,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.56", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz", - "integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==", + "version": "18.2.58", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.58.tgz", + "integrity": "sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -4352,16 +4352,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.1.tgz", - "integrity": "sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", + "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.1", - "@typescript-eslint/type-utils": "7.0.1", - "@typescript-eslint/utils": "7.0.1", - "@typescript-eslint/visitor-keys": "7.0.1", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/type-utils": "7.0.2", + "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -4420,15 +4420,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.1.tgz", - "integrity": "sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", + "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.0.1", - "@typescript-eslint/types": "7.0.1", - "@typescript-eslint/typescript-estree": "7.0.1", - "@typescript-eslint/visitor-keys": "7.0.1", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4" }, "engines": { @@ -4448,13 +4448,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.1.tgz", - "integrity": "sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", + "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.1", - "@typescript-eslint/visitor-keys": "7.0.1" + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4465,13 +4465,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.1.tgz", - "integrity": "sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", + "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.1", - "@typescript-eslint/utils": "7.0.1", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/utils": "7.0.2", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -4492,9 +4492,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.1.tgz", - "integrity": "sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", + "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4505,13 +4505,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.1.tgz", - "integrity": "sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", + "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.1", - "@typescript-eslint/visitor-keys": "7.0.1", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4566,17 +4566,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.1.tgz", - "integrity": "sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", + "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.1", - "@typescript-eslint/types": "7.0.1", - "@typescript-eslint/typescript-estree": "7.0.1", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", "semver": "^7.5.4" }, "engines": { @@ -4624,12 +4624,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.1.tgz", - "integrity": "sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", + "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.0.1", + "@typescript-eslint/types": "7.0.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4641,9 +4641,9 @@ } }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.21.22", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.22.tgz", - "integrity": "sha512-Lxq2EitQb/MwbNrMHBmVdSIR96WmaICnYBYeZbLUxmr4kQcbrA6HXqNSNZJ0V4ZihPfKnNs9+g87QK0HsadE6A==", + "version": "4.21.23", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.21.23.tgz", + "integrity": "sha512-8czPnm5f/UthTbByamiaeutvDDUf2ZIbXyfuamrU3J/ThLRVzOxtvv9Su1BWiFbO2enixQfxrKaZd26uuYUbtQ==", "dev": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -4668,16 +4668,16 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.21.22", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.21.22.tgz", - "integrity": "sha512-VmxU9oRXwcleG2u5Ui2xVXaLVPL8cBuRN3vA41hlu4OQ/ftJb+4p+dBd6bZ+NJKSXm3LufbPGzu8oKwNO4tG4A==", + "version": "4.21.23", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.21.23.tgz", + "integrity": "sha512-KCjIQdkb4Y1ZsMvWwj/rGjC81VFvzRNYvcpNpBzBx3D2ZlWdMnCWHV9KJtDuHyKTHQlgpWNp8HMnUjxaQsnisA==", "dev": true, "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.21.22", + "@uiw/codemirror-extensions-basic-setup": "4.21.23", "codemirror": "^6.0.0" }, "funding": { @@ -5292,10 +5292,13 @@ "dev": true }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5647,9 +5650,9 @@ } }, "node_modules/blockly": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.1.tgz", - "integrity": "sha512-FcAnMU4/uJkOiY3p3OISDfko8iXFlEIF52L2l1EclShkLuC+igW670Q2I+RXhjIyWRA9Lv08BCQLWuGXlsAlKw==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/blockly/-/blockly-10.4.2.tgz", + "integrity": "sha512-oCJkHZD1HEPYPwnMk/sbmMmhW6UFe+3iH5yvDn3hy3HSVzCOunkw9H1Crb/MmlhhFdvjB5uWgGzQNAa2eWAV6A==", "dev": true, "dependencies": { "jsdom": "22.1.0" @@ -5907,9 +5910,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001588", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", "dev": true, "funding": [ { @@ -7060,13 +7063,13 @@ } }, "node_modules/cssnano": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz", - "integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.4.tgz", + "integrity": "sha512-Bp607LopXmwV9TPUxw76yvcvRk4AYrrtHtLsndAnSWUwT4xgaiC6Eaa44cZ6ciu9J7Sqv9zocMTDcyQnU4dihw==", "dev": true, "dependencies": { - "cssnano-preset-default": "^6.0.3", - "lilconfig": "^3.0.0" + "cssnano-preset-default": "^6.0.4", + "lilconfig": "^3.1.1" }, "engines": { "node": "^14 || ^16 || >=18.0" @@ -7080,19 +7083,19 @@ } }, "node_modules/cssnano-preset-default": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.3.tgz", - "integrity": "sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.4.tgz", + "integrity": "sha512-mvyBIFHaFA4lkBwePlB9Gycnf/rgFQRKcP/yHG/tbD0ZuIdCDSF1GoL4QC4gcp8qaJOkmVmb0mCXMR6Wi4Da0A==", "dev": true, "dependencies": { "css-declaration-sorter": "^7.1.1", "cssnano-utils": "^4.0.1", "postcss-calc": "^9.0.1", "postcss-colormin": "^6.0.2", - "postcss-convert-values": "^6.0.2", + "postcss-convert-values": "^6.0.3", "postcss-discard-comments": "^6.0.1", - "postcss-discard-duplicates": "^6.0.1", - "postcss-discard-empty": "^6.0.1", + "postcss-discard-duplicates": "^6.0.2", + "postcss-discard-empty": "^6.0.2", "postcss-discard-overridden": "^6.0.1", "postcss-merge-longhand": "^6.0.2", "postcss-merge-rules": "^6.0.3", @@ -7708,9 +7711,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", + "version": "1.4.680", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.680.tgz", + "integrity": "sha512-4nToZ5jlPO14W82NkF32wyjhYqQByVaDmLy4J2/tYcAbJfgO2TKJC780Az1V13gzq4l73CJ0yuyalpXvxXXD9A==", "dev": true }, "node_modules/email-addresses": { @@ -7720,9 +7723,9 @@ "dev": true }, "node_modules/emoji-picker-react": { - "version": "4.7.18", - "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.7.18.tgz", - "integrity": "sha512-ZYTUl9KdSFfrdmPmAhcVwSv6/fBuhIw6LxqOJ8jz5min8sezjEArGs25LGjf6VABNE4895HBsuJ5uVKIb0lJuw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.8.0.tgz", + "integrity": "sha512-gKv+NOM2FjNAokXqlhhmDJMLp1hBTx4X+OoYrPAK1qpTVBseoeybtqPBR1NXixTow7Vbxv1WOuI3SSTiEB089A==", "dev": true, "dependencies": { "flairup": "0.0.38" @@ -8007,14 +8010,14 @@ "dev": true }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -9090,9 +9093,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { @@ -9682,9 +9685,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -10092,9 +10095,9 @@ } }, "node_modules/http-link-header": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.1.tgz", - "integrity": "sha512-mW3N/rTYpCn99s1do0zx6nzFZSwLH9HGfUM4ZqLWJ16ylmYaC2v5eYGqrNTQlByx8AzUgGI+V/32gXPugs1+Sw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.2.tgz", + "integrity": "sha512-6qz1XhMq/ryde52SZGzVhzi3jcG2KqO16KITkupyQxvW6u7iylm0Fq7r3OpCYsc0S0ELlCiFpuxDcccUwjbEqA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -10192,9 +10195,9 @@ } }, "node_modules/i18next": { - "version": "23.8.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.8.3.tgz", - "integrity": "sha512-IQn6Tfn+XkIRHjC/z3uQSGLhsRC6Y14kgyrsgoPqnFD9MqbNt2B9MF3Ch4p114pEVPQ2qktE2nd0aYr7UxRLKA==", + "version": "23.10.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.0.tgz", + "integrity": "sha512-/TgHOqsa7/9abUKJjdPeydoyDc0oTi/7u9F8lMSj6ufg4cbC1Oj3f/Jja7zj7WRIhEQKB7Q4eN6y68I9RDxxGQ==", "dev": true, "funding": [ { @@ -10224,9 +10227,9 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.4.3.tgz", - "integrity": "sha512-jo2M03O6n1/DNb51WSQ8PsQ0xEELzLZRdYUTbf17mLw3rVwnJF9hwNgMXvEFSxxb+N8dT+o0vtigA6s5mGWyPA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.0.tgz", + "integrity": "sha512-Z/aQsGZk1gSxt2/DztXk92DuDD20J+rNudT7ZCdTrNOiK8uQppfvdjq9+DFQfpAnFPn3VZS+KQIr1S/W1KxhpQ==", "dev": true, "dependencies": { "cross-fetch": "4.0.0" @@ -10778,9 +10781,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -10932,12 +10935,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11249,9 +11255,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -12407,9 +12413,9 @@ } }, "node_modules/lilconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.0.tgz", - "integrity": "sha512-p3cz0JV5vw/XeouBU3Ldnp+ZkBjE+n8ydJ4mcwBrOiXXPqNlrzGBqWs9X4MWF7f+iKUBu794Y8Hh8yawiJbCjw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true, "engines": { "node": ">=14" @@ -12612,9 +12618,9 @@ } }, "node_modules/memfs": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.7.6.tgz", - "integrity": "sha512-PMxcVnZYdSFYZIzsbhd8XLvxrHaIarhyyfDQHThUwhAYAPDfDTvKhEjWbzPyGFr9CPvJJl+VUetfcnVVF9Wckg==", + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.7.7.tgz", + "integrity": "sha512-x9qc6k88J/VVwnfTkJV8pRRswJ2156Rc4w5rciRqKceFDZ0y1MqsNL9pkg5sE0GOcDzZYbonreALhaHzg1siFw==", "dev": true, "dependencies": { "tslib": "^2.0.0" @@ -16310,9 +16316,9 @@ "dev": true }, "node_modules/phaser": { - "version": "3.70.0", - "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.70.0.tgz", - "integrity": "sha512-2g+gh+Jp9f/Ho9FOXOYbIJMGf3UZXyMbW2iLScFaLQw11e/LqVyxj/YmaBauWbHabeTnZjiWkPklDnxhesMH0g==", + "version": "3.80.0", + "resolved": "https://registry.npmjs.org/phaser/-/phaser-3.80.0.tgz", + "integrity": "sha512-LUEPFzQKXSlPxrDjFUaeq6t47j1Y58F67OsCKflvDH1DUSwVxAD1/vDUPQJj+dWniKBxAlL1BoCXQnjmtcJxUQ==", "dev": true, "dependencies": { "eventemitter3": "^5.0.1" @@ -16498,6 +16504,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.35", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", @@ -16561,9 +16576,9 @@ } }, "node_modules/postcss-convert-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.2.tgz", - "integrity": "sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.3.tgz", + "integrity": "sha512-Tj+VH3GtQxvBVX6hhggIUaAMLDbqoHgsAFeZ8iCOD03hnho+wrOF2IsahY9o4MANtaJEjqABrhD1SqwIILGH9A==", "dev": true, "dependencies": { "browserslist": "^4.22.2", @@ -16589,9 +16604,9 @@ } }, "node_modules/postcss-discard-duplicates": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.1.tgz", - "integrity": "sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.2.tgz", + "integrity": "sha512-U2rsj4w6pAGROCCcD13LP2eBIi1whUsXs4kgE6xkIuGfkbxCBSKhkCTWyowFd66WdVlLv0uM1euJKIgmdmZObg==", "dev": true, "engines": { "node": "^14 || ^16 || >=18.0" @@ -16601,9 +16616,9 @@ } }, "node_modules/postcss-discard-empty": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.1.tgz", - "integrity": "sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.2.tgz", + "integrity": "sha512-rj6pVC2dVCJrP0Y2RkYTQEbYaCf4HEm+R/2StQgJqGHxAa3+KcYslNQhcRqjLHtl/4wpzipJluaJLqBj6d5eDQ==", "dev": true, "engines": { "node": "^14 || ^16 || >=18.0" @@ -18023,9 +18038,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz", - "integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==", + "version": "1.71.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", + "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -18040,9 +18055,9 @@ } }, "node_modules/sass-loader": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.0.tgz", - "integrity": "sha512-LS2mLeFWA+orYxHNu+O18Xe4jR0kyamNOOUsE3NyBP4DvIL+8stHpNX0arYTItdPe80kluIiJ7Wfe/9iHSRO0Q==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.1.tgz", + "integrity": "sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw==", "dev": true, "dependencies": { "neo-async": "^2.6.2" @@ -18329,14 +18344,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -18468,11 +18484,12 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", + "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", "dev": true, "dependencies": { + "debug": "~4.3.4", "ws": "~8.11.0" } }, @@ -18531,9 +18548,9 @@ } }, "node_modules/socks": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", - "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", "dev": true, "dependencies": { "ip-address": "^9.0.5", @@ -18713,9 +18730,9 @@ } }, "node_modules/streamx": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.0.tgz", - "integrity": "sha512-a7Fi0PoUeusrUcMS4+HxivnZqYsw2MFEP841TIyLxTcEIucHcJsk+0ARcq3tGq1xDn+xK7sKHetvfMzI1/CzMA==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", "dev": true, "dependencies": { "fast-fifo": "^1.1.0", @@ -19245,9 +19262,9 @@ } }, "node_modules/terser": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.1.tgz", - "integrity": "sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.0.tgz", + "integrity": "sha512-UK1n2JZN6gqfwmjzcikRp+uF/7jdwPXO7M0k/Hnqxzj3T5POL4YBVrv5Y4MKixTzBq4OmH7FfEYRxcy/Eh7YhA==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -19567,12 +19584,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -19581,15 +19598,16 @@ } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -19599,16 +19617,16 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", - "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" }, "engines": { @@ -19619,14 +19637,20 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -20016,9 +20040,9 @@ } }, "node_modules/webpack": { - "version": "5.90.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.2.tgz", - "integrity": "sha512-ziXu8ABGr0InCMEYFnHrYweinHK2PWrMqnwdHk2oK3rRhv/1B+2FnfwYv5oD+RrknK/Pp/Hmyvu+eAsaMYhzCw==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", diff --git a/package.json b/package.json index 9280516d..bb4525b3 100644 --- a/package.json +++ b/package.json @@ -23,21 +23,21 @@ "@babel/register": "^7.23.7", "@codemirror/commands": "^6.3.3", "@codemirror/lang-html": "^6.4.8", - "@codemirror/lang-javascript": "^6.2.1", - "@codemirror/state": "^6.4.0", + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/state": "^6.4.1", "@emotion/styled": "^11.11.0", "@jsdevtools/coverage-istanbul-loader": "^3.0.5", "@lhci/cli": "^0.13.0", "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", - "@mui/styled-engine": "^5.15.9", + "@mui/styled-engine": "^5.15.11", "@playwright/test": "^1.41.2", "@svgr/webpack": "^8.1.0", - "@types/react": "^18.2.55", + "@types/react": "^18.2.58", "@types/serviceworker-webpack-plugin": "^1.0.7", - "@typescript-eslint/eslint-plugin": "^7.0.1", - "@typescript-eslint/parser": "^7.0.1", - "@uiw/react-codemirror": "^4.21.21", + "@typescript-eslint/eslint-plugin": "^7.0.2", + "@typescript-eslint/parser": "^7.0.2", + "@uiw/react-codemirror": "^4.21.23", "babel-loader": "^9.1.3", "clean-webpack-plugin": "^4.0.0", "compression-webpack-plugin": "^11.0.0", @@ -45,7 +45,7 @@ "cross-env": "^7.0.3", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", - "emoji-picker-react": "^4.7.17", + "emoji-picker-react": "^4.8.0", "eslint": "^8.56.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^9.1.0", @@ -56,9 +56,9 @@ "gh-pages": "^6.1.1", "html-minimizer-webpack-plugin": "^5.0.0", "html-webpack-plugin": "^5.6.0", - "i18next": "^23.8.2", + "i18next": "^23.10.0", "i18next-browser-languagedetector": "^7.2.0", - "i18next-http-backend": "^2.4.3", + "i18next-http-backend": "^2.5.0", "json-minimizer-webpack-plugin": "^5.0.0", "karma": "^6.4.2", "karma-chrome-launcher": "^3.2.0", @@ -73,7 +73,7 @@ "material-icons": "^1.13.12", "mini-css-extract-plugin": "^2.8.0", "npm": "^10.4.0", - "phaser": "^3.70.0", + "phaser": "^3.80.0", "playwright": "^1.41.2", "prettier": "^3.2.5", "react": "^18.2.0", @@ -83,8 +83,8 @@ "react-mosaic-component": "^6.1.0", "react-router-dom": "^6.22.0", "react-winbox": "^1.5.0", - "sass": "^1.70.0", - "sass-loader": "^14.1.0", + "sass": "^1.71.1", + "sass-loader": "^14.1.1", "style-loader": "^3.3.4", "styled-components": "^6.1.8", "terser-webpack-plugin": "^5.3.10", @@ -92,7 +92,7 @@ "uglify-js": "^3.17.4", "url-loader": "^4.1.1", "uuid": "^9.0.1", - "webpack": "^5.90.1", + "webpack": "^5.90.3", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.0", "webpack-merge": "^5.10.0", diff --git a/src/components/GameEditor/GameEditor.js b/src/components/GameEditor/GameEditor.js index 5cf1dca2..91916999 100644 --- a/src/components/GameEditor/GameEditor.js +++ b/src/components/GameEditor/GameEditor.js @@ -275,6 +275,14 @@ export class GameEditor extends React.PureComponent { this.setState({ screenshotUrl: '', project: this.state.project }); }); break; + case 'runtime_error': + console.log('[GameEditor] Received runtime error...'); + console.error(event.data.value); + break; + case 'error': + console.log('[GameEditor] Received error...'); + console.error(event.data.value); + break; } } diff --git a/src/components/GameEditor/blocks/ArcadePhysicsBlocks.js b/src/components/GameEditor/blocks/ArcadePhysicsBlocks.js index 2296f7b5..eb524de0 100644 --- a/src/components/GameEditor/blocks/ArcadePhysicsBlocks.js +++ b/src/components/GameEditor/blocks/ArcadePhysicsBlocks.js @@ -347,8 +347,8 @@ Blocks['phaser_physics_arcade_sprite_adjust'] = { this.appendValueInput('value') .setCheck('Number') .appendField(i18next.t('BLOCKS_TO')); - this.setPreviousStatement(true, ['Create', 'Update', 'Input']); - this.setNextStatement(true, ['Create', 'Update', 'Input']); + this.setPreviousStatement(true, ['Create', 'Event', 'Update', 'Input']); + this.setNextStatement(true, ['Create', 'Event', 'Update', 'Input']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -514,8 +514,8 @@ Blocks['phaser_physics_arcade_sprite_adjust_dimension'] = { this.appendDummyInput().appendField(i18next.t('WITH_DIMENSION')); this.appendValueInput('width').setCheck('Number'); this.appendValueInput('height').appendField('x').setCheck('Number'); - this.setPreviousStatement(true, 'Create'); - this.setNextStatement(true, 'Create'); + this.setPreviousStatement(true, 'Create', 'Event'); + this.setNextStatement(true, 'Create', 'Event'); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -589,8 +589,8 @@ Blocks['phaser_physics_arcade_sprite_destroy'] = { .appendField(i18next.t('BLOCKS_PHASER_PHYSICS_SPRITE_DESTROY')); this.appendValueInput('variable'); this.setInputsInline(true); - this.setPreviousStatement(true, ['Create', 'Update', 'Input']); - this.setNextStatement(true, ['Create', 'Update', 'Input']); + this.setPreviousStatement(true, ['Create', 'Event', 'Update', 'Input']); + this.setNextStatement(true, ['Create', 'Event', 'Update', 'Input']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -622,8 +622,8 @@ Blocks['phaser_physics_arcade_sprite_kill'] = { .appendField(i18next.t('BLOCKS_PHASER_PHYSICS_SPRITE_KILL')); this.appendValueInput('variable'); this.setInputsInline(true); - this.setPreviousStatement(true, ['Create', 'Update', 'Input']); - this.setNextStatement(true, ['Create', 'Update', 'Input']); + this.setPreviousStatement(true, ['Create', 'Event', 'Update', 'Input']); + this.setNextStatement(true, ['Create', 'Event', 'Update', 'Input']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -689,8 +689,8 @@ Blocks['phaser_physics_arcade_out_of_bounds'] = { this.appendValueInput('variable'); this.appendStatementInput('CODE').appendField(i18next.t('BLOCKS_DO')); this.setInputsInline(true); - this.setPreviousStatement(true, 'Create'); - this.setNextStatement(true, 'Create'); + this.setPreviousStatement(true, ['Create', 'Event']); + this.setNextStatement(true, ['Create', 'Event']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -734,8 +734,8 @@ Blocks['phaser_physics_arcade_overlap'] = { this.appendValueInput('object2'); this.appendStatementInput('CODE').appendField(i18next.t('BLOCKS_DO')); this.setInputsInline(true); - this.setPreviousStatement(true, 'Update'); - this.setNextStatement(true, 'Update'); + this.setPreviousStatement(true, ['Create', 'Event']); + this.setNextStatement(true, ['Create', 'Event']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); @@ -776,8 +776,8 @@ Blocks['phaser_physics_arcade_collide'] = { i18next.t('BLOCKS_PHASER_COLLIDE_WITH'), ); this.appendValueInput('object2'); - this.setPreviousStatement(true, 'Update'); - this.setNextStatement(true, 'Update'); + this.setPreviousStatement(true, ['Create', 'Event']); + this.setNextStatement(true, ['Create', 'Event']); this.setColour(0); this.setTooltip(''); this.setHelpUrl(''); diff --git a/src/components/GameEditor/blocks/BlocksHelper.js b/src/components/GameEditor/blocks/BlocksHelper.js index ed8945b0..7a23b27f 100644 --- a/src/components/GameEditor/blocks/BlocksHelper.js +++ b/src/components/GameEditor/blocks/BlocksHelper.js @@ -20,11 +20,48 @@ * @author mbordihn@google.com (Markus Bordihn) */ -import Blockly from 'blockly'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars +import Blockly, { Block } from 'blockly'; +import { javascriptGenerator } from 'blockly/javascript'; import { BlocksBuilder } from '../../BlockEditor/blocks/BlocksBuilder'; import { PhaserBlocksBuilder } from './PhaserBlocksBuilder'; +import i18next from 'i18next'; + +const reservedPhaserVariables = [ + 'add', + 'anims', + 'cache', + 'cameras', + 'children', + 'collision', + 'create', + 'data', + 'default_group', + 'events', + 'game', + 'helper_', + 'input', + 'lights', + 'load', + 'make', + 'physics', + 'plugins', + 'preload', + 'registry', + 'render', + 'renderer', + 'scale', + 'scene', + 'sound', + 'sys', + 'textures', + 'time', + 'tweens', + 'update', +]; + /** * Simple Blocks Helper */ @@ -99,7 +136,42 @@ export class BlocksHelper { /** * @param {BlockSvg} blockSvg - * @param {String} blockType + * @param {Array.} blockTypes + * @param {String} defaultName + * @param {String} defaultValue + * @return {!Array} + */ + static phaserVariables( + blockSvg, + blockTypes = ['phaser_variable_set'], + defaultName = 'found_no_variable', + defaultValue = 'default', + ) { + // Get all variables for the given block types. + const variableMap = new Map(); + for (const blockType of blockTypes) { + const variables = this.phaserVariable( + blockSvg, + blockType, + defaultName, + defaultValue, + ); + for (const variable of variables) { + variableMap.set(variable[0], variable[1]); + } + } + + // Remove default variable name and value, if other variables are available. + if (variableMap.size > 1) { + variableMap.delete(defaultName); + } + + return [].concat([...variableMap.entries()]).sort(); + } + + /** + * @param {BlockSvg} blockSvg + * @param {String|Array.} blockType * @param {String} defaultName * @param {String} defaultValue * @return {!Array} @@ -112,6 +184,7 @@ export class BlocksHelper { ) { const variableMap = new Map(); const mainWorkspace = Blockly.getMainWorkspace(); + // Get all variables from the workspace. const variableBlocks = mainWorkspace.getBlocksByType(blockType); for (const variableBlock of variableBlocks) { @@ -167,6 +240,36 @@ export class BlocksHelper { return [].concat([...variableMap.entries()]).sort(); } + /** + * @param {Block} block + * @param {String} variableType + * @return {string} + */ + static getVariableName(block, variableType = '') { + let variableName = block.getFieldValue('VAR'); + if (!variableName.startsWith('this')) { + variableName = 'this.' + variableName; + } + if (variableType && !variableName.endsWith(variableType)) { + variableName += variableType; + } + return [variableName, javascriptGenerator.ORDER_ATOMIC]; + } + + /** + * @param {Block} block + */ + static checkVariableName(block) { + const variableName = block.getFieldValue('VAR'); + if (!variableName) { + block.setWarningText(i18next.t('WARNING.NO_VARIABLE_DEFINED')); + } else if (reservedPhaserVariables.includes(variableName)) { + block.setWarningText(i18next.t('WARNING.RESERVED_VARIABLE_NAME')); + } else { + block.setWarningText(null); + } + } + /** * @param {String} blockXML * @return {String} diff --git a/src/components/GameEditor/blocks/CreateBlocks.js b/src/components/GameEditor/blocks/CreateBlocks.js index cef44f44..5d4a0378 100644 --- a/src/components/GameEditor/blocks/CreateBlocks.js +++ b/src/components/GameEditor/blocks/CreateBlocks.js @@ -41,7 +41,7 @@ Blocks['phaser_create'] = { .setAlign(Blockly.ALIGN_CENTRE) .setCheck(['Create']); this.setPreviousStatement(true, 'Create_'); - this.setNextStatement(true, ['Update_', 'Input_']); + this.setNextStatement(true, ['Update_', 'Input_', 'Event_']); this.setColour(30); this.setTooltip(''); this.setHelpUrl(''); @@ -63,6 +63,11 @@ javascriptGenerator.forBlock['phaser_create'] = function (block) { this.default_group = this.add.group(undefined, 'default_group'); ${javascriptGenerator.statementToCode(block, 'CODE')} + + // Separate event block for better code structure. + if (this.event_) { + this.event_(event); + } }`; }; diff --git a/src/components/GameEditor/blocks/EventBlocks.js b/src/components/GameEditor/blocks/EventBlocks.js new file mode 100644 index 00000000..d25ed163 --- /dev/null +++ b/src/components/GameEditor/blocks/EventBlocks.js @@ -0,0 +1,60 @@ +/** + * @fileoverview Phaser Event Blocks for Blockly. + * + * @license Copyright 2020 The Coding with Chrome Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author mbordihn@google.com (Markus Bordihn) + */ + +import Blockly, { Blocks } from 'blockly'; +import { javascriptGenerator } from 'blockly/javascript'; + +import { BlocksTemplate } from '../../BlockEditor/blocks/BlocksTemplate'; + +import i18next from 'i18next'; + +/** + * Phaser events section. + */ +Blocks['phaser_event'] = { + init: function () { + this.appendDummyInput() + .appendField(BlocksTemplate.addCircle()) + .appendField(i18next.t('BLOCKS_PHASER_ON_EVENT')); + this.appendStatementInput('CODE') + .appendField(i18next.t('BLOCKS_DO')) + .setAlign(Blockly.ALIGN_CENTRE) + .setCheck(['Event']); + this.setPreviousStatement(true, 'Event_'); + this.setNextStatement(true, ['Update_', 'Render_']); + this.setColour(35); + this.setTooltip(''); + this.setHelpUrl(''); + }, +}; + +/** + * Phaser events section. + * @param {Blockly.Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_event'] = function (block) { + return ` + event_ (event) { + ${javascriptGenerator.statementToCode(block, 'CODE')} + }`; +}; diff --git a/src/components/GameEditor/blocks/GameBlocks.js b/src/components/GameEditor/blocks/GameBlocks.js index 65fbae5e..1111954e 100644 --- a/src/components/GameEditor/blocks/GameBlocks.js +++ b/src/components/GameEditor/blocks/GameBlocks.js @@ -184,5 +184,9 @@ Blocks['phaser_game_restart'] = { * @return {string} */ javascriptGenerator.forBlock['phaser_game_restart'] = function () { - return 'this.scene.restart();\n'; + return ` + this.events.off(); + this.registry.destroy(); + this.scene.restart(); + `; }; diff --git a/src/components/GameEditor/blocks/InputBlocks.js b/src/components/GameEditor/blocks/InputBlocks.js index f84813a1..9f9446a2 100644 --- a/src/components/GameEditor/blocks/InputBlocks.js +++ b/src/components/GameEditor/blocks/InputBlocks.js @@ -41,7 +41,7 @@ Blocks['phaser_input'] = { .setAlign(Blockly.ALIGN_CENTRE) .setCheck(['Input']); this.setPreviousStatement(true, 'Input_'); - this.setNextStatement(true, 'Update_'); + this.setNextStatement(true, ['Event_', 'Update_']); this.setColour(135); this.setTooltip(''); this.setHelpUrl(''); diff --git a/src/components/GameEditor/blocks/TileSpriteBlocks.js b/src/components/GameEditor/blocks/TileSpriteBlocks.js index 17f782da..b0fee8eb 100644 --- a/src/components/GameEditor/blocks/TileSpriteBlocks.js +++ b/src/components/GameEditor/blocks/TileSpriteBlocks.js @@ -33,9 +33,11 @@ import i18next from 'i18next'; */ Blocks['phaser_tile_sprite_background'] = { init: function () { - this.appendDummyInput() + this.appendValueInput('variable') .appendField(BlocksTemplate.addCircle()) - .appendField(i18next.t('BLOCKS_PHASER_ADD_BACKGROUND_IMAGE')) + .appendField(i18next.t('BLOCKS_DEFINE')); + this.appendDummyInput() + .appendField(i18next.t('AS_BACKGROUND')) .appendField( new Blockly.FieldDropdown(() => { return BlocksHelper.phaserImage('bg_01'); @@ -64,6 +66,11 @@ Blocks['phaser_tile_sprite_background'] = { javascriptGenerator.forBlock['phaser_tile_sprite_background'] = function ( block, ) { + const variable = javascriptGenerator.valueToCode( + block, + 'variable', + javascriptGenerator.ORDER_ATOMIC, + ); const scrollFactorX = javascriptGenerator.valueToCode( block, 'x', @@ -75,11 +82,12 @@ javascriptGenerator.forBlock['phaser_tile_sprite_background'] = function ( javascriptGenerator.ORDER_ATOMIC, ); return ` - this.background = this.add.tileSprite(0, 0, this.cameras.main.width, this.cameras.main.height, "${block.getFieldValue( + ${variable} = this.add.tileSprite(0, 0, this.cameras.main.width, this.cameras.main.height, "${block.getFieldValue( 'sprite', )}") .setOrigin(0) .setScrollFactor(${scrollFactorX}, ${scrollFactorY}); + this.helper_.addTileSprite(${variable}); `; }; @@ -144,6 +152,7 @@ javascriptGenerator.forBlock['phaser_tile_sprite_floor_add'] = function ( .setScrollFactor(${scrollFactorX}, ${scrollFactorY}); this.physics.add.existing(${variable}, false); ${variable}.body.immovable = true; + this.helper_.addTileSprite(${variable}); `; }; @@ -209,6 +218,7 @@ javascriptGenerator.forBlock['phaser_tile_sprite_ceiling_add'] = function ( .setScrollFactor(${scrollFactorX}, ${scrollFactorY}); this.physics.add.existing(${variable}, false); ${variable}.body.immovable = true; + this.helper_.addTileSprite(${variable}); `; }; @@ -511,7 +521,10 @@ javascriptGenerator.forBlock['phaser_tile_sprite_autoScroll'] = function ( 'y', javascriptGenerator.ORDER_ATOMIC, ); - return variable + '.autoScroll(' + value_x + ', ' + value_y + ');\n'; + return ` + ${variable}.autoScroll(${value_x}, ${value_y}); + this.helper_.addTileSprite(${variable}); + `; }; /** diff --git a/src/components/GameEditor/blocks/VariableBlocks.js b/src/components/GameEditor/blocks/VariableBlocks.js index f094f03b..1681724b 100644 --- a/src/components/GameEditor/blocks/VariableBlocks.js +++ b/src/components/GameEditor/blocks/VariableBlocks.js @@ -27,85 +27,116 @@ import { BlocksHelper } from './BlocksHelper'; import i18next from 'i18next'; -const reservedPhaserVariables = [ - 'add', - 'anims', - 'cache', - 'cameras', - 'children', - 'create', - 'data', - 'default_group', - 'events', - 'game', - 'helper_', - 'input', - 'lights', - 'load', - 'make', - 'physics', - 'plugins', - 'preload', - 'registry', - 'render', - 'renderer', - 'scale', - 'scene', - 'sound', - 'sys', - 'textures', - 'time', - 'tweens', - 'update', -]; +/** + * Set dynamic arcade_sprite variable + */ +Blocks['phaser_variable_arcade_sprite_set'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_ARCADE_SPRITE')) + .appendField(new Blockly.FieldTextInput('default'), 'VAR'); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + this.setOnChange(() => { + BlocksHelper.checkVariableName(this); + }); + }, +}; /** - * Set dynamic variable + * Set dynamic arcade_sprite variable + * @param {Block} block + * @return {string} */ -Blocks['phaser_variable_set'] = { +javascriptGenerator.forBlock['phaser_variable_arcade_sprite_set'] = function ( + block, +) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Get dynamic arcade_sprite variable + */ +Blocks['phaser_variable_arcade_sprite_get'] = { init: function () { - this.appendDummyInput().appendField( - new Blockly.FieldTextInput('default'), - 'VAR', - ); + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_ARCADE_SPRITE')) + .appendField( + new Blockly.FieldDropdown(() => { + return BlocksHelper.phaserVariable( + this, + 'phaser_variable_arcade_sprite_set', + 'default_arcade_sprite', + 'default_arcade_sprite', + ); + }), + 'VAR', + ); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + }, +}; + +/** + * Get dynamic arcade_sprite variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_arcade_sprite_get'] = function ( + block, +) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Set dynamic audio variable + */ +Blocks['phaser_variable_audio_set'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_AUDIO')) + .appendField(new Blockly.FieldTextInput('default'), 'VAR'); this.setOutput(true, null); this.setColour(330); this.setTooltip(''); this.setHelpUrl(''); this.setOnChange(() => { - const variableName = this.getFieldValue('VAR'); - if (reservedPhaserVariables.includes(variableName)) { - this.setWarningText('Reserved variable name.'); - } else { - this.setWarningText(null); - } + BlocksHelper.checkVariableName(this); }); }, }; /** - * Set dynamic variable + * Set dynamic audio variable * @param {Block} block * @return {string} */ -javascriptGenerator.forBlock['phaser_variable_set'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; +javascriptGenerator.forBlock['phaser_variable_audio_set'] = function (block) { + return BlocksHelper.getVariableName(block); }; /** - * Get dynamic variable + * Get dynamic audio variable */ -Blocks['phaser_variable_get'] = { +Blocks['phaser_variable_audio_get'] = { init: function () { - this.appendDummyInput().appendField( - new Blockly.FieldDropdown(() => { - return BlocksHelper.phaserVariable(this); - }), - 'VAR', - ); + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_AUDIO')) + .appendField( + new Blockly.FieldDropdown(() => { + return BlocksHelper.phaserVariable( + this, + 'phaser_variable_audio_set', + 'default_audio', + 'default_audio', + ); + }), + 'VAR', + ); this.setOutput(true, null); this.setColour(330); this.setTooltip(''); @@ -114,15 +145,12 @@ Blocks['phaser_variable_get'] = { }; /** - * Get dynamic variable + * Get dynamic audio variable * @param {Block} block * @return {string} */ -javascriptGenerator.forBlock['phaser_variable_get'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; +javascriptGenerator.forBlock['phaser_variable_audio_get'] = function (block) { + return BlocksHelper.getVariableName(block); }; /** @@ -138,12 +166,7 @@ Blocks['phaser_variable_group_set'] = { this.setTooltip(''); this.setHelpUrl(''); this.setOnChange(() => { - const variableName = this.getFieldValue('VAR'); - if (reservedPhaserVariables.includes(variableName)) { - this.setWarningText('Reserved variable name.'); - } else { - this.setWarningText(null); - } + BlocksHelper.checkVariableName(this); }); }, }; @@ -154,10 +177,7 @@ Blocks['phaser_variable_group_set'] = { * @return {string} */ javascriptGenerator.forBlock['phaser_variable_group_set'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; + return BlocksHelper.getVariableName(block); }; /** @@ -191,10 +211,133 @@ Blocks['phaser_variable_group_get'] = { * @return {string} */ javascriptGenerator.forBlock['phaser_variable_group_get'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; + return BlocksHelper.getVariableName(block); +}; + +/** + * Set dynamic input variable + */ +Blocks['phaser_variable_input_set'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_INPUT')) + .appendField(new Blockly.FieldTextInput('default'), 'VAR'); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + this.setOnChange(() => { + BlocksHelper.checkVariableName(this); + }); + }, +}; + +/** + * Set dynamic input variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_input_set'] = function (block) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Get dynamic input variable + */ +Blocks['phaser_variable_input_get'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_INPUT')) + .appendField( + new Blockly.FieldDropdown(() => { + return BlocksHelper.phaserVariable( + this, + 'phaser_variable_input_set', + 'default_input', + 'default_input', + ); + }), + 'VAR', + ); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + }, +}; + +/** + * Get dynamic input variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_input_get'] = function (block) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Set dynamic sprite variable + */ +Blocks['phaser_variable_sprite_set'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_SPRITE')) + .appendField(new Blockly.FieldTextInput('default'), 'VAR'); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + this.setOnChange(() => { + BlocksHelper.checkVariableName(this); + }); + }, +}; + +/** + * Set dynamic sprite variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_sprite_set'] = function (block) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Get dynamic sprite variable + */ +Blocks['phaser_variable_sprite_get'] = { + init: function () { + this.appendDummyInput() + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_SPRITE')) + .appendField( + new Blockly.FieldDropdown(() => { + return BlocksHelper.phaserVariables( + this, + [ + 'phaser_variable_sprite_set', + 'phaser_variable_arcade_sprite_set', + 'phaser_variable_tile_sprite_set', + ], + 'default_sprite', + 'default_sprite', + ); + }), + 'VAR', + ); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + }, +}; + +/** + * Get dynamic sprite variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_sprite_get'] = function (block) { + return BlocksHelper.getVariableName(block); }; /** @@ -210,12 +353,7 @@ Blocks['phaser_variable_text_set'] = { this.setTooltip(''); this.setHelpUrl(''); this.setOnChange(() => { - const variableName = this.getFieldValue('VAR'); - if (reservedPhaserVariables.includes(variableName)) { - this.setWarningText('Reserved variable name.'); - } else { - this.setWarningText(null); - } + BlocksHelper.checkVariableName(this); }); }, }; @@ -226,10 +364,7 @@ Blocks['phaser_variable_text_set'] = { * @return {string} */ javascriptGenerator.forBlock['phaser_variable_text_set'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; + return BlocksHelper.getVariableName(block); }; /** @@ -263,61 +398,52 @@ Blocks['phaser_variable_text_get'] = { * @return {string} */ javascriptGenerator.forBlock['phaser_variable_text_get'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; + return BlocksHelper.getVariableName(block); }; /** - * Set dynamic sprite variable + * Set dynamic tile_sprite variable */ -Blocks['phaser_variable_sprite_set'] = { +Blocks['phaser_variable_tile_sprite_set'] = { init: function () { this.appendDummyInput() - .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_SPRITE')) + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_TILE_SPRITE')) .appendField(new Blockly.FieldTextInput('default'), 'VAR'); this.setOutput(true, null); this.setColour(330); this.setTooltip(''); this.setHelpUrl(''); this.setOnChange(() => { - const variableName = this.getFieldValue('VAR'); - if (reservedPhaserVariables.includes(variableName)) { - this.setWarningText('Reserved variable name.'); - } else { - this.setWarningText(null); - } + BlocksHelper.checkVariableName(this); }); }, }; /** - * Set dynamic sprite variable + * Set dynamic tile_sprite variable * @param {Block} block * @return {string} */ -javascriptGenerator.forBlock['phaser_variable_sprite_set'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; +javascriptGenerator.forBlock['phaser_variable_tile_sprite_set'] = function ( + block, +) { + return BlocksHelper.getVariableName(block); }; /** - * Get dynamic sprite variable + * Get dynamic tile_sprite variable */ -Blocks['phaser_variable_sprite_get'] = { +Blocks['phaser_variable_tile_sprite_get'] = { init: function () { this.appendDummyInput() - .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_SPRITE')) + .appendField(i18next.t('BLOCKS_PHASER_VARIABLE_TILE_SPRITE')) .appendField( new Blockly.FieldDropdown(() => { return BlocksHelper.phaserVariable( this, - 'phaser_variable_sprite_set', - 'default_sprite', - 'default_sprite', + 'phaser_variable_tile_sprite_set', + 'default_tile_sprite', + 'default_tile_sprite', ); }), 'VAR', @@ -330,13 +456,67 @@ Blocks['phaser_variable_sprite_get'] = { }; /** - * Get dynamic sprite variable + * Get dynamic tile_sprite variable * @param {Block} block * @return {string} */ -javascriptGenerator.forBlock['phaser_variable_sprite_get'] = function (block) { - const variable = block.getFieldValue('VAR').startsWith('this') - ? block.getFieldValue('VAR') - : 'this.' + block.getFieldValue('VAR'); - return [variable, javascriptGenerator.ORDER_ATOMIC]; +javascriptGenerator.forBlock['phaser_variable_tile_sprite_get'] = function ( + block, +) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Set dynamic variable + */ +Blocks['phaser_variable_set'] = { + init: function () { + this.appendDummyInput().appendField( + new Blockly.FieldTextInput('default'), + 'VAR', + ); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + this.setOnChange(() => { + BlocksHelper.checkVariableName(this); + }); + }, +}; + +/** + * Set dynamic variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_set'] = function (block) { + return BlocksHelper.getVariableName(block); +}; + +/** + * Get dynamic variable + */ +Blocks['phaser_variable_get'] = { + init: function () { + this.appendDummyInput().appendField( + new Blockly.FieldDropdown(() => { + return BlocksHelper.phaserVariable(this); + }), + 'VAR', + ); + this.setOutput(true, null); + this.setColour(330); + this.setTooltip(''); + this.setHelpUrl(''); + }, +}; + +/** + * Get dynamic variable + * @param {Block} block + * @return {string} + */ +javascriptGenerator.forBlock['phaser_variable_get'] = function (block) { + return BlocksHelper.getVariableName(block); }; diff --git a/src/components/GameEditor/toolbox/ArcadePhysicsToolbox.js b/src/components/GameEditor/toolbox/ArcadePhysicsToolbox.js index ee254d55..8f041a97 100644 --- a/src/components/GameEditor/toolbox/ArcadePhysicsToolbox.js +++ b/src/components/GameEditor/toolbox/ArcadePhysicsToolbox.js @@ -30,7 +30,7 @@ export const createBlocks = [ blockxml: ` - + ball @@ -87,7 +87,7 @@ export const createBlocks = [ blockxml: ` - + player @@ -111,7 +111,7 @@ export const createBlocks = [ blockxml: ` - + paddle @@ -179,7 +179,7 @@ export const createBlocks = [ blockxml: ` - + player @@ -196,7 +196,7 @@ export const createBlocks = [ blockxml: ` - + ball @@ -210,7 +210,7 @@ export const defaultBlocks = [ blockxml: ` - + player @@ -224,7 +224,7 @@ export const defaultBlocks = [ blockxml: ` - + player @@ -241,7 +241,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -252,7 +252,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -263,7 +263,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -277,7 +277,7 @@ export const eventBlocks = [ blockxml: ` - + ball @@ -289,8 +289,8 @@ export const eventBlocks = [ - - object2 + + sprite_object @@ -302,7 +302,7 @@ export const eventBlocks = [ blockxml: ` - + player @@ -318,12 +318,12 @@ export const eventBlocks = [ blockxml: ` - + player - + coin @@ -334,12 +334,12 @@ export const eventBlocks = [ blockxml: ` - + ball - + paddle @@ -350,17 +350,33 @@ export const eventBlocks = [ blockxml: ` - + player - + floor `, }, + { + kind: 'block', + blockxml: ` + + + + player + + + + + ceiling + + + `, + }, ]; export default { diff --git a/src/components/GameEditor/toolbox/AudioToolbox.js b/src/components/GameEditor/toolbox/AudioToolbox.js index 388a2dc2..0cc208d5 100644 --- a/src/components/GameEditor/toolbox/AudioToolbox.js +++ b/src/components/GameEditor/toolbox/AudioToolbox.js @@ -30,7 +30,7 @@ export const createBlocks = [ blockxml: ` - + bgm @@ -42,7 +42,7 @@ export const createBlocks = [ blockxml: ` - + sound_effect @@ -60,7 +60,7 @@ export const defaultBlocks = [ blockxml: ` - + sound_effect @@ -71,7 +71,7 @@ export const defaultBlocks = [ blockxml: ` - + sound_effect @@ -82,7 +82,7 @@ export const defaultBlocks = [ blockxml: ` - + sound_effect @@ -93,7 +93,7 @@ export const defaultBlocks = [ blockxml: ` - + sound_effect diff --git a/src/components/GameEditor/toolbox/EventToolbox.js b/src/components/GameEditor/toolbox/EventToolbox.js new file mode 100644 index 00000000..2fc10568 --- /dev/null +++ b/src/components/GameEditor/toolbox/EventToolbox.js @@ -0,0 +1,42 @@ +/** + * @license Copyright 2020 The Coding with Chrome Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Event Phaser Toolbox. + * @author mbordihn@google.com (Markus Bordihn) + */ + +import '../blocks/EventBlocks.js'; + +/** + * @type {array} + */ +export const createBlocks = []; + +/** + * @type {array} + */ +export const defaultBlocks = [ + { + kind: 'block', + type: 'phaser_event', + }, +]; + +export default { + createBlocks, + defaultBlocks, +}; diff --git a/src/components/GameEditor/toolbox/GameToolbox.js b/src/components/GameEditor/toolbox/GameToolbox.js index 0aa91944..b91ca777 100644 --- a/src/components/GameEditor/toolbox/GameToolbox.js +++ b/src/components/GameEditor/toolbox/GameToolbox.js @@ -36,13 +36,17 @@ export default [ - - - - - - - + + + + + + + + + + + diff --git a/src/components/GameEditor/toolbox/InputToolbox.js b/src/components/GameEditor/toolbox/InputToolbox.js index 953efad1..52e03399 100644 --- a/src/components/GameEditor/toolbox/InputToolbox.js +++ b/src/components/GameEditor/toolbox/InputToolbox.js @@ -30,7 +30,7 @@ export const createBlocks = [ blockxml: ` - + cursor_keys @@ -41,7 +41,7 @@ export const createBlocks = [ blockxml: ` - + spacebar @@ -52,7 +52,7 @@ export const createBlocks = [ blockxml: ` - + wasd_keys @@ -63,7 +63,7 @@ export const createBlocks = [ blockxml: ` - + shift_keys @@ -74,7 +74,7 @@ export const createBlocks = [ blockxml: ` - + keyboard_key @@ -85,7 +85,7 @@ export const createBlocks = [ blockxml: ` - + mouse_keys @@ -106,7 +106,7 @@ export const eventBlocks = [ - + spacebar @@ -115,7 +115,7 @@ export const eventBlocks = [ - + player @@ -142,7 +142,7 @@ export const eventBlocks = [ .left - + cursor_keys @@ -151,7 +151,7 @@ export const eventBlocks = [ - + paddle @@ -167,7 +167,7 @@ export const eventBlocks = [ .right - + cursor_keys @@ -176,7 +176,7 @@ export const eventBlocks = [ - + paddle @@ -191,7 +191,7 @@ export const eventBlocks = [ - + paddle @@ -218,7 +218,7 @@ export const eventBlocks = [ ShiftLeft - + shift_keys @@ -227,7 +227,7 @@ export const eventBlocks = [ - + player @@ -243,7 +243,7 @@ export const eventBlocks = [ ShiftRight - + shift_keys @@ -252,7 +252,7 @@ export const eventBlocks = [ - + player2 @@ -280,7 +280,7 @@ export const defaultBlocks = [ up.isDown - + cursor_keys @@ -292,7 +292,7 @@ export const defaultBlocks = [ up.isDown - + cursor_keys @@ -303,7 +303,7 @@ export const defaultBlocks = [ blockxml: ` - + spacebar @@ -314,7 +314,7 @@ export const defaultBlocks = [ blockxml: ` - + spacebar @@ -326,7 +326,7 @@ export const defaultBlocks = [ leftButton.isDown - + mouse_keys @@ -338,7 +338,7 @@ export const defaultBlocks = [ leftButton.isDown - + mouse_keys @@ -352,7 +352,7 @@ export const defaultBlocks = [ - + spacebar @@ -369,7 +369,7 @@ export const defaultBlocks = [ .up - + cursor_keys @@ -379,7 +379,7 @@ export const defaultBlocks = [ .down - + cursor_keys @@ -389,7 +389,7 @@ export const defaultBlocks = [ .left - + cursor_keys @@ -399,7 +399,7 @@ export const defaultBlocks = [ .right - + cursor_keys @@ -416,7 +416,7 @@ export const defaultBlocks = [ leftButton.isDown - + mouse_keys diff --git a/src/components/GameEditor/toolbox/RenderToolbox.js b/src/components/GameEditor/toolbox/RenderToolbox.js index b4527ab6..e1794726 100644 --- a/src/components/GameEditor/toolbox/RenderToolbox.js +++ b/src/components/GameEditor/toolbox/RenderToolbox.js @@ -40,7 +40,7 @@ export default [ blockxml: ` - + sprite diff --git a/src/components/GameEditor/toolbox/SpriteToolbox.js b/src/components/GameEditor/toolbox/SpriteToolbox.js index 094ef036..49b5d04e 100644 --- a/src/components/GameEditor/toolbox/SpriteToolbox.js +++ b/src/components/GameEditor/toolbox/SpriteToolbox.js @@ -31,7 +31,7 @@ export const createBlocks = [ blockxml: ` - + sprite @@ -54,7 +54,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -68,7 +68,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -85,7 +85,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -96,7 +96,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -107,7 +107,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite diff --git a/src/components/GameEditor/toolbox/TileSpriteToolbox.js b/src/components/GameEditor/toolbox/TileSpriteToolbox.js index 65123304..604f1fa3 100644 --- a/src/components/GameEditor/toolbox/TileSpriteToolbox.js +++ b/src/components/GameEditor/toolbox/TileSpriteToolbox.js @@ -29,6 +29,11 @@ export const createBlocks = [ kind: 'block', blockxml: ` + + + background + + 1 @@ -42,7 +47,7 @@ export const createBlocks = [ blockxml: ` - + floor @@ -59,7 +64,7 @@ export const createBlocks = [ blockxml: ` - + ceiling @@ -76,7 +81,7 @@ export const createBlocks = [ blockxml: ` - + tile_sprite @@ -93,7 +98,7 @@ export const createBlocks = [ blockxml: ` - + blocks @@ -110,7 +115,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -124,7 +129,7 @@ export const defaultBlocks = [ blockxml: ` - + sprite @@ -135,7 +140,7 @@ export const defaultBlocks = [ blockxml: ` - + blocks @@ -152,7 +157,7 @@ export const defaultBlocks = [ blockxml: ` - + blocks diff --git a/src/components/GameEditor/toolbox/Toolbox.js b/src/components/GameEditor/toolbox/Toolbox.js index 751621e8..60b0831a 100644 --- a/src/components/GameEditor/toolbox/Toolbox.js +++ b/src/components/GameEditor/toolbox/Toolbox.js @@ -23,6 +23,7 @@ import ArcadePhysicsToolbox from './ArcadePhysicsToolbox'; import AudioToolbox from './AudioToolbox'; import CreateToolbox from './CreateToolbox'; import DynamicFilesToolbox from './DynamicFilesToolbox'; +import EventToolbox from './EventToolbox'; import ExampleFilesToolbox from './ExampleFilesToolbox'; import GameToolbox from './GameToolbox'; import GeneratorToolbox from './GeneratorToolbox'; @@ -338,6 +339,28 @@ export class Toolbox { }, ]), }, + { + kind: 'category', + name: i18next.t('BLOCKS_PHASER_EVENT'), + colour: '315', + cssConfig: { + container: 'icon_repeat blocklyTreeRoot', + }, + expanded: 'false', + contents: EventToolbox.defaultBlocks.concat([ + { + kind: 'category', + name: i18next.t('BLOCKS_PHASER_PHYSICS_SPRITE'), + colour: '0', + cssConfig: { + container: 'icon_rotate_90_degrees_ccw blocklyTreeChild', + }, + contents: ArcadePhysicsToolbox.defaultBlocks.concat( + ArcadePhysicsToolbox.eventBlocks, + ), + }, + ]), + }, { kind: 'category', name: i18next.t('BLOCKS_PHASER_UPDATE'), diff --git a/src/components/GameEditor/toolbox/WorldToolbox.js b/src/components/GameEditor/toolbox/WorldToolbox.js index 108e00f9..abaf468d 100644 --- a/src/components/GameEditor/toolbox/WorldToolbox.js +++ b/src/components/GameEditor/toolbox/WorldToolbox.js @@ -67,7 +67,7 @@ export const updateBlocks = [ blockxml: ` - + sprite diff --git a/src/frameworks/phaser/phaser_extras.js b/src/frameworks/phaser/phaser_extras.js index 81ffc29a..1ffa9518 100644 --- a/src/frameworks/phaser/phaser_extras.js +++ b/src/frameworks/phaser/phaser_extras.js @@ -58,15 +58,29 @@ class PhaserExtras { */ static addGroupSprite(game, x, y, sprite_name, group, manipulation) { const sprite = game.physics.add.sprite(x, y, sprite_name); - if (group) { - group.add(sprite); - } - sprite['checkWorldBounds'] = true; - sprite['outOfBoundsKill'] = true; - sprite['z'] = 100; + sprite.z = 100; if (manipulation && typeof manipulation === 'function') { manipulation(sprite); } + + if (group) { + group.add(sprite); + + // Cleanup group sprites, if we have to many sprites outside of screen. + if (group.getLength() > 50) { + group.children.each((sprite) => { + if ( + !sprite.active || + sprite.y < 0 || + sprite.y > 2000 || + sprite.x < 0 || + sprite.x > 2000 + ) { + group.remove(sprite, true, true); + } + }); + } + } } /** @@ -109,7 +123,7 @@ class PhaserExtras { } PhaserExtras.addGroupSprite( game, - x, + x + spriteSize.width, y + i * spriteSize.height, groupSprite, group, @@ -226,13 +240,13 @@ class PhaserExtras { let height = texture?.source?.[0]?.height; if (!width || !height || manipulation) { const testSprite = game.physics.add.sprite(0, 0, sprite); - testSprite['visible'] = false; + testSprite.visible = false; if (manipulation && typeof manipulation == 'function') { manipulation(testSprite); } width = testSprite.width; height = testSprite.height; - testSprite['destroy'](); + testSprite.destroy(); } return { width: width, @@ -311,6 +325,38 @@ class PhaserExtras { ); } } + + /** + * Sends error to the main window. + * @param {Object} error + */ + static sendError(error) { + if (error && window.parent) { + window.parent.postMessage( + { + type: 'error', + value: error, + }, + `${window.location.origin}`, + ); + } + } + + /** + * Sends runtime error to the main window. + * @param {Object} error + */ + static sendRuntimeError(error) { + if (error && window.parent) { + window.parent.postMessage( + { + type: 'runtime_error', + value: error, + }, + `${window.location.origin}`, + ); + } + } } // Clear any existing fragments when the page is loaded. @@ -318,6 +364,14 @@ document.addEventListener('DOMContentLoaded', function () { new PhaserExtras().clear(); }); +// Capture errors and send them to the main window. +window.error = function (message, source, lineno, colno, error) { + PhaserExtras.sendRuntimeError(error); +}; +document.addEventListener('error', function (event) { + PhaserExtras.sendError(event); +}); + // Send a screenshot after 500ms when the page is loaded. if (window.location.pathname.endsWith('/screenshot')) { window.addEventListener('load', function () { diff --git a/src/frameworks/phaser/phaser_extras.min.js b/src/frameworks/phaser/phaser_extras.min.js index 05fb4c9e..8478c0a6 100644 --- a/src/frameworks/phaser/phaser_extras.min.js +++ b/src/frameworks/phaser/phaser_extras.min.js @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -class PhaserExtras{clear(){var canvasElements=document.getElementsByTagName("canvas");if(canvasElements)for(const canvasElement of canvasElements)canvasElement.style&&"none"==canvasElement.style.touchAction&&"none"==canvasElement.style.userSelect&&canvasElement.remove();document.getElementById("ghostery-tracker-tally")?.remove(),document.getElementById("ghostery-box")?.remove(),document.getElementById("ghostery-pb-background")?.remove()}static addGroupSprite(game,x,y,sprite_name,group,manipulation){game=game.physics.add.sprite(x,y,sprite_name);group&&group.add(game),game.checkWorldBounds=!0,game.outOfBoundsKill=!0,game.z=100,manipulation&&"function"==typeof manipulation&&manipulation(game)}static VerticalObstacleGenerator(game,x,y,num_blocks,space,sprite,opt_sprite_top,opt_sprite_bottom,group,manipulation){var spriteSize=PhaserExtras.getSpriteSize(game,sprite,manipulation),spriteSpace=Phaser.Math.RND.integerInRange(0,num_blocks-space-1);for(let i=0;i=spriteSpace+space){let groupSprite=sprite;i==spriteSpace+space&&opt_sprite_bottom?groupSprite=opt_sprite_bottom:i==spriteSpace-1&&opt_sprite_top&&(groupSprite=opt_sprite_top),PhaserExtras.addGroupSprite(game,x,y+i*spriteSize.height,groupSprite,group,manipulation)}}static RandomVerticalObstacleGenerator(game,x,y,num_blocks,sprite,opt_sprite,group,direction,manipulation){var spriteSize=PhaserExtras.getSpriteSize(game,sprite,manipulation),numBlocks=Phaser.Math.RND.integerInRange(0,num_blocks);"top"===direction&&(y-=spriteSize.height);for(let i=1;i<=numBlocks;i++)"top"===direction?PhaserExtras.addGroupSprite(game,x,y+i*spriteSize.height,opt_sprite&&i===numBlocks?opt_sprite:sprite,group,manipulation):PhaserExtras.addGroupSprite(game,x,y-i*spriteSize.height,opt_sprite&&i===numBlocks?opt_sprite:sprite,group,manipulation)}static MatrixBlockGenerator(game,sprite,data,x=0,y=0,padding=10,group,manipulation){let index=0;var blockX,blockY,spriteSize=PhaserExtras.getSpriteSize(game,sprite,manipulation),spriteWidthFactor=spriteSize.width+padding,spriteHeightFactor=spriteSize.height+padding;for(let row=0;row<=7;row++)for(let column=0;column<=7;column++)data[index++]&&(blockX=column*spriteWidthFactor+x,blockY=row*spriteHeightFactor+y,PhaserExtras.addGroupSprite(game,blockX,blockY,sprite,group,manipulation))}static getSpriteSize(game,sprite,manipulation){var texture=game.textures.get(sprite);let width=texture?.source?.[0]?.width,height=texture?.source?.[0]?.height;return width&&height&&!manipulation||((texture=game.physics.add.sprite(0,0,sprite)).visible=!1,manipulation&&"function"==typeof manipulation&&manipulation(texture),width=texture.width,height=texture.height,texture.destroy()),{width:width,height:height}}static takeScreenshot(game){if(game&&game.canvas){let width=game.canvas.width,height=game.canvas.height;width/height>270/152?(width=270,height=width/game.canvas.width*game.canvas.height):(height=152,width=height/game.canvas.height*game.canvas.width);var preview=document.createElement("canvas"),ctx=(preview.width=270,preview.height=152,preview.getContext("2d"));return ctx.fillStyle="rgba(0, 0, 0, 0)",ctx.fillRect(0,0,preview.width,preview.height),ctx.drawImage(game.canvas,0,0,game.canvas.width,game.canvas.height,(270-width)/2,(152-height)/2,width,height),preview.toDataURL()}console.warn("Unable to take screenshot for ",game,"!")}static showScreenshot(game){var image=new Image;image.src=PhaserExtras.takeScreenshot(game),window.open("").document.write(image.outerHTML)}static sendScreenshot(game){game=PhaserExtras.takeScreenshot(game);game&&window.parent&&window.parent.postMessage({type:"screenshot",value:game},""+window.location.origin)}}document.addEventListener("DOMContentLoaded",function(){(new PhaserExtras).clear()}),window.location.pathname.endsWith("/screenshot")&&window.addEventListener("load",function(){window.setTimeout(()=>{PhaserExtras.sendScreenshot(window.game)},750)}); \ No newline at end of file +class PhaserExtras{clear(){var canvasElements=document.getElementsByTagName("canvas");if(canvasElements)for(const canvasElement of canvasElements)canvasElement.style&&"none"==canvasElement.style.touchAction&&"none"==canvasElement.style.userSelect&&canvasElement.remove();document.getElementById("ghostery-tracker-tally")?.remove(),document.getElementById("ghostery-box")?.remove(),document.getElementById("ghostery-pb-background")?.remove()}static addGroupSprite(game,x,y,sprite_name,group,manipulation){game=game.physics.add.sprite(x,y,sprite_name);game.z=100,manipulation&&"function"==typeof manipulation&&manipulation(game),group&&(group.add(game),50{(!sprite.active||sprite.y<0||2e3=spriteSpace+space){let groupSprite=sprite;i==spriteSpace+space&&opt_sprite_bottom?groupSprite=opt_sprite_bottom:i==spriteSpace-1&&opt_sprite_top&&(groupSprite=opt_sprite_top),PhaserExtras.addGroupSprite(game,x+spriteSize.width,y+i*spriteSize.height,groupSprite,group,manipulation)}}static RandomVerticalObstacleGenerator(game,x,y,num_blocks,sprite,opt_sprite,group,direction,manipulation){var spriteSize=PhaserExtras.getSpriteSize(game,sprite,manipulation),numBlocks=Phaser.Math.RND.integerInRange(0,num_blocks);"top"===direction&&(y-=spriteSize.height);for(let i=1;i<=numBlocks;i++)"top"===direction?PhaserExtras.addGroupSprite(game,x,y+i*spriteSize.height,opt_sprite&&i===numBlocks?opt_sprite:sprite,group,manipulation):PhaserExtras.addGroupSprite(game,x,y-i*spriteSize.height,opt_sprite&&i===numBlocks?opt_sprite:sprite,group,manipulation)}static MatrixBlockGenerator(game,sprite,data,x=0,y=0,padding=10,group,manipulation){let index=0;var blockX,blockY,spriteSize=PhaserExtras.getSpriteSize(game,sprite,manipulation),spriteWidthFactor=spriteSize.width+padding,spriteHeightFactor=spriteSize.height+padding;for(let row=0;row<=7;row++)for(let column=0;column<=7;column++)data[index++]&&(blockX=column*spriteWidthFactor+x,blockY=row*spriteHeightFactor+y,PhaserExtras.addGroupSprite(game,blockX,blockY,sprite,group,manipulation))}static getSpriteSize(game,sprite,manipulation){var texture=game.textures.get(sprite);let width=texture?.source?.[0]?.width,height=texture?.source?.[0]?.height;return width&&height&&!manipulation||((texture=game.physics.add.sprite(0,0,sprite)).visible=!1,manipulation&&"function"==typeof manipulation&&manipulation(texture),width=texture.width,height=texture.height,texture.destroy()),{width:width,height:height}}static takeScreenshot(game){if(game&&game.canvas){let width=game.canvas.width,height=game.canvas.height;width/height>270/152?(width=270,height=width/game.canvas.width*game.canvas.height):(height=152,width=height/game.canvas.height*game.canvas.width);var preview=document.createElement("canvas"),ctx=(preview.width=270,preview.height=152,preview.getContext("2d"));return ctx.fillStyle="rgba(0, 0, 0, 0)",ctx.fillRect(0,0,preview.width,preview.height),ctx.drawImage(game.canvas,0,0,game.canvas.width,game.canvas.height,(270-width)/2,(152-height)/2,width,height),preview.toDataURL()}console.warn("Unable to take screenshot for ",game,"!")}static showScreenshot(game){var image=new Image;image.src=PhaserExtras.takeScreenshot(game),window.open("").document.write(image.outerHTML)}static sendScreenshot(game){game=PhaserExtras.takeScreenshot(game);game&&window.parent&&window.parent.postMessage({type:"screenshot",value:game},""+window.location.origin)}static sendError(error){error&&window.parent&&window.parent.postMessage({type:"error",value:error},""+window.location.origin)}static sendRuntimeError(error){error&&window.parent&&window.parent.postMessage({type:"runtime_error",value:error},""+window.location.origin)}}document.addEventListener("DOMContentLoaded",function(){(new PhaserExtras).clear()}),window.error=function(message,source,lineno,colno,error){PhaserExtras.sendRuntimeError(error)},document.addEventListener("error",function(event){PhaserExtras.sendError(event)}),window.location.pathname.endsWith("/screenshot")&&window.addEventListener("load",function(){window.setTimeout(()=>{PhaserExtras.sendScreenshot(window.game)},750)}); \ No newline at end of file diff --git a/src/frameworks/phaser/phaser_helper.js b/src/frameworks/phaser/phaser_helper.js index bc0276ad..e91d4b29 100644 --- a/src/frameworks/phaser/phaser_helper.js +++ b/src/frameworks/phaser/phaser_helper.js @@ -30,6 +30,30 @@ class PhaserHelper { */ constructor(game) { this.game = game; + this.sprite = new Set(); + this.tileSprite = new Set(); + this.arcadeSprite = new Set(); + } + + /** + * @param {object} sprite + */ + addSprite(sprite) { + this.sprite.add(sprite); + } + + /** + * @param {object} tileSprite + */ + addTileSprite(tileSprite) { + this.tileSprite.add(tileSprite); + } + + /** + * @param {object} arcadeSprite + */ + addArcadeSprite(arcadeSprite) { + this.arcadeSprite.add(arcadeSprite); } /** @@ -51,16 +75,16 @@ class PhaserHelper { return; } - // Automatically scroll the background, ceiling, and floor. - PhaserHelper.scrollTilePosition(this.game.background); - PhaserHelper.scrollTilePosition(this.game.ceiling); - PhaserHelper.scrollTilePosition(this.game.floor); + // Automatically scroll tile sprites, if any. + this.tileSprite.forEach((tileSprite) => { + PhaserHelper.scrollTileSprite(tileSprite); + }); } /** * @param {Object} tileObject */ - static scrollTilePosition(tileObject) { + static scrollTileSprite(tileObject) { if (!tileObject) { return; } diff --git a/src/frameworks/phaser/phaser_helper.min.js b/src/frameworks/phaser/phaser_helper.min.js index 3dc303b7..65edc539 100644 --- a/src/frameworks/phaser/phaser_helper.min.js +++ b/src/frameworks/phaser/phaser_helper.min.js @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -class PhaserHelper{constructor(game){this.game=game}handleInput(){this.game&&this.game.input_&&this.game.input_()}handleUpdate(){this.game&&(PhaserHelper.scrollTilePosition(this.game.background),PhaserHelper.scrollTilePosition(this.game.ceiling),PhaserHelper.scrollTilePosition(this.game.floor))}static scrollTilePosition(tileObject){tileObject&&(tileObject.scrollFactorX&&(tileObject.tilePositionX+=tileObject.scrollFactorX),tileObject.scrollFactorY)&&(tileObject.tilePositionY+=tileObject.scrollFactorY)}} \ No newline at end of file +class PhaserHelper{constructor(game){this.game=game,this.sprite=new Set,this.tileSprite=new Set,this.arcadeSprite=new Set}addSprite(sprite){this.sprite.add(sprite)}addTileSprite(tileSprite){this.tileSprite.add(tileSprite)}addArcadeSprite(arcadeSprite){this.arcadeSprite.add(arcadeSprite)}handleInput(){this.game&&this.game.input_&&this.game.input_()}handleUpdate(){this.game&&this.tileSprite.forEach(tileSprite=>{PhaserHelper.scrollTileSprite(tileSprite)})}static scrollTileSprite(tileObject){tileObject&&(tileObject.scrollFactorX&&(tileObject.tilePositionX+=tileObject.scrollFactorX),tileObject.scrollFactorY)&&(tileObject.tilePositionY+=tileObject.scrollFactorY)}} \ No newline at end of file