Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
Mal | 83c1ae8119 | |
Mal | e476e689e1 | |
Mal | 2fe9b63c70 | |
Mal | 598dbc67ac | |
Mal | 46c584d9ee |
|
@ -10,14 +10,7 @@
|
||||||
"name": "Moon",
|
"name": "Moon",
|
||||||
"tileset": "moon.jpg",
|
"tileset": "moon.jpg",
|
||||||
"tiles": 2,
|
"tiles": 2,
|
||||||
"backgroundColor": "#000000",
|
"backgroundColor": "black",
|
||||||
"backgroundImage": "background_earth.jpg"
|
"backgroundImage": null
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Io",
|
|
||||||
"tileset": "io.jpg",
|
|
||||||
"tiles": 3,
|
|
||||||
"backgroundColor": "#000000",
|
|
||||||
"backgroundImage": "background_jupiter.jpg"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
Before Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 9.3 KiB |
|
@ -13,12 +13,10 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
cursor: none;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="shortcut icon" type="image/png" href="favicon.png">
|
<link rel="shortcut icon" type="image/png" href="favicon.png">
|
||||||
<link rel="stylesheet" type="text/css" href="tilorswift/style.css">
|
<script type="module" src="js/module.js"></script>
|
||||||
<script type="module" src="js/module.js" defer></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="canvas"></canvas>
|
<canvas id="canvas"></canvas>
|
||||||
|
|
|
@ -4,8 +4,7 @@ export default class FileLoader
|
||||||
{
|
{
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
this.content = '';
|
this.content = '';
|
||||||
|
this.loadContent();
|
||||||
this.onLoad = () => {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getContent()
|
getContent()
|
||||||
|
@ -20,7 +19,6 @@ export default class FileLoader
|
||||||
request.onreadystatechange = () => {
|
request.onreadystatechange = () => {
|
||||||
if (request.status === 200 && request.readyState === 4) {
|
if (request.status === 200 && request.readyState === 4) {
|
||||||
this.content = request.responseText;
|
this.content = request.responseText;
|
||||||
this.onLoad(this.content);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
import FrameRateMeasuredEvent from "./events/FrameRateMeasuredEvent.js";
|
||||||
|
|
||||||
|
export default class FrameRateMeasurer
|
||||||
|
{
|
||||||
|
constructor(rounds = 30)
|
||||||
|
{
|
||||||
|
this.rounds = rounds;
|
||||||
|
this.round = 0;
|
||||||
|
this.lastTimestamp = undefined;
|
||||||
|
this.frameDurations = [];
|
||||||
|
|
||||||
|
window.requestAnimationFrame(
|
||||||
|
(timestamp) => {
|
||||||
|
this.measureFrameRate(timestamp);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
measureFrameRate(timestamp)
|
||||||
|
{
|
||||||
|
if (this.lastTimestamp !== undefined) {
|
||||||
|
this.round++;
|
||||||
|
this.frameDurations.push(timestamp - this.lastTimestamp);
|
||||||
|
|
||||||
|
this.lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
if (this.round < this.rounds) {
|
||||||
|
window.requestAnimationFrame(
|
||||||
|
(timestamp) => {
|
||||||
|
this.measureFrameRate(timestamp);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
window.dispatchEvent(new FrameRateMeasuredEvent(this.getAverageFrameRate()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.round = 0;
|
||||||
|
this.lastTimestamp = timestamp;
|
||||||
|
window.requestAnimationFrame(
|
||||||
|
(timestamp) => {
|
||||||
|
this.measureFrameRate(timestamp);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastTimestamp = timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
getAverageFrameRate()
|
||||||
|
{
|
||||||
|
let frameDurationSum = 0;
|
||||||
|
|
||||||
|
this.frameDurations.forEach(
|
||||||
|
(duration) => {
|
||||||
|
frameDurationSum += duration;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let durationAverage = frameDurationSum / this.frameDurations.length;
|
||||||
|
|
||||||
|
return 1000 / durationAverage;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFrameRate()
|
||||||
|
{
|
||||||
|
const DEFAULT_FRAME_RATES = [30, 60, 120];
|
||||||
|
|
||||||
|
let averageFrameRate = this.getAverageFrameRate();
|
||||||
|
let closestDistance = {frameRate: 0, distance: 99999};
|
||||||
|
|
||||||
|
DEFAULT_FRAME_RATES.forEach(
|
||||||
|
(frameRate) => {
|
||||||
|
let distance = Math.abs(frameRate - averageFrameRate);
|
||||||
|
|
||||||
|
if (closestDistance.distance > distance) {
|
||||||
|
closestDistance.frameRate = frameRate;
|
||||||
|
closestDistance.distance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return closestDistance.frameRate;
|
||||||
|
}
|
||||||
|
}
|
242
js/Game.js
|
@ -1,242 +0,0 @@
|
||||||
import MrCroc from "./MrCroc.js";
|
|
||||||
import Gisela from "./Gisela.js";
|
|
||||||
import RetroArchitecture from "./retro/RetroArchitecture.js";
|
|
||||||
import Camera from "./Camera.js";
|
|
||||||
import TextMessageMrCroc from "./ui/TextMessageMrCroc.js";
|
|
||||||
import TextMessageGisela from "./ui/TextMessageGisela.js";
|
|
||||||
import UserInterface from "./ui/UserInterface.js";
|
|
||||||
import Key from "./Key.js";
|
|
||||||
import Setting from "./Setting.js";
|
|
||||||
import {EventBus} from "./events/EventBus.js";
|
|
||||||
|
|
||||||
|
|
||||||
export class Game
|
|
||||||
{
|
|
||||||
static GAME_SPEED = 1
|
|
||||||
|
|
||||||
constructor(level) {
|
|
||||||
this.level = level;
|
|
||||||
this.fps = 60;
|
|
||||||
this.frameDuration = 1000.0 / this.fps;
|
|
||||||
this.lastRendered = undefined;
|
|
||||||
this.lastTimestamp = undefined;
|
|
||||||
this.canvas = document.getElementById('canvas');
|
|
||||||
this.context = this.canvas.getContext('2d');
|
|
||||||
this.mrCroc = new MrCroc();
|
|
||||||
this.gisela = new Gisela();
|
|
||||||
this.architecture = RetroArchitecture.createFromData(this.level);
|
|
||||||
|
|
||||||
const cameraPosition = this.architecture.getStartPosition();
|
|
||||||
|
|
||||||
this.camera = new Camera(cameraPosition.x, cameraPosition.y);
|
|
||||||
this.gameFinished = false;
|
|
||||||
this.hasPlayerLeftArchitecture = false;
|
|
||||||
this.textBoxGameStart = new TextMessageMrCroc('Mr. Croc: "Where is Gisela? I have to find her!"', this.context);
|
|
||||||
this.textBoxGameFinished = new TextMessageGisela(
|
|
||||||
'Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."',
|
|
||||||
this.context
|
|
||||||
);
|
|
||||||
this.userInterface = new UserInterface();
|
|
||||||
this.isPaused = true;
|
|
||||||
|
|
||||||
this.KeyLeft = new Key('ArrowLeft');
|
|
||||||
this.KeyRight = new Key('ArrowRight');
|
|
||||||
this.KeyJump = new Key('Space');
|
|
||||||
this.KeyLoad = new Key('KeyL');
|
|
||||||
}
|
|
||||||
|
|
||||||
render(timestamp)
|
|
||||||
{
|
|
||||||
if (timestamp - this.lastRendered < this.frameDuration) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (this.gisela.currentAnimation !== 'SLEEP_LEFT' && this.mrCroc.position.x < this.gisela.position.x) {
|
|
||||||
this.gisela.currentAnimation = 'SLEEP_LEFT';
|
|
||||||
} else if (this.gisela.currentAnimation !== 'SLEEP_RIGHT' && this.mrCroc.position.x >= this.gisela.position.x) {
|
|
||||||
this.gisela.currentAnimation = 'SLEEP_RIGHT';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!this.gameFinished) {
|
|
||||||
if (this.mrCroc.position.x < this.gisela.position.x) {
|
|
||||||
this.gisela.playAnimation('SLEEP_LEFT', timestamp);
|
|
||||||
} else {
|
|
||||||
this.gisela.playAnimation('SLEEP_RIGHT', timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
|
||||||
this.architecture.draw(this.context, this.camera);
|
|
||||||
this.mrCroc.draw(this.context, this.camera);
|
|
||||||
this.gisela.draw(this.context, this.camera);
|
|
||||||
this.userInterface.draw(this.context);
|
|
||||||
|
|
||||||
this.lastRendered = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
canBeFinished()
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
!this.gameFinished &&
|
|
||||||
this.mrCroc.isJumping === false &&
|
|
||||||
this.architecture.isMovableInsideTargetPosition(this.mrCroc)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePhysics(delta, timestamp)
|
|
||||||
{
|
|
||||||
const ceilingHeight = Math.max(
|
|
||||||
this.architecture.getCeilingHeight(this.mrCroc.getPositionHeadLeft()),
|
|
||||||
this.architecture.getCeilingHeight(this.mrCroc.getPositionHeadRight()),
|
|
||||||
);
|
|
||||||
|
|
||||||
const groundHeight = Math.min(
|
|
||||||
this.architecture.getGroundHeight(this.mrCroc.getPositionFootLeft()),
|
|
||||||
this.architecture.getGroundHeight(this.mrCroc.getPositionFootRight())
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Handle falling */
|
|
||||||
this.mrCroc.position.y += this.mrCroc.fallSpeed * delta * 0.6;
|
|
||||||
this.mrCroc.fallSpeed += this.level.gravity * delta;
|
|
||||||
|
|
||||||
/* Handle ground collision */
|
|
||||||
if (this.mrCroc.position.y > groundHeight && this.mrCroc.fallSpeed > 0) {
|
|
||||||
this.mrCroc.position.y = groundHeight;
|
|
||||||
this.mrCroc.fallSpeed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle ceiling collision */
|
|
||||||
if (this.mrCroc.position.y - this.mrCroc.getHeight() <= ceilingHeight) {
|
|
||||||
this.mrCroc.fallSpeed = 0;
|
|
||||||
this.mrCroc.position.y = ceilingHeight + this.mrCroc.getHeight() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.handlePlayerMovement(delta, timestamp, groundHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCamera()
|
|
||||||
{
|
|
||||||
this.camera.focusPosition(
|
|
||||||
this.mrCroc.position.x - this.mrCroc.getWidth() * 0.5,
|
|
||||||
this.mrCroc.position.y - this.mrCroc.getHeight() * 0.5,
|
|
||||||
20
|
|
||||||
);
|
|
||||||
this.camera.lockCameraIntoBorders();
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePlayerMovement(delta, timestamp, groundHeight)
|
|
||||||
{
|
|
||||||
/* Jumping */
|
|
||||||
if (!this.mrCroc.isJumping && this.mrCroc.fallSpeed === 0 && this.mrCroc.position.y === groundHeight && this.KeyJump.isPressed()) {
|
|
||||||
this.mrCroc.jump();
|
|
||||||
} else if (!this.KeyJump.isPressed()) {
|
|
||||||
this.mrCroc.isJumping = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Movement left and right */
|
|
||||||
if (!this.hasPlayerLeftArchitecture && this.KeyLeft.isPressed()) {
|
|
||||||
const lastWallLeft = Math.min(
|
|
||||||
this.architecture.getWallLeft(this.mrCroc.getPositionHeadLeft()),
|
|
||||||
this.architecture.getWallLeft(this.mrCroc.getPositionFootLeft())
|
|
||||||
);
|
|
||||||
|
|
||||||
this.mrCroc.moveLeft(timestamp, delta);
|
|
||||||
|
|
||||||
if (this.mrCroc.position.x <= lastWallLeft + this.mrCroc.getWidth() * 0.5) {
|
|
||||||
this.mrCroc.position.x = lastWallLeft + this.mrCroc.getWidth() * 0.5 + 1;
|
|
||||||
}
|
|
||||||
} else if (!this.hasPlayerLeftArchitecture && this.KeyRight.isPressed()) {
|
|
||||||
const lastWallRight = Math.max(
|
|
||||||
this.architecture.getWallRight(this.mrCroc.getPositionHeadRight()),
|
|
||||||
this.architecture.getWallRight(this.mrCroc.getPositionFootRight())
|
|
||||||
);
|
|
||||||
|
|
||||||
this.mrCroc.moveRight(timestamp, delta);
|
|
||||||
|
|
||||||
if (this.mrCroc.position.x >= lastWallRight - this.mrCroc.getWidth() * 0.5) {
|
|
||||||
this.mrCroc.position.x = lastWallRight - this.mrCroc.getWidth() * 0.5 - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hasPlayerLeftArchitecture && !this.architecture.isInsideArchitecture(this.mrCroc.position)) {
|
|
||||||
this.hasPlayerLeftArchitecture = true;
|
|
||||||
|
|
||||||
setTimeout(
|
|
||||||
() => {
|
|
||||||
this.architecture.setMovableToStartPosition(this.mrCroc);
|
|
||||||
this.hasPlayerLeftArchitecture = false;
|
|
||||||
}, 2000
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
finish()
|
|
||||||
{
|
|
||||||
if (this.mrCroc.position.x < this.gisela.position.x) {
|
|
||||||
this.gisela.currentAnimation = 'LOOK_LEFT';
|
|
||||||
} else {
|
|
||||||
this.gisela.currentAnimation = 'LOOK_RIGHT';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.gameFinished = true;
|
|
||||||
this.KeyLeft.pressed = false;
|
|
||||||
this.KeyRight.pressed = false;
|
|
||||||
this.KeyJump.pressed = false;
|
|
||||||
this.lastTimestamp = undefined;
|
|
||||||
this.lastRendered = undefined;
|
|
||||||
this.textBoxGameFinished.updateLines(window.innerWidth - 40, this.context);
|
|
||||||
this.textBoxGameFinished.animate(75);
|
|
||||||
this.userInterface.addTextBox(this.textBoxGameFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
init(loopFunction) {
|
|
||||||
if (this.isChromeBrowser()) {
|
|
||||||
this.canvas.width = window.innerWidth - 1;
|
|
||||||
this.canvas.height = window.innerHeight - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.canvas.style.backgroundAttachment = 'fixed';
|
|
||||||
this.canvas.style.backgroundSize = 'cover';
|
|
||||||
this.canvas.style.backgroundPosition = 'center center';
|
|
||||||
|
|
||||||
if (this.level.getBackgroundImage() !== undefined) {
|
|
||||||
this.canvas.style.backgroundImage = "url("+ Setting.GRAPHICS_LOCATION + this.level.getBackgroundImage() + ")";
|
|
||||||
} else {
|
|
||||||
this.canvas.style.backgroundImage = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.canvas.style.backgroundColor = this.level.getBackgroundColor();
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
|
|
||||||
EventBus.addEventListener(
|
|
||||||
'resize',
|
|
||||||
function () {
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.textBoxGameStart.animate(75, 1000);
|
|
||||||
this.textBoxGameStart.show(1000);
|
|
||||||
this.textBoxGameStart.hide(10000);
|
|
||||||
this.userInterface.addTextBox(this.textBoxGameStart);
|
|
||||||
|
|
||||||
this.camera.borderRight = this.architecture.columns * this.architecture.tileWidth;
|
|
||||||
this.camera.borderBottom = this.architecture.rows * this.architecture.tileHeight;
|
|
||||||
|
|
||||||
this.architecture.setMovableToStartPosition(this.mrCroc);
|
|
||||||
this.architecture.setMovableToTargetPosition(this.gisela);
|
|
||||||
|
|
||||||
this.isPaused = false;
|
|
||||||
|
|
||||||
window.requestAnimationFrame(loopFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
isChromeBrowser()
|
|
||||||
{
|
|
||||||
return navigator.userAgent.match('Chrome') !== null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,13 +15,5 @@ export default class Gisela extends Movable
|
||||||
'LOOK_RIGHT',
|
'LOOK_RIGHT',
|
||||||
new RetroAnimation(Setting.GRAPHICS_LOCATION + 'gisela-right.png', 1, SCALE, 0.01)
|
new RetroAnimation(Setting.GRAPHICS_LOCATION + 'gisela-right.png', 1, SCALE, 0.01)
|
||||||
);
|
);
|
||||||
this.addAnimation(
|
|
||||||
'SLEEP_LEFT',
|
|
||||||
new RetroAnimation(Setting.GRAPHICS_LOCATION + 'giesela-left-sleeping.png', 4, SCALE, 6)
|
|
||||||
);
|
|
||||||
this.addAnimation(
|
|
||||||
'SLEEP_RIGHT',
|
|
||||||
new RetroAnimation(Setting.GRAPHICS_LOCATION + 'giesela-right-sleeping.png', 4, SCALE, 6)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,10 +5,7 @@ let GraphicSet = [
|
||||||
tiles: 8,
|
tiles: 8,
|
||||||
scale: 3,
|
scale: 3,
|
||||||
backgroundColor: '#6096ff',
|
backgroundColor: '#6096ff',
|
||||||
backgroundImage: null,
|
backgroundImage: null
|
||||||
tilePreview: 5,
|
|
||||||
primaryTiles: 8,
|
|
||||||
gravity: 9.806,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Moon',
|
name: 'Moon',
|
||||||
|
@ -16,43 +13,7 @@ let GraphicSet = [
|
||||||
tiles: 2,
|
tiles: 2,
|
||||||
scale: 3,
|
scale: 3,
|
||||||
backgroundColor: 'black',
|
backgroundColor: 'black',
|
||||||
backgroundImage: 'background_earth.jpg',
|
backgroundImage: 'background_earth.jpg'
|
||||||
tilePreview: 1,
|
|
||||||
primaryTiles: 2,
|
|
||||||
gravity: 2.4515,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Death Star',
|
|
||||||
tileset: 'deathstar.png',
|
|
||||||
tiles: 96,
|
|
||||||
scale: 1,
|
|
||||||
backgroundColor: '#171721',
|
|
||||||
backgroundImage: null,
|
|
||||||
tilePreview: 3,
|
|
||||||
primaryTiles: 6,
|
|
||||||
gravity: 9.806,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Nature 2.0',
|
|
||||||
tileset: 'nature.png',
|
|
||||||
tiles: 48,
|
|
||||||
scale: 3,
|
|
||||||
backgroundColor: '#6096ff',
|
|
||||||
backgroundImage: null,
|
|
||||||
tilePreview: 46,
|
|
||||||
primaryTiles: 3,
|
|
||||||
gravity: 9.806,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Io',
|
|
||||||
tileset: 'io.png',
|
|
||||||
tiles: 96,
|
|
||||||
scale: 1,
|
|
||||||
backgroundColor: '#000000',
|
|
||||||
backgroundImage: 'background_jupiter.jpg',
|
|
||||||
tilePreview: 2,
|
|
||||||
primaryTiles: 6,
|
|
||||||
gravity: 1.796,
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -3,25 +3,15 @@ export default class ImageLoader
|
||||||
images = [];
|
images = [];
|
||||||
numberImagesLoaded = 0;
|
numberImagesLoaded = 0;
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.onLoad = () => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
update()
|
update()
|
||||||
{
|
{
|
||||||
this.numberImagesLoaded++;
|
this.numberImagesLoaded++;
|
||||||
|
|
||||||
if (this.numberImagesLoaded === this.images.length) {
|
if (this.numberImagesLoaded === this.images.length) {
|
||||||
window.dispatchEvent(new Event('imagesloaded'));
|
window.dispatchEvent(new Event('imagesloaded'));
|
||||||
this.onLoad();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isComplete()
|
|
||||||
{
|
|
||||||
return this.numberImagesLoaded === this.images.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentProgress()
|
getCurrentProgress()
|
||||||
{
|
{
|
||||||
return this.numberImagesLoaded / this.images.length;
|
return this.numberImagesLoaded / this.images.length;
|
||||||
|
@ -29,12 +19,6 @@ export default class ImageLoader
|
||||||
|
|
||||||
addImage(imagePath)
|
addImage(imagePath)
|
||||||
{
|
{
|
||||||
this.images.push(imagePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
load()
|
|
||||||
{
|
|
||||||
for (const imagePath of this.images) {
|
|
||||||
let image = new Image();
|
let image = new Image();
|
||||||
image.src = imagePath;
|
image.src = imagePath;
|
||||||
image.addEventListener(
|
image.addEventListener(
|
||||||
|
@ -42,6 +26,7 @@ export default class ImageLoader
|
||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
this.images.push(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import {EventBus} from "./events/EventBus.js";
|
|
||||||
|
|
||||||
export default class Key
|
export default class Key
|
||||||
{
|
{
|
||||||
constructor(name)
|
constructor(name)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.pressed = false;
|
this.pressed = false;
|
||||||
EventBus.addEventListener(
|
|
||||||
|
window.addEventListener(
|
||||||
'keydown',
|
'keydown',
|
||||||
(event) => {
|
(event) => {
|
||||||
if (event.code === this.name) {
|
if (event.code === this.name) {
|
||||||
|
@ -14,7 +13,8 @@ export default class Key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
EventBus.addEventListener(
|
|
||||||
|
window.addEventListener(
|
||||||
'keyup',
|
'keyup',
|
||||||
(event) => {
|
(event) => {
|
||||||
if (event.code === this.name) {
|
if (event.code === this.name) {
|
||||||
|
|
25
js/Level.js
|
@ -3,8 +3,6 @@ import Terrain from "../tilorswift/js/Terrain.js";
|
||||||
|
|
||||||
export default class Level
|
export default class Level
|
||||||
{
|
{
|
||||||
static FACTOR_GRAVITY = 4.903;
|
|
||||||
|
|
||||||
constructor(terrain)
|
constructor(terrain)
|
||||||
{
|
{
|
||||||
this.terrain = terrain;
|
this.terrain = terrain;
|
||||||
|
@ -76,26 +74,13 @@ export default class Level
|
||||||
this.gravity = gravity;
|
this.gravity = gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
static createFromFile(filename, callback = () => {})
|
static createFromFile(filename)
|
||||||
{
|
{
|
||||||
let loader = new FileLoader(filename);
|
let loader = new FileLoader(filename);
|
||||||
loader.onLoad = (data) => {
|
let levelData = JSON.parse(loader.getContent());
|
||||||
const json = JSON.parse(data);
|
let terrain = Terrain.createFromJson(levelData);
|
||||||
const level = new Level(Terrain.createFromJson(json));
|
let level = new Level(terrain);
|
||||||
level.setGravity(json.gravity / Level.FACTOR_GRAVITY);
|
level.setGravity(levelData.gravity);
|
||||||
|
|
||||||
callback(level);
|
|
||||||
}
|
|
||||||
loader.loadContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
static createFromJson(json)
|
|
||||||
{
|
|
||||||
const data = JSON.parse(json);
|
|
||||||
|
|
||||||
const terrain = Terrain.createFromJson(data);
|
|
||||||
const level = new Level(terrain);
|
|
||||||
level.setGravity(data.gravity / Level.FACTOR_GRAVITY);
|
|
||||||
|
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,15 +44,15 @@ export default class UrlParam
|
||||||
|
|
||||||
getInt(name)
|
getInt(name)
|
||||||
{
|
{
|
||||||
const value = parseInt(this.get(name));
|
let value = parseInt(this.get(name));
|
||||||
|
|
||||||
return isNaN(value) ? 0 : value;
|
return isNaN(value) ? undefined : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFloat(name)
|
getFloat(name)
|
||||||
{
|
{
|
||||||
const value = parseFloat(this.get(name));
|
let value = parseFloat(this.get(name));
|
||||||
|
|
||||||
return isNaN(value) ? 0.0 : value;
|
return isNaN(value) ? undefined : value;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
export class EventBus
|
|
||||||
{
|
|
||||||
static listeners = []
|
|
||||||
|
|
||||||
static addEventListener(eventName, callback)
|
|
||||||
{
|
|
||||||
EventBus.listeners.push({eventName, callback});
|
|
||||||
|
|
||||||
window.addEventListener(eventName, callback, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static dispatchEvent(event)
|
|
||||||
{
|
|
||||||
window.dispatchEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static clear()
|
|
||||||
{
|
|
||||||
for (const listener of EventBus.listeners) {
|
|
||||||
window.removeEventListener(listener.eventName, listener.callback, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventBus.listeners = [];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import InterfaceEvent from "./InterfaceEvent.js";
|
||||||
|
|
||||||
|
export default class FrameRateMeasuredEvent extends Event
|
||||||
|
{
|
||||||
|
constructor(frameRate) {
|
||||||
|
super(InterfaceEvent.FRAME_RATE_MEASURED);
|
||||||
|
this.frameRate = frameRate;
|
||||||
|
}
|
||||||
|
}
|
290
js/module.js
|
@ -1,83 +1,147 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
import Key from "./Key.js";
|
||||||
|
import MrCroc from "./MrCroc.js";
|
||||||
|
import RetroArchitecture from "./retro/RetroArchitecture.js";
|
||||||
|
import Camera from "./Camera.js";
|
||||||
|
import Gisela from "./Gisela.js";
|
||||||
import Setting from "./Setting.js";
|
import Setting from "./Setting.js";
|
||||||
|
import FrameRateMeasurer from "./FrameRateMeasurer.js";
|
||||||
import GraphicSet from "./GraphicSet.js";
|
import GraphicSet from "./GraphicSet.js";
|
||||||
import ImageLoader from "./ImageLoader.js";
|
import ImageLoader from "./ImageLoader.js";
|
||||||
import Level from "./Level.js";
|
import Level from "./Level.js";
|
||||||
|
import InterfaceEvent from "./events/InterfaceEvent.js";
|
||||||
import UrlParam from "./UrlParam.js";
|
import UrlParam from "./UrlParam.js";
|
||||||
import {LoadLevelDialog} from "./ui/LoadLevelDialog.js";
|
import UserInterface from "./ui/UserInterface.js";
|
||||||
import {EventBus} from "./events/EventBus.js";
|
import TextMessageGisela from "./ui/TextMessageGisela.js";
|
||||||
import {Game} from "./Game.js";
|
import TextMessageMrCroc from "./ui/TextMessageMrCroc.js";
|
||||||
|
|
||||||
|
function MainLoop(timestamp)
|
||||||
function mainLoop(timestamp)
|
|
||||||
{
|
{
|
||||||
if (game.isPaused) {
|
if (lastRendered === undefined && lastTimestamp === undefined) {
|
||||||
return;
|
lastRendered = timestamp;
|
||||||
|
lastTimestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.lastRendered === undefined && game.lastTimestamp === undefined) {
|
let delta = (timestamp - lastTimestamp) / (10 / GAME_SPEED);
|
||||||
game.lastRendered = timestamp;
|
|
||||||
game.lastTimestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
let delta = (timestamp - game.lastTimestamp) / (10 / Game.GAME_SPEED);
|
let ceilingHeight = Math.max(
|
||||||
|
architecture.getCeilingHeight(mrCroc.getPositionHeadLeft()),
|
||||||
game.handlePhysics(delta, timestamp);
|
architecture.getCeilingHeight(mrCroc.getPositionHeadRight()),
|
||||||
game.updateCamera();
|
|
||||||
game.render(timestamp);
|
|
||||||
game.lastTimestamp = timestamp;
|
|
||||||
|
|
||||||
if (game.canBeFinished()) {
|
|
||||||
game.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.KeyLoad.isPressed()) {
|
|
||||||
const dialog = new LoadLevelDialog();
|
|
||||||
dialog.onClose = () => {
|
|
||||||
dialog.close();
|
|
||||||
game.isPaused = false;
|
|
||||||
window.requestAnimationFrame(mainLoop);
|
|
||||||
}
|
|
||||||
dialog.onLoad = (data) => {
|
|
||||||
EventBus.clear();
|
|
||||||
loadLevel(Level.createFromJson(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
game.isPaused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.requestAnimationFrame(mainLoop);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadLevel(level)
|
|
||||||
{
|
|
||||||
const loader = new ImageLoader();
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-right.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-left.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-right.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-left.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-left.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'giesela-left-sleeping.png');
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + 'giesela-right-sleeping.png');
|
|
||||||
|
|
||||||
for (const graphicSet of GraphicSet) {
|
|
||||||
loader.addImage(Setting.TILESET_LOCATION + graphicSet.tileset);
|
|
||||||
|
|
||||||
if (graphicSet.backgroundImage !== null) {
|
|
||||||
loader.addImage(Setting.GRAPHICS_LOCATION + graphicSet.backgroundImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loader.load();
|
|
||||||
|
|
||||||
EventBus.addEventListener(
|
|
||||||
'imagesloaded',
|
|
||||||
() => {
|
|
||||||
game = new Game(level);
|
|
||||||
game.init(mainLoop);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let groundHeight = Math.min(
|
||||||
|
architecture.getGroundHeight(mrCroc.getPositionFootLeft()),
|
||||||
|
architecture.getGroundHeight(mrCroc.getPositionFootRight())
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Handle falling */
|
||||||
|
mrCroc.position.y += mrCroc.fallSpeed;
|
||||||
|
mrCroc.fallSpeed += GRAVITY * delta;
|
||||||
|
|
||||||
|
/* Handle ground collision */
|
||||||
|
if (mrCroc.position.y > groundHeight && mrCroc.fallSpeed > 0) {
|
||||||
|
mrCroc.position.y = groundHeight;
|
||||||
|
mrCroc.fallSpeed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle ceiling collision */
|
||||||
|
if (mrCroc.position.y - mrCroc.getHeight() <= ceilingHeight) {
|
||||||
|
mrCroc.fallSpeed = 0;
|
||||||
|
mrCroc.position.y = ceilingHeight + mrCroc.getHeight() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle jumping */
|
||||||
|
if (!mrCroc.isJumping && mrCroc.fallSpeed === 0 && mrCroc.position.y === groundHeight && KeyJump.isPressed()) {
|
||||||
|
mrCroc.jump();
|
||||||
|
} else if (!KeyJump.isPressed()) {
|
||||||
|
mrCroc.isJumping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Movement left and right */
|
||||||
|
if (!hasPlayerLeftArchitecture && KeyLeft.isPressed()) {
|
||||||
|
let lastWallLeft = Math.min(
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionHeadLeft()),
|
||||||
|
architecture.getWallLeft(mrCroc.getPositionFootLeft())
|
||||||
|
);
|
||||||
|
|
||||||
|
mrCroc.moveLeft(timestamp, delta);
|
||||||
|
|
||||||
|
if (mrCroc.position.x <= lastWallLeft + mrCroc.getWidth() * 0.5) {
|
||||||
|
mrCroc.position.x = lastWallLeft + mrCroc.getWidth() * 0.5 + 1;
|
||||||
|
}
|
||||||
|
} else if (!hasPlayerLeftArchitecture && KeyRight.isPressed()) {
|
||||||
|
let lastWallRight = Math.max(
|
||||||
|
architecture.getWallRight(mrCroc.getPositionHeadRight()),
|
||||||
|
architecture.getWallRight(mrCroc.getPositionFootRight())
|
||||||
|
);
|
||||||
|
|
||||||
|
mrCroc.moveRight(timestamp, delta);
|
||||||
|
|
||||||
|
if (mrCroc.position.x >= lastWallRight - mrCroc.getWidth() * 0.5) {
|
||||||
|
mrCroc.position.x = lastWallRight - mrCroc.getWidth() * 0.5 - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasPlayerLeftArchitecture && !architecture.isInsideArchitecture(mrCroc.position)) {
|
||||||
|
hasPlayerLeftArchitecture = true;
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
function () {
|
||||||
|
architecture.setMovableToStartPosition(mrCroc);
|
||||||
|
hasPlayerLeftArchitecture = false;
|
||||||
|
}, 2000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.focusPosition(
|
||||||
|
mrCroc.position.x - mrCroc.getWidth() * 0.5,
|
||||||
|
mrCroc.position.y - mrCroc.getHeight() * 0.5,
|
||||||
|
20
|
||||||
|
);
|
||||||
|
camera.lockCameraIntoBorders();
|
||||||
|
|
||||||
|
/* Drawing */
|
||||||
|
if (timestamp - lastRendered >= frameDuration) {
|
||||||
|
lastRendered = timestamp;
|
||||||
|
|
||||||
|
if (gisela.currentAnimation !== 'LOOK_LEFT' && mrCroc.position.x < gisela.position.x) {
|
||||||
|
gisela.currentAnimation = 'LOOK_LEFT';
|
||||||
|
} else if (gisela.currentAnimation !== 'LOOK_RIGHT' && mrCroc.position.x >= gisela.position.x) {
|
||||||
|
gisela.currentAnimation = 'LOOK_RIGHT';
|
||||||
|
}
|
||||||
|
|
||||||
|
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
||||||
|
|
||||||
|
switch (browser) {
|
||||||
|
case 'Chrome':
|
||||||
|
architecture.drawForChrome(context, camera);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
architecture.drawForFirefox(context, camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
mrCroc.draw(context, camera);
|
||||||
|
gisela.draw(context, camera);
|
||||||
|
userInterface.draw(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
if (!gameFinished && mrCroc.isJumping === false && architecture.isMovableInsideTargetPosition(mrCroc)) {
|
||||||
|
gameFinished = true;
|
||||||
|
KeyLeft.pressed = false;
|
||||||
|
KeyRight.pressed = false;
|
||||||
|
KeyJump.pressed = false;
|
||||||
|
lastTimestamp = undefined;
|
||||||
|
lastRendered = undefined;
|
||||||
|
textBoxGameFinished.updateLines(window.innerWidth - 40, context);
|
||||||
|
textBoxGameFinished.animate(75);
|
||||||
|
userInterface.addTextBox(textBoxGameFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimationFrame(MainLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LEVEL = [
|
const LEVEL = [
|
||||||
|
@ -86,17 +150,93 @@ const LEVEL = [
|
||||||
'moonbase.json',
|
'moonbase.json',
|
||||||
'terrain8.json',
|
'terrain8.json',
|
||||||
'darius.json',
|
'darius.json',
|
||||||
'imperial-prison.json',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let game;
|
let urlGetter = new UrlParam();
|
||||||
|
|
||||||
const urlGetter = new UrlParam();
|
let levelIndex = urlGetter.getInt('level');
|
||||||
const levelIndex = urlGetter.getInt('level');
|
|
||||||
|
|
||||||
Level.createFromFile(
|
if (levelIndex === undefined || levelIndex < 0 || levelIndex >= LEVEL.length) {
|
||||||
Setting.LEVELS_LOCATION + LEVEL[levelIndex % LEVEL.length],
|
levelIndex = 0;
|
||||||
(level) => {
|
}
|
||||||
loadLevel(level);
|
|
||||||
|
let level = Level.createFromFile(Setting.LEVELS_LOCATION + LEVEL[levelIndex]);
|
||||||
|
|
||||||
|
const GAME_SPEED = 1;
|
||||||
|
const GRAVITY = level.gravity;
|
||||||
|
let fps = 120;
|
||||||
|
const browser = navigator.userAgent.indexOf('Firefox') === -1 ? 'Chrome' : 'Firefox';
|
||||||
|
let frameDuration;
|
||||||
|
let lastRendered = undefined;
|
||||||
|
let lastTimestamp = undefined;
|
||||||
|
let context;
|
||||||
|
let mrCroc, gisela, architecture;
|
||||||
|
let camera = new Camera();
|
||||||
|
let gameFinished = false;
|
||||||
|
let hasPlayerLeftArchitecture = false;
|
||||||
|
let textBoxGameStart;
|
||||||
|
let textBoxGameFinished;
|
||||||
|
let userInterface = new UserInterface();
|
||||||
|
|
||||||
|
let KeyLeft = new Key('ArrowLeft');
|
||||||
|
let KeyRight = new Key('ArrowRight');
|
||||||
|
let KeyJump = new Key('Space');
|
||||||
|
|
||||||
|
let loader = new ImageLoader();
|
||||||
|
|
||||||
|
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-right.png');
|
||||||
|
loader.addImage(Setting.GRAPHICS_LOCATION + 'mr-croc-walk-left.png');
|
||||||
|
loader.addImage(Setting.TILESET_LOCATION + GraphicSet[level.getTilesetId()].tileset);
|
||||||
|
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-right.png');
|
||||||
|
loader.addImage(Setting.GRAPHICS_LOCATION + 'gisela-left.png');
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
'imagesloaded',
|
||||||
|
() => {
|
||||||
|
let canvas = document.getElementById('canvas');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
canvas.style.backgroundAttachment = 'fixed';
|
||||||
|
canvas.style.backgroundSize = 'cover';
|
||||||
|
canvas.style.backgroundPosition = 'center center';
|
||||||
|
|
||||||
|
if (GraphicSet[level.getTilesetId()].backgroundImage !== null) {
|
||||||
|
canvas.style.backgroundImage = 'url("' + Setting.GRAPHICS_LOCATION + GraphicSet[level.getTilesetId()].backgroundImage +'")';
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.style.backgroundColor = level.getBackgroundColor();
|
||||||
|
|
||||||
|
window.addEventListener(
|
||||||
|
'resize',
|
||||||
|
function () {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
context = canvas.getContext('2d');
|
||||||
|
textBoxGameFinished = new TextMessageGisela(
|
||||||
|
'Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."',
|
||||||
|
context
|
||||||
|
);
|
||||||
|
|
||||||
|
textBoxGameStart = new TextMessageMrCroc('Mr. Croc: "Where is Gisela? I have to find her!"', context);
|
||||||
|
textBoxGameStart.animate(75, 1000);
|
||||||
|
textBoxGameStart.show(1000);
|
||||||
|
textBoxGameStart.hide(10000);
|
||||||
|
userInterface.addTextBox(textBoxGameStart);
|
||||||
|
|
||||||
|
architecture = RetroArchitecture.createFromData(level);
|
||||||
|
camera.borderRight = architecture.columns * architecture.tileWidth;
|
||||||
|
camera.borderBottom = architecture.rows * architecture.tileHeight;
|
||||||
|
|
||||||
|
mrCroc = new MrCroc();
|
||||||
|
architecture.setMovableToStartPosition(mrCroc);
|
||||||
|
|
||||||
|
gisela = new Gisela();
|
||||||
|
architecture.setMovableToTargetPosition(gisela);
|
||||||
|
|
||||||
|
frameDuration = 1000 / fps;
|
||||||
|
window.requestAnimationFrame(MainLoop);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -63,4 +63,3 @@ export default class RetroAnimation extends RetroSprite
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import GeometryPoint from "../geometry/GeometryPoint.js";
|
||||||
import GeometryRect from "../geometry/GeometryRect.js";
|
import GeometryRect from "../geometry/GeometryRect.js";
|
||||||
import GraphicSet from "../GraphicSet.js";
|
import GraphicSet from "../GraphicSet.js";
|
||||||
import Setting from "../Setting.js";
|
import Setting from "../Setting.js";
|
||||||
|
import Camera from "../Camera.js";
|
||||||
|
|
||||||
export default class RetroArchitecture
|
export default class RetroArchitecture
|
||||||
{
|
{
|
||||||
|
@ -19,6 +20,10 @@ export default class RetroArchitecture
|
||||||
this.matrix = [];
|
this.matrix = [];
|
||||||
this.tileWidth = this.tilesetSprite.getWidth() / this.tiles;
|
this.tileWidth = this.tilesetSprite.getWidth() / this.tiles;
|
||||||
this.tileHeight = this.tilesetSprite.getHeight();
|
this.tileHeight = this.tilesetSprite.getHeight();
|
||||||
|
this.terrainCanvas = document.createElement('canvas');
|
||||||
|
this.terrainCanvas.width = this.tileWidth * this.columns;
|
||||||
|
this.terrainCanvas.height = this.tileHeight * this.rows;
|
||||||
|
this.terrainContext = this.terrainCanvas.getContext('2d');
|
||||||
this.startX = 0;
|
this.startX = 0;
|
||||||
this.startY = 0;
|
this.startY = 0;
|
||||||
this.targetX = 0;
|
this.targetX = 0;
|
||||||
|
@ -41,6 +46,23 @@ export default class RetroArchitecture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
const camera = new Camera();
|
||||||
|
|
||||||
|
for (let y = 0; y < this.rows; y++) {
|
||||||
|
for (let x = 0; x < this.columns; x++) {
|
||||||
|
const field = this.matrix[y][x];
|
||||||
|
|
||||||
|
if (field === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawField(this.terrainContext, x, y, camera, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setBackgroundColor(color)
|
setBackgroundColor(color)
|
||||||
{
|
{
|
||||||
this.backgroundColor = color;
|
this.backgroundColor = color;
|
||||||
|
@ -202,7 +224,7 @@ export default class RetroArchitecture
|
||||||
tileRect.isContainingPoint(movable.getPositionFootRight());
|
tileRect.isContainingPoint(movable.getPositionFootRight());
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(context, camera = new Camera())
|
drawForFirefox(context, camera = new Camera())
|
||||||
{
|
{
|
||||||
const viewX = parseInt(Math.floor(Math.max(0, camera.position.x) / this.tileWidth));
|
const viewX = parseInt(Math.floor(Math.max(0, camera.position.x) / this.tileWidth));
|
||||||
const viewWidth = parseInt(Math.min(Math.ceil(camera.width), this.columns));
|
const viewWidth = parseInt(Math.min(Math.ceil(camera.width), this.columns));
|
||||||
|
@ -211,7 +233,7 @@ export default class RetroArchitecture
|
||||||
|
|
||||||
for (let y = viewY; y < viewHeight; y++) {
|
for (let y = viewY; y < viewHeight; y++) {
|
||||||
for (let x = viewX; x < viewWidth; x++) {
|
for (let x = viewX; x < viewWidth; x++) {
|
||||||
let field = this.matrix[y][x];
|
const field = this.matrix[y][x];
|
||||||
|
|
||||||
if (field !== null) {
|
if (field !== null) {
|
||||||
this.drawField(context, x, y, camera, field);
|
this.drawField(context, x, y, camera, field);
|
||||||
|
@ -220,26 +242,41 @@ export default class RetroArchitecture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param camera Camera
|
||||||
|
*/
|
||||||
|
drawForChrome(context, camera)
|
||||||
|
{
|
||||||
|
context.drawImage(
|
||||||
|
this.terrainCanvas,
|
||||||
|
camera.position.x,
|
||||||
|
camera.position.y,
|
||||||
|
camera.width,
|
||||||
|
camera.height,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
camera.width,
|
||||||
|
camera.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
drawField(context, x, y, camera, field)
|
drawField(context, x, y, camera, field)
|
||||||
{
|
{
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
this.tilesetSprite.canvas,
|
this.tilesetSprite.canvas,
|
||||||
(field.tile.index % this.tiles) * this.tileWidth,
|
field.tile.index * this.tileWidth,
|
||||||
0,
|
0,
|
||||||
this.tileWidth,
|
this.tileWidth,
|
||||||
this.tileHeight,
|
this.tileHeight,
|
||||||
x * this.tileWidth - camera.position.x - 1,
|
x * this.tileWidth - camera.position.x,
|
||||||
y * this.tileHeight - camera.position.y - 1,
|
y * this.tileHeight - camera.position.y,
|
||||||
this.tileWidth + 1,
|
this.tileWidth + 1,
|
||||||
this.tileHeight + 1
|
this.tileHeight + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStartPosition()
|
|
||||||
{
|
|
||||||
return new GeometryPoint(this.startX * this.tileWidth, this.startY * this.tileHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
static createFromData(level)
|
static createFromData(level)
|
||||||
{
|
{
|
||||||
let graphicSet = GraphicSet[level.getTilesetId()];
|
let graphicSet = GraphicSet[level.getTilesetId()];
|
||||||
|
@ -279,6 +316,8 @@ export default class RetroArchitecture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
architecture.render();
|
||||||
|
|
||||||
return architecture;
|
return architecture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ export default class RetroSprite
|
||||||
canvasTemp.width = this.image.width * this.scale;
|
canvasTemp.width = this.image.width * this.scale;
|
||||||
canvasTemp.height = this.image.height * this.scale;
|
canvasTemp.height = this.image.height * this.scale;
|
||||||
|
|
||||||
let contextTemp = canvasTemp.getContext('2d', {willReadFrequently: true});
|
let contextTemp = canvasTemp.getContext('2d');
|
||||||
contextTemp.drawImage(this.image, 0, 0);
|
contextTemp.drawImage(this.image, 0, 0);
|
||||||
|
|
||||||
this.canvas.width = this.image.width * this.scale;
|
this.canvas.width = this.image.width * this.scale;
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
import Dialog from "../../tilorswift/js/dialog/Dialog.js";
|
|
||||||
|
|
||||||
export class LoadLevelDialog extends Dialog
|
|
||||||
{
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.setMessage('Level laden');
|
|
||||||
this.fileInput = this.createFileInput(['json']);
|
|
||||||
this.fileInput.addEventListener(
|
|
||||||
'change',
|
|
||||||
() => {
|
|
||||||
if (this.fileInput.files.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.addEventListener(
|
|
||||||
'load',
|
|
||||||
(event) => {
|
|
||||||
this.onClose();
|
|
||||||
this.onLoad(event.target.result);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
reader.readAsBinaryString(this.fileInput.files[0]);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
this.onClose = () => {};
|
|
||||||
this.onLoad = () => {};
|
|
||||||
|
|
||||||
this.buttonCancel = this.createButton('Abbrechen');
|
|
||||||
this.buttonCancel.addEventListener(
|
|
||||||
'click',
|
|
||||||
() => {
|
|
||||||
this.onClose();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
openFileBrowser()
|
|
||||||
{
|
|
||||||
this.fileInput.click();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,12 +4,11 @@ import UserInterfaceElement from "./UserInterfaceElement.js";
|
||||||
|
|
||||||
export default class TextBox extends UserInterfaceElement
|
export default class TextBox extends UserInterfaceElement
|
||||||
{
|
{
|
||||||
constructor(text, width, context, paused = false)
|
constructor(text, width, context)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.paused = paused;
|
|
||||||
this.colorText = 'red';
|
this.colorText = 'red';
|
||||||
this.colorShadow = 'black';
|
this.colorShadow = 'black';
|
||||||
this.colorBorder = 'black';
|
this.colorBorder = 'black';
|
||||||
|
|
|
@ -2,10 +2,9 @@ import TextAlignment from "./TextAlignment.js";
|
||||||
|
|
||||||
export default class TextLine
|
export default class TextLine
|
||||||
{
|
{
|
||||||
constructor(text, paused)
|
constructor(text)
|
||||||
{
|
{
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.paused = paused;
|
|
||||||
this.estimatedTextWidth = null;
|
this.estimatedTextWidth = null;
|
||||||
this.colorText = 'red';
|
this.colorText = 'red';
|
||||||
this.colorShadow = 'black';
|
this.colorShadow = 'black';
|
||||||
|
@ -25,10 +24,6 @@ export default class TextLine
|
||||||
|
|
||||||
let process = setInterval(
|
let process = setInterval(
|
||||||
() => {
|
() => {
|
||||||
if (this.paused) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.chars++;
|
this.chars++;
|
||||||
|
|
||||||
if (this.chars === this.text.length) {
|
if (this.chars === this.text.length) {
|
||||||
|
|
|
@ -3,8 +3,8 @@ import GeometryPoint from "../geometry/GeometryPoint.js";
|
||||||
|
|
||||||
export default class TextMessage extends TextBox
|
export default class TextMessage extends TextBox
|
||||||
{
|
{
|
||||||
constructor(text, context, paused = false) {
|
constructor(text, context) {
|
||||||
super(text, window.innerWidth - 40, context, paused);
|
super(text, window.innerWidth - 40, context);
|
||||||
this.update();
|
this.update();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
15113
levels/darius.json
|
@ -1 +0,0 @@
|
||||||
{"tileset":2,"rows":"30","columns":"30","startX":2,"startY":28,"targetX":2,"targetY":15,"gravity":9.806,"matrix":[[3,0,5,0,5,18,-1,30,5,0,5,0,21,-1,-1,33,5,0,0,5,0,0,5,0,0,3,21,-1,33,3],[2,0,24,0,24,72,-1,66,24,24,0,24,19,-1,-1,31,0,0,0,0,0,0,0,24,24,25,73,-1,31,1],[3,18,-1,92,-1,-1,-1,-1,-1,-1,92,-1,87,-1,-1,33,24,28,28,24,28,28,72,-1,-1,-1,-1,-1,33,3],[2,18,-1,-1,-1,8,-1,10,-1,-1,-1,-1,85,-1,-1,92,-1,-1,-1,-1,-1,-1,-1,-1,36,13,43,-1,31,1],[3,18,-1,39,57,75,-1,69,57,63,-1,51,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,30,3,21,-1,33,3],[2,18,-1,85,-1,-1,-1,-1,-1,-1,-1,-1,85,-1,-1,38,56,56,62,-1,-1,50,56,56,0,1,19,-1,31,1],[3,18,-1,87,-1,-1,50,56,56,56,56,56,21,-1,-1,84,-1,-1,-1,-1,-1,-1,-1,-1,30,3,21,-1,33,3],[2,18,-1,31,62,-1,-1,-1,-1,-1,-1,-1,85,-1,-1,86,-1,-1,50,62,-1,-1,-1,-1,30,1,19,-1,31,1],[3,18,-1,87,-1,-1,38,56,62,-1,50,56,21,-1,-1,86,-1,-1,-1,-1,-1,-1,-1,-1,30,3,21,-1,33,3],[2,18,-1,85,-1,37,19,-1,-1,-1,-1,-1,85,-1,-1,30,63,-1,-1,-1,-1,-1,-1,51,0,1,19,-1,1,1],[3,18,-1,69,56,26,20,-1,50,56,62,-1,93,-1,-1,86,-1,-1,-1,-1,-1,-1,-1,-1,30,3,21,-1,3,3],[2,18,-1,-1,-1,-1,89,-1,-1,-1,-1,-1,-1,-1,-1,84,-1,50,62,-1,-1,80,-1,-1,30,1,19,-1,1,1],[3,0,62,-1,50,14,26,56,14,56,15,56,44,-1,-1,86,-1,-1,-1,-1,-1,-1,-1,51,0,3,21,-1,3,3],[2,18,-1,-1,-1,86,-1,-1,89,-1,85,-1,89,-1,51,18,-1,-1,-1,-1,-1,-1,-1,-1,30,1,19,-1,31,1],[3,18,-1,-1,-1,86,-1,-1,95,-1,93,-1,95,-1,-1,92,-1,-1,7,-1,-1,-1,7,-1,30,3,21,-1,33,3],[2,18,-1,-1,-1,86,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,88,-1,-1,-1,88,-1,30,1,19,-1,31,1],[3,2,57,56,57,2,15,56,57,56,15,14,45,-1,-1,36,12,12,0,14,14,14,0,12,0,3,21,-1,33,3],[2,18,-1,-1,-1,30,18,-1,-1,-1,30,5,18,-1,80,0,5,5,0,5,5,5,0,5,0,1,19,-1,31,1],[3,18,-1,10,-1,32,20,-1,10,-1,30,5,18,-1,-1,66,24,24,0,26,26,26,24,24,24,27,75,-1,33,3],[2,0,14,0,14,0,0,14,0,14,0,2,0,80,-1,-1,-1,-1,92,-1,-1,-1,-1,-1,-1,-1,-1,-1,31,1],[3,0,5,0,5,0,0,5,0,5,0,5,18,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,36,15,45,-1,33,3],[2,0,2,0,2,0,0,2,0,2,0,2,0,14,44,-1,50,56,56,56,56,62,-1,-1,30,1,19,-1,31,1],[3,0,3,0,3,0,0,3,0,3,0,3,0,3,18,-1,33,3,3,3,21,-1,-1,-1,30,3,21,-1,33,3],[2,0,26,24,26,24,0,26,24,26,24,26,0,0,18,-1,30,0,0,0,18,-1,-1,80,0,1,19,-1,31,1],[3,18,-1,-1,-1,-1,86,-1,-1,-1,-1,-1,30,2,18,-1,30,2,0,2,18,-1,-1,-1,30,3,21,-1,33,3],[2,18,-1,-1,-1,-1,92,-1,-1,-1,-1,-1,30,2,18,-1,30,2,0,2,0,62,-1,-1,30,1,19,-1,31,1],[3,18,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,66,24,72,-1,66,24,24,24,72,-1,-1,-1,30,3,21,-1,33,3],[2,18,-1,-1,-1,-1,-1,-1,-1,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,0,1,19,-1,31,1],[3,18,-1,-1,-1,-1,8,-1,-1,87,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,30,3,21,-1,33,3],[2,0,12,17,16,17,0,12,17,0,17,12,14,44,-1,-1,38,44,-1,-1,38,14,14,14,0,1,19,-1,31,1]]}
|
|
|
@ -3,7 +3,7 @@
|
||||||
"rows": 10,
|
"rows": 10,
|
||||||
"columns": 17,
|
"columns": 17,
|
||||||
"backgroundColor": "#6096ff",
|
"backgroundColor": "#6096ff",
|
||||||
"gravity": 9.806,
|
"gravity": 2.0,
|
||||||
"matrix": [
|
"matrix": [
|
||||||
[6 ,6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,4 ,4 ],
|
[6 ,6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,4 ,4 ],
|
||||||
[6 ,6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,4 ,4 ],
|
[6 ,6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,4 ,4 ],
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"tileset":1,"rows":"20","columns":51,"startX":2,"startY":16,"targetX":49,"targetY":16,"backgroundColor":"black","gravity":2.4515,"matrix":[[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,1],[1,1,0,0,1,1,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,0,0,1,1,1,1,0,0,0,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]}
|
{"tileset":1,"rows":"20","columns":51,"startX":2,"startY":16,"targetX":49,"targetY":16,"backgroundColor":"black","gravity":0.5,"matrix":[[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1],[1,1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,1],[1,1,0,0,1,1,1,1,1,1,1,0,0,-1,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1,0,0,1,1,1,1,0,0,0,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]]}
|
|
@ -1 +1 @@
|
||||||
{"tileset":0,"rows":"20","columns":"40","startX":0,"startY":18,"targetX":0,"targetY":8,"gravity":9.806,"matrix":[[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[7,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[7,-1,4,-1,4,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,4,1,4,1,1,1,4,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[5,-1,-1,-1,-1,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,4,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[4,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[4,1,1,1,1,-1,-1,-1,1,1,1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,5,-1,-1,-1,4,4,1,-1,-1,-1,-1,-1,1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,4,4,-1,-1,1,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,1,5,5,-1,-1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,4,4,4,-1,-1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[1,1,1,1,1,4,4,4,1,1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]]}
|
{"tileset":0,"rows":"20","columns":"40","startX":0,"startY":18,"targetX":0,"targetY":8,"gravity":2.0,"matrix":[[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[7,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[7,-1,4,-1,4,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,4,1,4,1,1,1,4,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[5,-1,-1,-1,-1,-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,4,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[4,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[4,1,1,1,1,-1,-1,-1,1,1,1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,5,-1,-1,-1,4,4,1,-1,-1,-1,-1,-1,1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,4,4,-1,-1,1,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,1,5,5,-1,-1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,4,4,4,-1,-1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[1,1,1,1,1,4,4,4,1,1,4,4,4,-1,-1,4,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]]}
|
Before Width: | Height: | Size: 4.2 KiB |
|
@ -4,8 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Tilorswift</title>
|
<title>Tilorswift</title>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css">
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
<link rel="shortcut icon" type="image/png" href="favicon.png">
|
<script type="module" src="js/module.js"></script>
|
||||||
<script type="module" src="js/module.js" defer></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
|
|
@ -5,6 +5,5 @@ export default class Brush
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
this.mode = BrushMode.TERRAIN;
|
this.mode = BrushMode.TERRAIN;
|
||||||
this.isIntelligent = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ export default class ButtonTile extends Field
|
||||||
{
|
{
|
||||||
constructor(tileset, index = 0)
|
constructor(tileset, index = 0)
|
||||||
{
|
{
|
||||||
super(tileset, 0, 0, index);
|
super(tileset, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
initHtml() {
|
initHtml() {
|
||||||
|
|
|
@ -3,12 +3,10 @@ import TilorswiftFieldEnteredEvent from "./events/TilorswiftFieldEnteredEvent.js
|
||||||
|
|
||||||
export default class Field
|
export default class Field
|
||||||
{
|
{
|
||||||
constructor(tileset, x = 0, y = 0, index = -1)
|
constructor(tileset, index = -1)
|
||||||
{
|
{
|
||||||
this.tileset = tileset;
|
this.tileset = tileset;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.isEntrancePoint = false;
|
this.isEntrancePoint = false;
|
||||||
this.isTargetPoint = false;
|
this.isTargetPoint = false;
|
||||||
this.initHtml();
|
this.initHtml();
|
||||||
|
|
|
@ -53,12 +53,12 @@ export default class Terrain
|
||||||
|
|
||||||
getWidth()
|
getWidth()
|
||||||
{
|
{
|
||||||
return this.tilesX * this.tileset.getTileWidth();
|
return this.tilesX * this.tilest.getTileWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeight()
|
getHeight()
|
||||||
{
|
{
|
||||||
return this.tilesY * this.tileset.getTileHeight();
|
return this.tilesY * this.tilest.getTileHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
addRows(index, quantity = 1)
|
addRows(index, quantity = 1)
|
||||||
|
@ -70,26 +70,19 @@ export default class Terrain
|
||||||
this.targetTileY = this.targetTileY === undefined ? undefined : this.targetTileY + 1;
|
this.targetTileY = this.targetTileY === undefined ? undefined : this.targetTileY + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let y = index; y < this.tilesY; y++) {
|
|
||||||
for (let x = 0; x < this.tilesX; x++) {
|
|
||||||
// this.fields[y][x].index += quantity;
|
|
||||||
console.log(x, y);
|
|
||||||
this.fields[y][x].y += quantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.htmlElement.style.height = this.tileset.getTileHeight() * this.tilesY + 'px';
|
this.htmlElement.style.height = this.tileset.getTileHeight() * this.tilesY + 'px';
|
||||||
}
|
}
|
||||||
|
|
||||||
_insertRow(index = undefined)
|
_insertRow(index = undefined)
|
||||||
{
|
{
|
||||||
const row = [];
|
let row = [];
|
||||||
const tr = document.createElement('tr');
|
let tr = document.createElement('tr');
|
||||||
|
|
||||||
for (let col = 0; col < this.tilesX; col++) {
|
for (let col = 0; col < this.tilesX; col++) {
|
||||||
const field = new Field(this.tileset, col, this.fields.length);
|
let field = new Field(this.tileset);
|
||||||
|
let td = field.getElement();
|
||||||
row.push(field);
|
row.push(field);
|
||||||
tr.appendChild(field.getElement());
|
tr.appendChild(td);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index === undefined || index >= this.tilesY - 1) {
|
if (index === undefined || index >= this.tilesY - 1) {
|
||||||
|
@ -106,8 +99,6 @@ export default class Terrain
|
||||||
|
|
||||||
addColumns(index, quantity = 1)
|
addColumns(index, quantity = 1)
|
||||||
{
|
{
|
||||||
console.log(this.fields);
|
|
||||||
|
|
||||||
for (let c = 0; c < quantity; c++) {
|
for (let c = 0; c < quantity; c++) {
|
||||||
this._insertColumn(index);
|
this._insertColumn(index);
|
||||||
this.tilesX++;
|
this.tilesX++;
|
||||||
|
@ -115,15 +106,7 @@ export default class Terrain
|
||||||
this.targetTileX = this.targetTileX === undefined ? undefined : this.targetTileX + 1;
|
this.targetTileX = this.targetTileX === undefined ? undefined : this.targetTileX + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let y = 0; y < this.tilesY; y++) {
|
|
||||||
for (let x = index; x < this.tilesX; x++) {
|
|
||||||
this.fields[y][x].x += quantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.htmlElement.style.width = this.tileset.getTileWidth() * this.tilesX + 'px';
|
this.htmlElement.style.width = this.tileset.getTileWidth() * this.tilesX + 'px';
|
||||||
|
|
||||||
console.log(this.fields);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_insertColumn(index = undefined)
|
_insertColumn(index = undefined)
|
||||||
|
@ -200,11 +183,10 @@ export default class Terrain
|
||||||
|
|
||||||
static createFromJson(levelData)
|
static createFromJson(levelData)
|
||||||
{
|
{
|
||||||
const graphicSet = GraphicSet[levelData.tileset];
|
let graphicSet = GraphicSet[levelData.tileset];
|
||||||
|
|
||||||
const tileset = new Tileset(levelData.tileset);
|
let tileset = new Tileset(levelData.tileset);
|
||||||
const terrain = new Terrain(tileset, levelData.columns, levelData.rows, graphicSet.backgroundColor);
|
let terrain = new Terrain(tileset, levelData.columns, levelData.rows, graphicSet.backgroundColor);
|
||||||
terrain.backgroundImage = graphicSet.backgroundImage ?? undefined;
|
|
||||||
|
|
||||||
for (let y = 0; y < levelData.rows; y++) {
|
for (let y = 0; y < levelData.rows; y++) {
|
||||||
for (let x = 0; x < levelData.columns; x++) {
|
for (let x = 0; x < levelData.columns; x++) {
|
||||||
|
@ -220,60 +202,4 @@ export default class Terrain
|
||||||
|
|
||||||
return terrain;
|
return terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFieldNeighbours(field)
|
|
||||||
{
|
|
||||||
const neighbours = [];
|
|
||||||
|
|
||||||
for (let x = Math.max(0, field.x - 1); x < Math.min(this.tilesX, field.x + 2); x++) {
|
|
||||||
for (let y = Math.max(0, field.y - 1); y < Math.min(this.tilesY, field.y + 2); y++) {
|
|
||||||
if (field.x === x && field.y === y) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
neighbours.push(this.fields[y][x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return neighbours;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasFieldNeighbour(field, offsetX, offsetY)
|
|
||||||
{
|
|
||||||
const x = field.x + offsetX;
|
|
||||||
const y = field.y + offsetY;
|
|
||||||
|
|
||||||
if (x < 0 || x > this.tilesX - 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < 0 || y > this.tilesY - 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.fields[y][x].index > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFieldNeighbourCode(field)
|
|
||||||
{
|
|
||||||
let code = '';
|
|
||||||
|
|
||||||
if (!this.hasFieldNeighbour(field, -1, 0)) {
|
|
||||||
code += 'l';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hasFieldNeighbour(field, 0, -1)) {
|
|
||||||
code += 't';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hasFieldNeighbour(field, 1, 0)) {
|
|
||||||
code += 'r';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hasFieldNeighbour(field, 0, 1)) {
|
|
||||||
code += 'b';
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -10,7 +10,6 @@ export default class Tileset
|
||||||
this.image.src = '../' + Setting.TILESET_LOCATION + GraphicSet[this.setId].tileset;
|
this.image.src = '../' + Setting.TILESET_LOCATION + GraphicSet[this.setId].tileset;
|
||||||
this.tiles = GraphicSet[this.setId].tiles;
|
this.tiles = GraphicSet[this.setId].tiles;
|
||||||
this.scale = GraphicSet[this.setId].scale;
|
this.scale = GraphicSet[this.setId].scale;
|
||||||
this.primaryTiles = GraphicSet[this.setId].primaryTiles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getWidth()
|
getWidth()
|
||||||
|
@ -32,16 +31,4 @@ export default class Tileset
|
||||||
{
|
{
|
||||||
return this.image.height * this.scale;
|
return this.image.height * this.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasExtendedTiles()
|
|
||||||
{
|
|
||||||
return GraphicSet[this.setId].tiles > GraphicSet[this.setId].primaryTiles ;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTileIndexFactor(code)
|
|
||||||
{
|
|
||||||
const CODES = ['ltr', 't', 'r', 'b', 'l', 'lt', 'tr', 'ltb', 'tb', 'trb', 'lb', 'rb', 'ltrb', 'lr', 'lrb'];
|
|
||||||
|
|
||||||
return CODES.indexOf(code) + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,156 +1,54 @@
|
||||||
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";
|
|
||||||
import {IntelligentBrushSwitch} from "./menu/IntelligentBrushSwitch.js";
|
|
||||||
|
|
||||||
export default class Tilorswift
|
export default class Tilorswift
|
||||||
{
|
{
|
||||||
constructor(level) {
|
static getLevelAsJson(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.intelligentBrushSwitch = new IntelligentBrushSwitch(this.tilesetPicker, this.brush);
|
|
||||||
this.widgetBar.addWidget(this.intelligentBrushSwitch);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
getLevelAsJson()
|
|
||||||
{
|
{
|
||||||
let matrix = [];
|
let matrix = [];
|
||||||
|
|
||||||
for (let y = 0; y < this.level.terrain.fields.length; y++) {
|
for (let y = 0; y < level.terrain.fields.length; y++) {
|
||||||
let row = [];
|
let row = [];
|
||||||
|
|
||||||
for (let x = 0; x < this.level.terrain.fields[y].length; x++) {
|
for (let x = 0; x < level.terrain.fields[y].length; x++) {
|
||||||
row.push(this.level.terrain.fields[y][x].index);
|
row.push(level.terrain.fields[y][x].index);
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix.push(row);
|
matrix.push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
tileset: this.level.getTilesetId(),
|
tileset: level.getTilesetId(),
|
||||||
rows: this.level.getRows(),
|
rows: level.getRows(),
|
||||||
columns: this.level.getColumns(),
|
columns: level.getColumns(),
|
||||||
startX: this.level.getStartX(),
|
startX: level.getStartX(),
|
||||||
startY: this.level.getStartY(),
|
startY: level.getStartY(),
|
||||||
targetX: this.level.getTargetX(),
|
targetX: level.getTargetX(),
|
||||||
targetY: this.level.getTargetY(),
|
targetY: level.getTargetY(),
|
||||||
gravity: this.level.gravity,
|
gravity: level.gravity,
|
||||||
matrix: matrix,
|
matrix: matrix,
|
||||||
};
|
};
|
||||||
|
|
||||||
return JSON.stringify(data);
|
return JSON.stringify(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
openLevelFromFile()
|
static saveLevelToFile(level)
|
||||||
{
|
{
|
||||||
const dialog = new LoadLevelDialog();
|
if (!level.hasEntrancePoint()) {
|
||||||
dialog.onLoad = (json) => {
|
|
||||||
this.tileset = new Tileset(JSON.parse(json).tileset);
|
|
||||||
this.level = Level.createFromJson(json);
|
|
||||||
this.loadLevel();
|
|
||||||
dialog.close();
|
|
||||||
}
|
|
||||||
dialog.openFileBrowser();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
this.initializeIntelligentBrushWidget();
|
|
||||||
}
|
|
||||||
|
|
||||||
saveLevelToFile()
|
|
||||||
{
|
|
||||||
if (!this.level.hasEntrancePoint()) {
|
|
||||||
alert('Es muss ein Startpunkt definiert sein!');
|
alert('Es muss ein Startpunkt definiert sein!');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.level.hasTargetPoint()) {
|
if (!level.hasTargetPoint()) {
|
||||||
alert('Es muss ein Zielpunkt definiert sein!');
|
alert('Es muss ein Zielpunkt definiert sein!');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename = prompt('Dateiname', 'terrain.json');
|
let filename = prompt('Dateiname', 'terrain.json');
|
||||||
|
|
||||||
if (filename === null) {
|
if (filename === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const json = this.getLevelAsJson(level);
|
let json = Tilorswift.getLevelAsJson(level);
|
||||||
const download = document.createElement('a');
|
let download = document.createElement('a');
|
||||||
|
|
||||||
download.setAttribute('download', filename);
|
download.setAttribute('download', filename);
|
||||||
download.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(json));
|
download.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(json));
|
||||||
|
@ -159,208 +57,4 @@ export default class Tilorswift
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeIntelligentBrushWidget()
|
|
||||||
{
|
|
||||||
if (this.tileset.hasExtendedTiles()) {
|
|
||||||
this.intelligentBrushSwitch.enable();
|
|
||||||
this.intelligentBrushSwitch.switchOn();
|
|
||||||
} else {
|
|
||||||
this.intelligentBrushSwitch.switchOff();
|
|
||||||
this.intelligentBrushSwitch.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createNewTerrain(tilesetIndex, tilesX, tilesY)
|
|
||||||
{
|
|
||||||
this.tileset = new Tileset(tilesetIndex);
|
|
||||||
this.level.terrain = new Terrain(this.tileset, tilesX, tilesY, GraphicSet[tilesetIndex].backgroundColor);
|
|
||||||
this.level.setGravity(GraphicSet[tilesetIndex].gravity);
|
|
||||||
document.body.style.backgroundColor = this.level.getBackgroundColor();
|
|
||||||
|
|
||||||
if (GraphicSet[tilesetIndex].backgroundImage !== null) {
|
|
||||||
document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[tilesetIndex].backgroundImage + '")';
|
|
||||||
} else {
|
|
||||||
document.body.style.backgroundImage = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.map.innerHTML = '';
|
|
||||||
this.map.appendChild(this.level.terrain.getElement());
|
|
||||||
|
|
||||||
this.tilesetPicker.reloadTileset(this.tileset);
|
|
||||||
|
|
||||||
this.initializeIntelligentBrushWidget();
|
|
||||||
}
|
|
||||||
|
|
||||||
addTerrain(field)
|
|
||||||
{
|
|
||||||
if (this.brush.isIntelligent) {
|
|
||||||
const index = this.level.terrain.brushTileIndex + this.tileset.primaryTiles * this.tileset.getTileIndexFactor(
|
|
||||||
this.level.terrain.getFieldNeighbourCode(field)
|
|
||||||
);
|
|
||||||
|
|
||||||
field.setIndex(index);
|
|
||||||
|
|
||||||
this.updateNeighbours(field);
|
|
||||||
} else {
|
|
||||||
field.setIndex(this.level.terrain.brushTileIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNeighbours(field)
|
|
||||||
{
|
|
||||||
for (const neighbour of this.level.terrain.getFieldNeighbours(field)) {
|
|
||||||
if (neighbour.index === -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const neighbourIndex = (neighbour.index % this.tileset.primaryTiles) + this.tileset.primaryTiles * this.tileset.getTileIndexFactor(
|
|
||||||
this.level.terrain.getFieldNeighbourCode(neighbour)
|
|
||||||
);
|
|
||||||
|
|
||||||
neighbour.setIndex(neighbourIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeTerrain(field)
|
|
||||||
{
|
|
||||||
field.setIndex(-1);
|
|
||||||
|
|
||||||
if (this.brush.isIntelligent) {
|
|
||||||
for (const neighbour of this.level.terrain.getFieldNeighbours(field)) {
|
|
||||||
this.updateNeighbours(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListeners()
|
|
||||||
{
|
|
||||||
window.addEventListener(
|
|
||||||
TilorswiftEvent.FIELD_CLICKED,
|
|
||||||
(event) => {
|
|
||||||
if (this.brush.mode === BrushMode.TERRAIN && !event.getField().isEntrancePoint) {
|
|
||||||
switch (event.button) {
|
|
||||||
case 0:
|
|
||||||
this.addTerrain(event.getField());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this.removeTerrain(event.getField());
|
|
||||||
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) {
|
|
||||||
this.addTerrain(event.getField());
|
|
||||||
} 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.createNewTerrain(event.tilesetIndex, event.tilesX, event.tilesY);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/* 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()) {
|
|
||||||
window.dispatchEvent(new TilorswiftSavedEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -100,12 +100,7 @@ export default class Dialog
|
||||||
|
|
||||||
let htmlThumbnail = document.createElement('div');
|
let htmlThumbnail = document.createElement('div');
|
||||||
htmlThumbnail.classList.add('tileset-thumbnail');
|
htmlThumbnail.classList.add('tileset-thumbnail');
|
||||||
|
htmlThumbnail.style.backgroundImage = 'url("../' + Setting.TILESET_LOCATION + graphicSet.tileset + '")';
|
||||||
const image = new Image();
|
|
||||||
image.src = '../' + Setting.TILESET_LOCATION + graphicSet.tileset;
|
|
||||||
|
|
||||||
htmlThumbnail.style.backgroundImage = 'url(' + image.src + ')';
|
|
||||||
htmlThumbnail.style.backgroundPositionX = -(image.width / graphicSet.tiles) * graphicSet.tilePreview + 'px';
|
|
||||||
htmlTilesetElement.appendChild(htmlThumbnail);
|
htmlTilesetElement.appendChild(htmlThumbnail);
|
||||||
|
|
||||||
let htmlTitleElement = document.createElement('div');
|
let htmlTitleElement = document.createElement('div');
|
||||||
|
@ -117,9 +112,7 @@ export default class Dialog
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
htmlListElement.style.display = 'none';
|
htmlListElement.style.display = 'none';
|
||||||
htmlAvatarElement.style.backgroundImage = 'url(' + image.src + ')';
|
htmlAvatarElement.style.backgroundImage = 'url("../' + Setting.TILESET_LOCATION + GraphicSet[index].tileset + '")';
|
||||||
htmlAvatarElement.style.backgroundPositionX = -96 * graphicSet.tilePreview + 'px';
|
|
||||||
|
|
||||||
window.dispatchEvent(new TilorswiftTilesetSelectedEvent(index));
|
window.dispatchEvent(new TilorswiftTilesetSelectedEvent(index));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -133,31 +126,8 @@ export default class Dialog
|
||||||
return htmlElement;
|
return htmlElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
createFileInput(types = [])
|
|
||||||
{
|
|
||||||
let input = document.createElement('input');
|
|
||||||
input.type = 'file';
|
|
||||||
|
|
||||||
if (types.length > 0) {
|
|
||||||
for (const t in types) {
|
|
||||||
types[t] = '.' + types[t]
|
|
||||||
}
|
|
||||||
|
|
||||||
input.accept = types.join(', ');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.inputAreaElement.appendChild(input);
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessage(message)
|
setMessage(message)
|
||||||
{
|
{
|
||||||
this.messageElement.innerText = message;
|
this.messageElement.innerText = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
close()
|
|
||||||
{
|
|
||||||
this.htmlElement.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default class DialogGravity extends Dialog
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.setMessage('Gravitation einstellen');
|
this.setMessage('Gravitation einstellen');
|
||||||
this.inputGravity = this.createInputNumber('Stärke', gravity, 0, 10, 0.001);
|
this.inputGravity = this.createInputNumber('Stärke', gravity, 0, 10, 0.01);
|
||||||
this.createButton('Abbrechen');
|
this.createButton('Abbrechen');
|
||||||
this.buttonOk = this.createButton('OK');
|
this.buttonOk = this.createButton('OK');
|
||||||
this.buttonOk.addEventListener(
|
this.buttonOk.addEventListener(
|
||||||
|
|
|
@ -3,7 +3,6 @@ const TilorswiftEvent = {
|
||||||
FIELD_ENTERED: 'fieldEntered',
|
FIELD_ENTERED: 'fieldEntered',
|
||||||
BUTTON_TILE_CLICKED: 'buttonTileClicked',
|
BUTTON_TILE_CLICKED: 'buttonTileClicked',
|
||||||
MENU_SAVE_CLICKED: 'menuSaveClicked',
|
MENU_SAVE_CLICKED: 'menuSaveClicked',
|
||||||
MENU_OPEN_CLICKED: 'menuOpenClicked',
|
|
||||||
DIALOG_BUTTON_OK_CLICKED: 'dialogButtonOkClicked',
|
DIALOG_BUTTON_OK_CLICKED: 'dialogButtonOkClicked',
|
||||||
MENU_EDIT_CLICKED: 'menuEditClicked',
|
MENU_EDIT_CLICKED: 'menuEditClicked',
|
||||||
SAVED: 'saved',
|
SAVED: 'saved',
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import TilorswiftEvent from "./TilorswiftEvent.js";
|
|
||||||
|
|
||||||
export class TilorswiftMenuOpenCLickedEvent extends Event
|
|
||||||
{
|
|
||||||
constructor() {
|
|
||||||
super(TilorswiftEvent.MENU_OPEN_CLICKED);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
import Widget from "./Widget.js";
|
|
||||||
import {Switch} from "./Switch.js";
|
|
||||||
|
|
||||||
export class IntelligentBrushSwitch extends Widget
|
|
||||||
{
|
|
||||||
constructor(tilesetPicker, brush) {
|
|
||||||
super('Intelligenter Pinsel');
|
|
||||||
|
|
||||||
this.tilesetPicker = tilesetPicker;
|
|
||||||
this.brush = brush;
|
|
||||||
|
|
||||||
this.switch = new Switch();
|
|
||||||
this.switch.onToggle = (status) => {
|
|
||||||
if (this.isActive) {
|
|
||||||
this.setIntelligentBrush(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.htmlElement.appendChild(this.switch.htmlElement);
|
|
||||||
|
|
||||||
if (tilesetPicker.tileset.hasExtendedTiles()) {
|
|
||||||
this.setIntelligentBrush(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switchOn()
|
|
||||||
{
|
|
||||||
if (!this.switch.status) {
|
|
||||||
this.switch.toggle()
|
|
||||||
this.setIntelligentBrush(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switchOff()
|
|
||||||
{
|
|
||||||
if (this.switch.status) {
|
|
||||||
this.switch.toggle()
|
|
||||||
this.setIntelligentBrush(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setIntelligentBrush(status)
|
|
||||||
{
|
|
||||||
this.brush.isIntelligent = status;
|
|
||||||
this.tilesetPicker.updateExtendedTileVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
super.enable();
|
|
||||||
|
|
||||||
this.switch.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
super.disable();
|
|
||||||
|
|
||||||
this.switch.disable();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
export class Switch
|
|
||||||
{
|
|
||||||
constructor(status = false) {
|
|
||||||
this.htmlElement = document.createElement('div');
|
|
||||||
this.htmlElement.classList.add('switch');
|
|
||||||
this.slider = document.createElement('div');
|
|
||||||
this.slider.classList.add('switch-slider');
|
|
||||||
this.htmlElement.appendChild(this.slider);
|
|
||||||
this.status = status;
|
|
||||||
this.isEnabled = true;
|
|
||||||
|
|
||||||
this.updateSlider();
|
|
||||||
|
|
||||||
this.onToggle = () => {}
|
|
||||||
|
|
||||||
this.htmlElement.addEventListener(
|
|
||||||
'click',
|
|
||||||
() => {
|
|
||||||
if (!this.isEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.toggle();
|
|
||||||
this.onToggle(this.status);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle()
|
|
||||||
{
|
|
||||||
this.status = !this.status;
|
|
||||||
this.updateSlider();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSlider()
|
|
||||||
{
|
|
||||||
this.slider.classList.add(this.status ? 'switch-slider-on' : 'switch-slider-off');
|
|
||||||
this.slider.classList.remove(this.status ? 'switch-slider-off' : 'switch-slider-on');
|
|
||||||
}
|
|
||||||
|
|
||||||
enable()
|
|
||||||
{
|
|
||||||
this.isEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
disable()
|
|
||||||
{
|
|
||||||
this.isEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,13 +24,13 @@ export default class TilesetPickerWidget extends Widget
|
||||||
this.brush.mode = BrushMode.TERRAIN;
|
this.brush.mode = BrushMode.TERRAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTileset()
|
loadTileset()
|
||||||
{
|
{
|
||||||
for (let t = 0; t < this.tileset.tiles; t++) {
|
for (let t = 0; t < this.tileset.tiles; t++) {
|
||||||
const button = new ButtonTile(this.tileset, t);
|
let button = new ButtonTile(this.tileset, t);
|
||||||
this.htmlElementSelector.appendChild(button.getElement());
|
this.htmlElementSelector.appendChild(button.getElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ export default class TilesetPickerWidget extends Widget
|
||||||
|
|
||||||
createElementPicker()
|
createElementPicker()
|
||||||
{
|
{
|
||||||
const htmlElement = document.createElement('div');
|
let htmlElement = document.createElement('div');
|
||||||
htmlElement.id = 'tileset-picker';
|
htmlElement.id = 'tileset-picker';
|
||||||
htmlElement.style.width = this.tileset.getTileWidth() + 'px';
|
htmlElement.style.width = this.tileset.getTileWidth() + 'px';
|
||||||
htmlElement.style.height = this.tileset.getTileHeight() + 'px';
|
htmlElement.style.height = this.tileset.getTileHeight() + 'px';
|
||||||
|
@ -59,7 +59,7 @@ export default class TilesetPickerWidget extends Widget
|
||||||
|
|
||||||
createElementSelector()
|
createElementSelector()
|
||||||
{
|
{
|
||||||
const htmlElementSelector = document.createElement('div');
|
let htmlElementSelector = document.createElement('div');
|
||||||
htmlElementSelector.id = 'tileset-selector-widget';
|
htmlElementSelector.id = 'tileset-selector-widget';
|
||||||
htmlElementSelector.style.width = Math.ceil(Math.sqrt(this.tileset.tiles)) * this.tileset.getTileWidth() + 'px';
|
htmlElementSelector.style.width = Math.ceil(Math.sqrt(this.tileset.tiles)) * this.tileset.getTileWidth() + 'px';
|
||||||
htmlElementSelector.style.left = String(this.tileset.getTileWidth() + 1) + 'px';
|
htmlElementSelector.style.left = String(this.tileset.getTileWidth() + 1) + 'px';
|
||||||
|
@ -69,24 +69,12 @@ export default class TilesetPickerWidget extends Widget
|
||||||
|
|
||||||
setTile(index)
|
setTile(index)
|
||||||
{
|
{
|
||||||
this.htmlElement.style.backgroundPosition = -this.tileset.getTileWidth() * index + 'px ' + this.tileset.getTileHeight() + 'px';
|
let position = -this.tileset.getTileWidth() * index + 'px ' + this.tileset.getTileHeight() + 'px';
|
||||||
|
this.htmlElement.style.backgroundPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
getElement()
|
getElement()
|
||||||
{
|
{
|
||||||
return this.htmlElement;
|
return this.htmlElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateExtendedTileVisibility()
|
|
||||||
{
|
|
||||||
const firstExtendedTileIndex = this.tileset.tiles - (this.tileset.tiles - this.tileset.primaryTiles);
|
|
||||||
|
|
||||||
for (const index of this.htmlElementSelector.childNodes.keys()) {
|
|
||||||
if (index >= firstExtendedTileIndex) {
|
|
||||||
this.htmlElementSelector.childNodes.item(index).style.display = this.brush.isIntelligent
|
|
||||||
? 'none'
|
|
||||||
: 'inline-flex';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,23 +1,208 @@
|
||||||
|
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 Tilorswift from "./Tilorswift.js";
|
||||||
import Level from "../../js/Level.js";
|
import TilorswiftSavedEvent from "./events/TilorswiftSavedEvent.js";
|
||||||
import ImageLoader from "../../js/ImageLoader.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 GraphicSet from "../../js/GraphicSet.js";
|
import GraphicSet from "../../js/GraphicSet.js";
|
||||||
import Setting from "../../js/Setting.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";
|
||||||
|
|
||||||
const imageLoader = new ImageLoader();
|
let level = Level.createFromFile('../levels/moonbase.json');
|
||||||
|
|
||||||
for (const graphicSet of GraphicSet) {
|
if (GraphicSet[level.terrain.tileset.setId].backgroundImage !== null) {
|
||||||
imageLoader.addImage('../' + Setting.TILESET_LOCATION + graphicSet.tileset);
|
document.body.style.backgroundImage = 'url("../' + Setting.GRAPHICS_LOCATION + GraphicSet[level.getTilesetId()].backgroundImage + '")';
|
||||||
}
|
}
|
||||||
|
|
||||||
imageLoader.onLoad = () => {
|
let image = new Image();
|
||||||
Level.createFromFile(
|
image.src = '../' + Setting.TILESET_LOCATION + GraphicSet[level.terrain.tileset.setId].tileset;
|
||||||
'../levels/moonbase.json',
|
|
||||||
(level) => {
|
image.onload = function () {
|
||||||
const tilorswift = new Tilorswift(level);
|
document.body.style.backgroundColor = GraphicSet[level.terrain.tileset.setId].backgroundColor;
|
||||||
tilorswift.loadLevel();
|
|
||||||
tilorswift.init();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
imageLoader.load();
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -3,16 +3,6 @@
|
||||||
to { width: 512px; }
|
to { width: 512px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes switch-toggle-on {
|
|
||||||
from {left: 0}
|
|
||||||
to {left: 50%}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes switch-toggle-off {
|
|
||||||
from {left: 50%}
|
|
||||||
to {left: 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -122,9 +112,6 @@ body {
|
||||||
top: 0;
|
top: 0;
|
||||||
background-color: #cccccc;
|
background-color: #cccccc;
|
||||||
box-shadow: 20px 20px 20px rgba(0, 0, 0, 0.5);
|
box-shadow: 20px 20px 20px rgba(0, 0, 0, 0.5);
|
||||||
max-width: 1000%;
|
|
||||||
max-height: 500%;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#tileset-picker:hover > #tileset-selector-widget {
|
#tileset-picker:hover > #tileset-selector-widget {
|
||||||
|
@ -249,10 +236,6 @@ body {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="file"] {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-button {
|
.dialog-button {
|
||||||
padding: 5px 20px;
|
padding: 5px 20px;
|
||||||
background-color: grey;
|
background-color: grey;
|
||||||
|
@ -294,7 +277,7 @@ input[type="file"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tileset-thumbnail {
|
.tileset-thumbnail {
|
||||||
display: block;
|
display: table-cell;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
background-size: auto 100%;
|
background-size: auto 100%;
|
||||||
|
@ -309,34 +292,8 @@ input[type="file"] {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.switch {
|
/*
|
||||||
position: relative;
|
tr:hover > td > .selection {
|
||||||
border-radius: 16px;
|
opacity: 0.5;
|
||||||
border: 2px solid #333333;
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #777777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-slider {
|
|
||||||
position: absolute;
|
|
||||||
border-radius: 14px;
|
|
||||||
width: 50%;
|
|
||||||
height: 100%;
|
|
||||||
border: 1px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-slider-on {
|
|
||||||
left: 50%;
|
|
||||||
background-color: #2222aa;
|
|
||||||
animation-name: switch-toggle-on;
|
|
||||||
animation-duration: 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-slider-off {
|
|
||||||
left: 0;
|
|
||||||
background-color: #888888;
|
|
||||||
animation-name: switch-toggle-off;
|
|
||||||
animation-duration: 0.2s;
|
|
||||||
}
|
}
|
||||||
|
*/
|