diff --git a/js/ImageLoader.js b/js/ImageLoader.js index 3c4cd80..1d93c29 100644 --- a/js/ImageLoader.js +++ b/js/ImageLoader.js @@ -3,14 +3,18 @@ export default class ImageLoader images = []; numberImagesLoaded = 0; + constructor() { + this.onLoad = () => {} + } + update() { this.numberImagesLoaded++; if (this.numberImagesLoaded === this.images.length) { window.dispatchEvent(new Event('imagesloaded')); + this.onLoad(); } - } isComplete() diff --git a/tilorswift/index.html b/tilorswift/index.html index f2f6f9e..75f7e80 100644 --- a/tilorswift/index.html +++ b/tilorswift/index.html @@ -5,7 +5,7 @@ Tilorswift - +
diff --git a/tilorswift/js/Tilorswift.js b/tilorswift/js/Tilorswift.js index 249859b..fb4c0b8 100644 --- a/tilorswift/js/Tilorswift.js +++ b/tilorswift/js/Tilorswift.js @@ -1,6 +1,218 @@ +import {LoadLevelDialog} from "../../js/ui/LoadLevelDialog.js"; +import GraphicSet from "../../js/GraphicSet.js"; +import Setting from "../../js/Setting.js"; +import Brush from "./Brush.js"; +import Tileset from "./Tileset.js"; +import WidgetBar from "./menu/WidgetBar.js"; +import TilesetPickerWidget from "./menu/TilesetPickerWidget.js"; +import EntrancePointWidget from "./menu/EntrancePointWidget.js"; +import TargetPointWidget from "./menu/TargetPointWidget.js"; +import Mouse from "./Mouse.js"; +import MainMenu from "./menu/MainMenu.js"; +import MenuGroup from "./menu/MenuGroup.js"; +import MainMenuEntry from "./menu/MainMenuEntry.js"; +import TilorswiftMenuNewTerrainClickedEvent from "./events/TilorswiftMenuNewTerrainClickedEvent.js"; +import {TilorswiftMenuOpenCLickedEvent} from "./events/TilorswiftMenuOpenCLickedEvent.js"; +import TilorswiftMenuSaveClickedEvent from "./events/TilorswiftMenuSaveClickedEvent.js"; +import TilorswiftAddRowsClickedEvent from "./events/TilorswiftAddRowsClickedEvent.js"; +import TilorswiftAddColumnsClickedEvent from "./events/TilorswiftAddColumnsClickedEvent.js"; +import TilorswiftMenuGravityClickedEvent from "./events/TilorswiftMenuGravityClickedEvent.js"; +import TilorswiftEvent from "./events/TilorswiftEvent.js"; +import BrushMode from "./BrushMode.js"; +import DialogNewTerrain from "./dialog/DialogNewTerrain.js"; +import DialogGravity from "./dialog/DialogGravity.js"; +import DialogAddRows from "./dialog/DialogAddRows.js"; +import DialogAddColumns from "./dialog/DialogAddColumns.js"; +import Terrain from "./Terrain.js"; +import TilorswiftSavedEvent from "./events/TilorswiftSavedEvent.js"; +import Level from "../../js/Level.js"; + export default class Tilorswift { - static getLevelAsJson(level) + constructor(level) { + this.level = level; + this.map = document.getElementById('map'); + this.brush = new Brush(); + this.tileset = new Tileset(this.level.terrain.tileset.setId); + this.widgetBar = new WidgetBar('widget-bar'); + this.tilesetPicker = new TilesetPickerWidget(this.tileset, this.brush); + this.widgetBar.addWidget(this.tilesetPicker); + this.entrancePicker = new EntrancePointWidget(this.widgetBar, this.brush); + this.widgetBar.addWidget(this.entrancePicker); + this.targetPicker = new TargetPointWidget(this.widgetBar, this.brush); + this.widgetBar.addWidget(this.targetPicker); + this.mouse = new Mouse(); + this.mainbar = new MainMenu('mainbar'); + } + + init() + { + document.body.appendChild(this.widgetBar.getElement()); + + const menuFile = new MenuGroup('Datei'); + menuFile.addMenuEntry(new MainMenuEntry('Neu...', TilorswiftMenuNewTerrainClickedEvent)); + menuFile.addMenuEntry(new MainMenuEntry('Öffnen...', TilorswiftMenuOpenCLickedEvent)); + menuFile.addMenuEntry(new MainMenuEntry('Speichern...', TilorswiftMenuSaveClickedEvent)); + this.mainbar.addMenuGroup(menuFile); + + const menuEdit = new MenuGroup('Bearbeiten'); + menuEdit.addMenuEntry(new MainMenuEntry('Zeilen einfügen...', TilorswiftAddRowsClickedEvent)); + menuEdit.addMenuEntry(new MainMenuEntry('Spalten einfügen...', TilorswiftAddColumnsClickedEvent)); + this.mainbar.addMenuGroup(menuEdit); + + const menuLevel = new MenuGroup('Level'); + menuLevel.addMenuEntry(new MainMenuEntry('Gravitation...', TilorswiftMenuGravityClickedEvent)); + this.mainbar.addMenuGroup(menuLevel); + + document.body.appendChild(this.mainbar.getElement()); + + this.addEventListeners(); + } + + addEventListeners() + { + window.addEventListener( + TilorswiftEvent.FIELD_CLICKED, + (event) => { + if (this.brush.mode === BrushMode.TERRAIN && !event.getField().isEntrancePoint) { + switch (event.button) { + case 0: + event.getField().setIndex(this.level.terrain.brushTileIndex); + break; + case 2: + event.getField().setIndex(-1); + break; + } + } else if (this.brush.mode === BrushMode.ENTRANCE) { + if (event.getField().index === -1) { + const coordinates = this.level.terrain.getFieldCoordinates(event.getField()); + this.level.terrain.setEntrancePoint(coordinates.x, coordinates.y); + this.brush.mode = BrushMode.TERRAIN; + this.widgetBar.enableWidgets(); + } + } else if (this.brush.mode === BrushMode.EXIT) { + if (event.getField().index === -1) { + const coordinates = this.level.terrain.getFieldCoordinates(event.getField()); + this.level.terrain.setTargetPoint(coordinates.x, coordinates.y); + this.brush.mode = BrushMode.TERRAIN; + this.widgetBar.enableWidgets(); + } + } + } + ); + + window.addEventListener( + 'contextmenu', + (event) => { + event.preventDefault(); + } + ); + + window.addEventListener( + TilorswiftEvent.FIELD_ENTERED, + (event) => { + if (this.mouse.isPressedLeft) { + event.getField().setIndex(this.level.terrain.brushTileIndex); + } else if (this.mouse.isPressedRight) { + event.getField().setIndex(-1); + } + } + ); + + window.addEventListener( + TilorswiftEvent.NEW_TERRAIN_CLICKED, + () => { + new DialogNewTerrain(); + } + ); + + window.addEventListener( + TilorswiftEvent.MENU_GRAVITY_CLICKED, + () => { + new DialogGravity(this.level.gravity); + } + ); + + window.addEventListener( + TilorswiftEvent.ADD_ROWS_CLICKED, + () => { + new DialogAddRows(); + } + ); + + window.addEventListener( + TilorswiftEvent.ADD_COLUMNS_CLICKED, + () => { + new DialogAddColumns(); + } + ); + + window.addEventListener( + TilorswiftEvent.GRAVITY_UPDATED, + (event) => { + this.level.gravity = event.gravity; + } + ); + + window.addEventListener( + TilorswiftEvent.ADD_ROWS, + (event) => { + this.level.terrain.addRows(event.beforeRow, event.rowCount); + } + ); + + window.addEventListener( + TilorswiftEvent.ADD_COLUMNS, + (event) => { + this.level.terrain.addColumns(event.beforeColumn, event.columnCount); + } + ); + + window.addEventListener( + TilorswiftEvent.NEW_TERRAIN, + (event) => { + this.tileset = new Tileset(event.tilesetIndex); + this.level.terrain = new Terrain(this.tileset, event.tilesX, event.tilesY, GraphicSet[event.tilesetIndex].backgroundColor); + + document.body.style.backgroundColor = this.level.getBackgroundColor(); + + if (GraphicSet[event.tilesetIndex].backgroundImage !== null) { + document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[event.tilesetIndex].backgroundImage + '")'; + } else { + document.body.style.backgroundImage = 'none'; + } + this.map.innerHTML = ''; + this.map.appendChild(this.level.terrain.getElement()); + this.tilesetPicker.reloadTileset(this.tileset); + } + ); + + /* Prevents Firefox's annoying default drag and drop behavior for images */ + document.addEventListener( + 'dragstart', + (event) => { + event.preventDefault(); + } + ); + + window.addEventListener( + TilorswiftEvent.MENU_OPEN_CLICKED, + () => { + this.openLevelFromFile(); + } + ); + + window.addEventListener( + TilorswiftEvent.MENU_SAVE_CLICKED, + ()=> { + if (this.saveLevelToFile(this.level)) { + window.dispatchEvent(new TilorswiftSavedEvent()); + } + } + ); + } + + getLevelAsJson(level) { let matrix = []; @@ -29,26 +241,52 @@ export default class Tilorswift return JSON.stringify(data); } - static saveLevelToFile(level) + openLevelFromFile() { - if (!level.hasEntrancePoint()) { + const dialog = new LoadLevelDialog(); + dialog.onLoad = (json) => { + this.level = Level.createFromJson(json); + this.loadLevel(); + dialog.close(); + } + } + + loadLevel() + { + this.tileset = new Tileset(this.level.terrain.tileset.setId); + + document.body.style.backgroundColor = this.level.getBackgroundColor(); + + if (GraphicSet[this.level.terrain.tileset.setId].backgroundImage !== null) { + document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[this.level.terrain.tileset.setId].backgroundImage + '")'; + } else { + document.body.style.backgroundImage = 'none'; + } + this.map.innerHTML = ''; + this.map.appendChild(this.level.terrain.getElement()); + this.tilesetPicker.reloadTileset(this.tileset); + } + + saveLevelToFile() + { + if (!this.level.hasEntrancePoint()) { alert('Es muss ein Startpunkt definiert sein!'); return false; } - if (!level.hasTargetPoint()) { + if (!this.level.hasTargetPoint()) { alert('Es muss ein Zielpunkt definiert sein!'); return false; } - let filename = prompt('Dateiname', 'terrain.json'); + const filename = prompt('Dateiname', 'terrain.json'); if (filename === null) { return false; } - let json = Tilorswift.getLevelAsJson(level); - let download = document.createElement('a'); + const json = this.getLevelAsJson(level); + const download = document.createElement('a'); download.setAttribute('download', filename); download.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(json)); @@ -57,4 +295,4 @@ export default class Tilorswift return true; } -} \ No newline at end of file +} diff --git a/tilorswift/js/events/TilorswiftEvent.js b/tilorswift/js/events/TilorswiftEvent.js index cdb8d4a..791d092 100644 --- a/tilorswift/js/events/TilorswiftEvent.js +++ b/tilorswift/js/events/TilorswiftEvent.js @@ -3,6 +3,7 @@ const TilorswiftEvent = { FIELD_ENTERED: 'fieldEntered', BUTTON_TILE_CLICKED: 'buttonTileClicked', MENU_SAVE_CLICKED: 'menuSaveClicked', + MENU_OPEN_CLICKED: 'menuOpenClicked', DIALOG_BUTTON_OK_CLICKED: 'dialogButtonOkClicked', MENU_EDIT_CLICKED: 'menuEditClicked', SAVED: 'saved', @@ -18,4 +19,4 @@ const TilorswiftEvent = { GRAVITY_UPDATED: 'gravityUpdated', }; -export default TilorswiftEvent; \ No newline at end of file +export default TilorswiftEvent; diff --git a/tilorswift/js/events/TilorswiftMenuOpenCLickedEvent.js b/tilorswift/js/events/TilorswiftMenuOpenCLickedEvent.js new file mode 100644 index 0000000..7cb89a8 --- /dev/null +++ b/tilorswift/js/events/TilorswiftMenuOpenCLickedEvent.js @@ -0,0 +1,8 @@ +import TilorswiftEvent from "./TilorswiftEvent.js"; + +export class TilorswiftMenuOpenCLickedEvent extends Event +{ + constructor() { + super(TilorswiftEvent.MENU_OPEN_CLICKED); + } +} diff --git a/tilorswift/js/menu/TilesetPickerWidget.js b/tilorswift/js/menu/TilesetPickerWidget.js index b573708..b1e919c 100644 --- a/tilorswift/js/menu/TilesetPickerWidget.js +++ b/tilorswift/js/menu/TilesetPickerWidget.js @@ -30,7 +30,7 @@ export default class TilesetPickerWidget extends Widget loadTileset() { for (let t = 0; t < this.tileset.tiles; t++) { - let button = new ButtonTile(this.tileset, t); + const button = new ButtonTile(this.tileset, t); this.htmlElementSelector.appendChild(button.getElement()); } @@ -48,7 +48,7 @@ export default class TilesetPickerWidget extends Widget createElementPicker() { - let htmlElement = document.createElement('div'); + const htmlElement = document.createElement('div'); htmlElement.id = 'tileset-picker'; htmlElement.style.width = this.tileset.getTileWidth() + 'px'; htmlElement.style.height = this.tileset.getTileHeight() + 'px'; @@ -59,7 +59,7 @@ export default class TilesetPickerWidget extends Widget createElementSelector() { - let htmlElementSelector = document.createElement('div'); + const htmlElementSelector = document.createElement('div'); htmlElementSelector.id = 'tileset-selector-widget'; htmlElementSelector.style.width = Math.ceil(Math.sqrt(this.tileset.tiles)) * this.tileset.getTileWidth() + 'px'; htmlElementSelector.style.left = String(this.tileset.getTileWidth() + 1) + 'px'; @@ -69,12 +69,11 @@ export default class TilesetPickerWidget extends Widget setTile(index) { - let position = -this.tileset.getTileWidth() * index + 'px ' + this.tileset.getTileHeight() + 'px'; - this.htmlElement.style.backgroundPosition = position; + this.htmlElement.style.backgroundPosition = -this.tileset.getTileWidth() * index + 'px ' + this.tileset.getTileHeight() + 'px'; } getElement() { return this.htmlElement; } -} \ No newline at end of file +} diff --git a/tilorswift/js/module.js b/tilorswift/js/module.js index 2232465..5a004b6 100644 --- a/tilorswift/js/module.js +++ b/tilorswift/js/module.js @@ -1,208 +1,15 @@ -import Terrain from "./Terrain.js"; -import TilorswiftEvent from "./events/TilorswiftEvent.js"; -import Mouse from "./Mouse.js"; -import Tileset from "./Tileset.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"; -import TilesetPickerWidget from "./menu/TilesetPickerWidget.js"; -import WidgetBar from "./menu/WidgetBar.js"; -import EntrancePointWidget from "./menu/EntrancePointWidget.js"; -import Brush from "./Brush.js"; -import BrushMode from "./BrushMode.js"; -import DialogAddRows from "./dialog/DialogAddRows.js"; -import DialogAddColumns from "./dialog/DialogAddColumns.js"; -import TilorswiftAddRowsClickedEvent from "./events/TilorswiftAddRowsClickedEvent.js"; -import TilorswiftAddColumnsClickedEvent from "./events/TilorswiftAddColumnsClickedEvent.js"; -import TilorswiftMenuNewTerrainClickedEvent from "./events/TilorswiftMenuNewTerrainClickedEvent.js"; -import DialogNewTerrain from "./dialog/DialogNewTerrain.js"; -import TargetPointWidget from "./menu/TargetPointWidget.js"; +import Level from "../../js/Level.js"; +import ImageLoader from "../../js/ImageLoader.js"; import GraphicSet from "../../js/GraphicSet.js"; import Setting from "../../js/Setting.js"; -import Level from "../../js/Level.js"; -import TilorswiftMenuGravityClickedEvent from "./events/TilorswiftMenuGravityClickedEvent.js"; -import DialogGravity from "./dialog/DialogGravity.js"; -let level = Level.createFromFile('../levels/moonbase.json'); - -if (GraphicSet[level.terrain.tileset.setId].backgroundImage !== null) { - document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[level.getTilesetId()].backgroundImage + '")'; +const level = Level.createFromFile('../levels/moonbase.json'); +const imageLoader = new ImageLoader(); +imageLoader.addImage('../' + Setting.TILESET_LOCATION + GraphicSet[level.terrain.tileset.setId].tileset); +imageLoader.onLoad = () => { + const tilorswift = new Tilorswift(level); + tilorswift.init(); + tilorswift.loadLevel(); } - -let image = new Image(); -image.src = '../' + Setting.TILESET_LOCATION + GraphicSet[level.terrain.tileset.setId].tileset; - -image.onload = function () { - document.body.style.backgroundColor = GraphicSet[level.terrain.tileset.setId].backgroundColor; - - let map = document.getElementById('map'); - map.appendChild(level.terrain.getElement()); - - let brush = new Brush(); - let tileset = new Tileset(level.terrain.tileset.setId); - let widgetBar = new WidgetBar('widget-bar'); - - let tilesetPicker = new TilesetPickerWidget(tileset, brush); - widgetBar.addWidget(tilesetPicker); - - let entrancePicker = new EntrancePointWidget(widgetBar, brush); - widgetBar.addWidget(entrancePicker); - - let targetPicker = new TargetPointWidget(widgetBar, brush); - widgetBar.addWidget(targetPicker); - - document.body.appendChild(widgetBar.getElement()); - - let mouse = new Mouse(); - let mainbar = new MainMenu('mainbar'); - - let menuFile = new MenuGroup('Datei'); - menuFile.addMenuEntry(new MainMenuEntry('Neu...', TilorswiftMenuNewTerrainClickedEvent)); - menuFile.addMenuEntry(new MainMenuEntry('Speichern...', TilorswiftMenuSaveClickedEvent)); - mainbar.addMenuGroup(menuFile); - - let menuEdit = new MenuGroup('Bearbeiten'); - menuEdit.addMenuEntry(new MainMenuEntry('Zeilen einfügen...', TilorswiftAddRowsClickedEvent)); - menuEdit.addMenuEntry(new MainMenuEntry('Spalten einfügen...', TilorswiftAddColumnsClickedEvent)); - mainbar.addMenuGroup(menuEdit); - - let menuLevel = new MenuGroup('Level'); - menuLevel.addMenuEntry(new MainMenuEntry('Gravitation...', TilorswiftMenuGravityClickedEvent)); - mainbar.addMenuGroup(menuLevel); - - document.body.appendChild(mainbar.getElement()); - - window.addEventListener( - TilorswiftEvent.FIELD_CLICKED, - (event) => { - if (brush.mode === BrushMode.TERRAIN && !event.getField().isEntrancePoint) { - switch (event.button) { - case 0: - event.getField().setIndex(level.terrain.brushTileIndex); - break; - case 2: - event.getField().setIndex(-1); - break; - } - } else if (brush.mode === BrushMode.ENTRANCE) { - if (event.getField().index === -1) { - let coordinates = level.terrain.getFieldCoordinates(event.getField()); - level.terrain.setEntrancePoint(coordinates.x, coordinates.y); - brush.mode = BrushMode.TERRAIN; - widgetBar.enableWidgets(); - } - } else if (brush.mode === BrushMode.EXIT) { - if (event.getField().index === -1) { - let coordinates = level.terrain.getFieldCoordinates(event.getField()); - level.terrain.setTargetPoint(coordinates.x, coordinates.y); - brush.mode = BrushMode.TERRAIN; - widgetBar.enableWidgets(); - } - } - } - ); - - window.addEventListener( - 'contextmenu', - (event) => { - event.preventDefault(); - } - ); - - window.addEventListener( - TilorswiftEvent.FIELD_ENTERED, - (event) => { - if (mouse.isPressedLeft) { - event.getField().setIndex(level.terrain.brushTileIndex); - } else if (mouse.isPressedRight) { - event.getField().setIndex(-1); - } - } - ); - - window.addEventListener( - TilorswiftEvent.NEW_TERRAIN_CLICKED, - () => { - new DialogNewTerrain(); - } - ); - - window.addEventListener( - TilorswiftEvent.MENU_GRAVITY_CLICKED, - () => { - new DialogGravity(level.gravity); - } - ); - - window.addEventListener( - TilorswiftEvent.ADD_ROWS_CLICKED, - () => { - new DialogAddRows(); - } - ); - - window.addEventListener( - TilorswiftEvent.ADD_COLUMNS_CLICKED, - () => { - new DialogAddColumns(); - } - ); - - window.addEventListener( - TilorswiftEvent.GRAVITY_UPDATED, - (event) => { - level.gravity = event.gravity; - } - ); - - window.addEventListener( - TilorswiftEvent.ADD_ROWS, - function (event) { - level.terrain.addRows(event.beforeRow, event.rowCount); - } - ); - - window.addEventListener( - TilorswiftEvent.ADD_COLUMNS, - function (event) { - level.terrain.addColumns(event.beforeColumn, event.columnCount); - } - ); - - window.addEventListener( - TilorswiftEvent.NEW_TERRAIN, - (event) => { - let tileset = new Tileset(event.tilesetIndex); - level.terrain = new Terrain(tileset, event.tilesX, event.tilesY, GraphicSet[event.tilesetIndex].backgroundColor); - document.body.style.backgroundColor = level.getBackgroundColor(); - if (GraphicSet[event.tilesetIndex].backgroundImage !== null) { - document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[event.tilesetIndex].backgroundImage + '")'; - } else { - document.body.style.backgroundImage = 'none'; - } - map.innerHTML = ''; - map.appendChild(level.terrain.getElement()); - tilesetPicker.reloadTileset(tileset); - } - ); - - /* Prevents Firefox's annoying default drag and drop behavior for images */ - document.addEventListener( - 'dragstart', - function (event) { - event.preventDefault(); - } - ); - - window.addEventListener( - TilorswiftEvent.MENU_SAVE_CLICKED, - function () { - if (Tilorswift.saveLevelToFile(level)) { - window.dispatchEvent(new TilorswiftSavedEvent()); - } - } - ); -}; +imageLoader.load();