diff --git a/js/module.js b/js/module.js index d408b92..8ea1e71 100644 --- a/js/module.js +++ b/js/module.js @@ -26,7 +26,7 @@ class ImageLoader { image.addEventListener( 'load', () => { - this.update();1 + this.update(); } ); @@ -133,7 +133,8 @@ const FRAME_DURATION = 1000 / FPS; const GAME_SPEED = 1; const GRAVITY = 2; -let levelJson = new FileLoader('levels/level.json'); +let levelJson = new FileLoader('levels/test_stairs.json'); +console.log(levelJson.getContent()); const LEVEL = levelJson.getContent(); let lastRendered = undefined; diff --git a/tilorswift/js/Tilorswift.js b/tilorswift/js/Tilorswift.js new file mode 100644 index 0000000..8ecacdb --- /dev/null +++ b/tilorswift/js/Tilorswift.js @@ -0,0 +1,40 @@ +export default class Tilorswift +{ + static getTerrainAsJson(terrain) + { + let matrix = []; + + for (let y = 0; y < terrain.fields.length; y++) { + let row = []; + + for (let x = 0; x < terrain.fields[y].length; x++) { + row.push(terrain.fields[y][x].index); + } + + matrix.push(row); + } + + let data = { + tileset: terrain.tileset.image.src, + tiles: terrain.tileset.tiles, + scale: terrain.tileset.scale, + rows: terrain.tilesY, + columns: terrain.tilesX, + backgroundColor: terrain.backgroundColor, + matrix: matrix, + }; + + return JSON.stringify(data); + } + + static saveTerrainToFile(terrain) + { + let json = Tilorswift.getTerrainAsJson(terrain); + let download = document.createElement('a'); + + download.setAttribute('download', 'terrain.json'); + download.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(json)); + download.click(); + download.remove(); + } +} \ No newline at end of file diff --git a/tilorswift/js/events/TilorswiftEvent.js b/tilorswift/js/events/TilorswiftEvent.js index e5f6aba..e48f1c0 100644 --- a/tilorswift/js/events/TilorswiftEvent.js +++ b/tilorswift/js/events/TilorswiftEvent.js @@ -2,6 +2,8 @@ const TilorswiftEvent = { FIELD_CLICKED: 'fieldClicked', FIELD_ENTERED: 'fieldEntered', BUTTON_TILE_CLICKED: 'buttonTileClicked', + MENU_SAVE_CLICKED: 'menuSaveClicked', + SAVED: 'saved', }; export default TilorswiftEvent; \ No newline at end of file diff --git a/tilorswift/js/events/TilorswiftFieldClickedEvent.js b/tilorswift/js/events/TilorswiftFieldClickedEvent.js index 26b5e20..1787e95 100644 --- a/tilorswift/js/events/TilorswiftFieldClickedEvent.js +++ b/tilorswift/js/events/TilorswiftFieldClickedEvent.js @@ -4,7 +4,6 @@ export default class TilorswiftFieldClickedEvent extends Event { constructor(field, button) { - console.log('So kommt der Scheiß hier rein: ' + button); super(TilorswiftEvent.FIELD_CLICKED); this.field = field; diff --git a/tilorswift/js/events/TilorswiftMenuSaveClickedEvent.js b/tilorswift/js/events/TilorswiftMenuSaveClickedEvent.js new file mode 100644 index 0000000..ec54feb --- /dev/null +++ b/tilorswift/js/events/TilorswiftMenuSaveClickedEvent.js @@ -0,0 +1,9 @@ +import TilorswiftEvent from "./TilorswiftEvent.js"; + +export default class TilorswiftMenuSaveClickedEvent extends Event +{ + constructor() + { + super(TilorswiftEvent.MENU_SAVE_CLICKED); + } +} \ No newline at end of file diff --git a/tilorswift/js/events/TilorswiftSavedEvent.js b/tilorswift/js/events/TilorswiftSavedEvent.js new file mode 100644 index 0000000..bafd904 --- /dev/null +++ b/tilorswift/js/events/TilorswiftSavedEvent.js @@ -0,0 +1,8 @@ +import TilorswiftEvent from "./TilorswiftEvent.js"; + +export default class TilorswiftSavedEvent extends Event +{ + constructor() { + super(TilorswiftEvent.SAVED); + } +} \ No newline at end of file diff --git a/tilorswift/js/menu/MainMenu.js b/tilorswift/js/menu/MainMenu.js new file mode 100644 index 0000000..797a55a --- /dev/null +++ b/tilorswift/js/menu/MainMenu.js @@ -0,0 +1,27 @@ +export default class MainMenu +{ + constructor(id) + { + this.id = id; + this.menuGroups = []; + } + + addMenuGroup(group) + { + this.menuGroups.push(group); + } + + getElement() + { + let htmlElement = document.createElement('div'); + htmlElement.id = this.id; + + this.menuGroups.forEach( + (group) =>{ + htmlElement.appendChild(group.getElement()); + } + ); + + return htmlElement; + } +} \ No newline at end of file diff --git a/tilorswift/js/menu/MainMenuEntry.js b/tilorswift/js/menu/MainMenuEntry.js new file mode 100644 index 0000000..ded66f3 --- /dev/null +++ b/tilorswift/js/menu/MainMenuEntry.js @@ -0,0 +1,22 @@ +export default class MainMenuEntry +{ + constructor(title, event) + { + this.title = title; + this.event = event; + } + + getElement() + { + let htmlElement = document.createElement('li'); + htmlElement.innerText = this.title; + htmlElement.addEventListener( + 'click', + () => { + window.dispatchEvent(new this.event()); + } + ); + + return htmlElement; + } +} \ No newline at end of file diff --git a/tilorswift/js/menu/MenuGroup.js b/tilorswift/js/menu/MenuGroup.js new file mode 100644 index 0000000..aa9fbca --- /dev/null +++ b/tilorswift/js/menu/MenuGroup.js @@ -0,0 +1,34 @@ +export default class MenuGroup +{ + className = 'menu-group'; + + constructor(title) + { + this.title = title; + this.menuEntries = []; + } + + addMenuEntry(entry) + { + this.menuEntries.push(entry); + } + + getElement() + { + let htmlElement = document.createElement('div'); + htmlElement.classList.add(this.className); + htmlElement.innerText = this.title; + + let dropdown = document.createElement('ul'); + dropdown.classList.add('menu-dropdown'); + htmlElement.appendChild(dropdown); + + this.menuEntries.forEach( + (entry) => { + dropdown.appendChild(entry.getElement()); + } + ); + + return htmlElement; + } +} \ No newline at end of file diff --git a/tilorswift/js/module.js b/tilorswift/js/module.js index 9925c28..ea23d74 100644 --- a/tilorswift/js/module.js +++ b/tilorswift/js/module.js @@ -4,6 +4,12 @@ import TilorswiftEvent from "./events/TilorswiftEvent.js"; import Mouse from "./Mouse.js"; import Tileset from "./Tileset.js"; import ButtonTile from "./ButtonTile.js"; +import Tilorswift from "./Tilorswift.js"; +import TilorswiftSavedEvent from "./events/TilorswiftSavedEvent.js"; +import MainMenu from "./menu/MainMenu.js"; +import MenuGroup from "./menu/MenuGroup.js"; +import MainMenuEntry from "./menu/MainMenuEntry.js"; +import TilorswiftMenuSaveClickedEvent from "./events/TilorswiftMenuSaveClickedEvent.js"; let loader = new FileLoader('../levels/level.json'); @@ -26,6 +32,17 @@ image.onload = function () { let mouse = new Mouse(); + let mainbar = new MainMenu('mainbar'); + + let menuFile = new MenuGroup('Datei'); + menuFile.addMenuEntry( + new MainMenuEntry('Speichern', TilorswiftMenuSaveClickedEvent) + ); + + mainbar.addMenuGroup(menuFile); + + document.body.appendChild(mainbar.getElement()); + window.addEventListener( TilorswiftEvent.FIELD_CLICKED, (event) => { @@ -58,4 +75,28 @@ image.onload = function () { } } ); + + document.addEventListener( + 'dragstart', + function (event) { + event.preventDefault(); + } + ); + + window.addEventListener( + 'keydown', function (event) { + if (event.code === 'KeyS') { + Tilorswift.saveTerrainToFile(terrain); + window.dispatchEvent(new TilorswiftSavedEvent()); + } + } + ); + + window.addEventListener( + TilorswiftEvent.MENU_SAVE_CLICKED, + function () { + Tilorswift.saveTerrainToFile(terrain); + window.dispatchEvent(new TilorswiftSavedEvent()); + } + ); }; diff --git a/tilorswift/style.css b/tilorswift/style.css index d3be950..abf1479 100644 --- a/tilorswift/style.css +++ b/tilorswift/style.css @@ -1,3 +1,8 @@ +@keyframes menuFadeIn { + from { width: 96px; } + to { width: 512px; } +} + body { padding: 0; margin: 0; @@ -9,26 +14,82 @@ body { border-collapse: collapse; } -.row { +#mainbar { + display: flex; + position: fixed; + top: 0; + left: 0; + right: 0; + height: 32px; + background-color: #cccccc; + box-shadow: 0 0 20px black; +} + +.menu-group { + position: relative; + display: inline-block; + cursor: pointer; + padding: 5px 20px; + overflow: visible; + font-family: sans-serif; +} + +.menu-group:hover { + background-color: #5555cc; +} + +.menu-dropdown { + display: none; + position: absolute; + top: 16px; + left: 0; + background-color: #cccccc; + list-style: none; + box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5); + padding-left: 0; +} + +.menu-dropdown > li { + padding: 5px 20px; + width: 180px; +} + +.menu-dropdown > li:hover { + background-color: #5555cc; +} + +.menu-group:hover > .menu-dropdown { + display: block; } #menu { position: fixed; - top: 0; + display: flex; + flex-flow: wrap row; + top: 32px; left: 0; bottom: 0; + padding-top: 20px; width: 96px; - background-color: grey; + overflow: hidden; + background-color: #cccccc; box-shadow: 0 0 20px black; } +#menu:hover { + animation-name: menuFadeIn; + animation-duration: 0.5s; + width: 512px; +} + #map { position: fixed; - top: 0; + top: 32px; left: 96px; right: 0; bottom: 0; overflow: scroll; + background-color: black; } .field, .button-tile { @@ -37,6 +98,7 @@ body { margin: 0; background-repeat: no-repeat; cursor: pointer; + display: inline-flex; } .selection {