Snow fullscreen effect implemented

This commit is contained in:
Mal 2024-12-08 16:53:56 +01:00
parent 4bf46d99fd
commit 4b85a314c4
13 changed files with 250 additions and 2 deletions

View File

@ -71,7 +71,13 @@ export class Game
this.architecture.draw(this.context, this.camera); this.architecture.draw(this.context, this.camera);
this.mrCroc.draw(this.context, this.camera); this.mrCroc.draw(this.context, this.camera);
this.gisela.draw(this.context, this.camera); this.gisela.draw(this.context, this.camera);
this.userInterface.draw(this.context);
for (const effect of this.level.fullscreenEffects) {
effect.update(timestamp);
effect.render(this.context);
}
this.userInterface.draw(this.context);
this.lastRendered = timestamp; this.lastRendered = timestamp;
} }

View File

@ -1,5 +1,6 @@
import FileLoader from "./FileLoader.js"; import FileLoader from "./FileLoader.js";
import Terrain from "../tilorswift/js/Terrain.js"; import Terrain from "../tilorswift/js/Terrain.js";
import {FullscreenEffectFactory} from "./effects/FullscreenEffectFactory.js";
export default class Level export default class Level
{ {
@ -8,6 +9,7 @@ export default class Level
constructor(terrain) constructor(terrain)
{ {
this.terrain = terrain; this.terrain = terrain;
this.fullscreenEffects = [];
this.gravity = 2.0; this.gravity = 2.0;
} }
@ -83,7 +85,6 @@ export default class Level
const json = JSON.parse(data); const json = JSON.parse(data);
const level = new Level(Terrain.createFromJson(json)); const level = new Level(Terrain.createFromJson(json));
level.setGravity(json.gravity / Level.FACTOR_GRAVITY); level.setGravity(json.gravity / Level.FACTOR_GRAVITY);
callback(level); callback(level);
} }
loader.loadContent(); loader.loadContent();
@ -97,6 +98,16 @@ export default class Level
const level = new Level(terrain); const level = new Level(terrain);
level.setGravity(data.gravity / Level.FACTOR_GRAVITY); level.setGravity(data.gravity / Level.FACTOR_GRAVITY);
if (data.hasOwnProperty('effects')) {
const effectFactory = new FullscreenEffectFactory();
for (const effect of data.effects) {
level.fullscreenEffects.push(
effectFactory.getEffect(effect)
);
}
}
return level; return level;
} }
} }

View File

@ -0,0 +1,22 @@
export class FullscreenEffect
{
static NAME = '';
constructor(canvas)
{
this.canvas = canvas;
}
update(timestamp)
{
}
render(context)
{
}
getName()
{
return this.constructor.NAME;
}
}

View File

@ -0,0 +1,27 @@
import {SnowEffect} from "./SnowEffect.js";
export class FullscreenEffectFactory
{
static EFFECTS = {
[SnowEffect.NAME]: SnowEffect,
}
getEffect(name)
{
return new FullscreenEffectFactory.EFFECTS[name]();
}
static getNames()
{
const names = [];
for (const name in FullscreenEffectFactory.EFFECTS) {
console.log(name);
names.push(name);
}
console.log(names);
return names;
}
}

31
js/effects/SnowEffect.js Normal file
View File

@ -0,0 +1,31 @@
import {FullscreenEffect} from "./FullscreenEffect.js";
export class SnowEffect extends FullscreenEffect
{
static NAME = 'snow';
constructor()
{
super();
this.image = new Image();
this.image.src = '/js/effects/snow.png';
this.offset = 0;
}
update(timestamp)
{
super.update(timestamp);
this.offset = timestamp % 512;
}
render(context)
{
super.render(context);
for (let y = -1; y < Math.ceil(context.canvas.height / 512); y++) {
for (let x = -1; x < Math.ceil(context.canvas.width / 512); x++) {
context.drawImage(this.image, this.offset + 512 * x, this.offset + 512 * y);
}
}
}
}

BIN
js/effects/snow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -17,19 +17,27 @@ import TilorswiftMenuSaveClickedEvent from "./events/TilorswiftMenuSaveClickedEv
import TilorswiftAddRowsClickedEvent from "./events/TilorswiftAddRowsClickedEvent.js"; import TilorswiftAddRowsClickedEvent from "./events/TilorswiftAddRowsClickedEvent.js";
import TilorswiftAddColumnsClickedEvent from "./events/TilorswiftAddColumnsClickedEvent.js"; import TilorswiftAddColumnsClickedEvent from "./events/TilorswiftAddColumnsClickedEvent.js";
import TilorswiftMenuGravityClickedEvent from "./events/TilorswiftMenuGravityClickedEvent.js"; import TilorswiftMenuGravityClickedEvent from "./events/TilorswiftMenuGravityClickedEvent.js";
import TilorswiftMenuEffectsClickedEvent from "./events/TilorswiftMenuEffectsClickedEvent.js";
import TilorswiftEvent from "./events/TilorswiftEvent.js"; import TilorswiftEvent from "./events/TilorswiftEvent.js";
import BrushMode from "./BrushMode.js"; import BrushMode from "./BrushMode.js";
import DialogNewTerrain from "./dialog/DialogNewTerrain.js"; import DialogNewTerrain from "./dialog/DialogNewTerrain.js";
import DialogGravity from "./dialog/DialogGravity.js"; import DialogGravity from "./dialog/DialogGravity.js";
import DialogEffects from "./dialog/DialogEffects.js";
import DialogAddRows from "./dialog/DialogAddRows.js"; import DialogAddRows from "./dialog/DialogAddRows.js";
import DialogAddColumns from "./dialog/DialogAddColumns.js"; import DialogAddColumns from "./dialog/DialogAddColumns.js";
import Terrain from "./Terrain.js"; import Terrain from "./Terrain.js";
import TilorswiftSavedEvent from "./events/TilorswiftSavedEvent.js"; import TilorswiftSavedEvent from "./events/TilorswiftSavedEvent.js";
import Level from "../../js/Level.js"; import Level from "../../js/Level.js";
import {IntelligentBrushSwitch} from "./menu/IntelligentBrushSwitch.js"; import {IntelligentBrushSwitch} from "./menu/IntelligentBrushSwitch.js";
import {SnowEffect} from "../../js/effects/SnowEffect.js";
import {FullscreenEffectFactory} from "../../js/effects/FullscreenEffectFactory.js";
export default class Tilorswift export default class Tilorswift
{ {
static EFFECT_NAMES = {
[SnowEffect.NAME]: 'Schnee',
}
constructor(level) { constructor(level) {
this.level = level; this.level = level;
this.map = document.getElementById('map'); this.map = document.getElementById('map');
@ -65,6 +73,7 @@ export default class Tilorswift
const menuLevel = new MenuGroup('Level'); const menuLevel = new MenuGroup('Level');
menuLevel.addMenuEntry(new MainMenuEntry('Gravitation...', TilorswiftMenuGravityClickedEvent)); menuLevel.addMenuEntry(new MainMenuEntry('Gravitation...', TilorswiftMenuGravityClickedEvent));
menuLevel.addMenuEntry(new MainMenuEntry('Effekte...', TilorswiftMenuEffectsClickedEvent));
this.mainbar.addMenuGroup(menuLevel); this.mainbar.addMenuGroup(menuLevel);
document.body.appendChild(this.mainbar.getElement()); document.body.appendChild(this.mainbar.getElement());
@ -96,6 +105,7 @@ export default class Tilorswift
targetY: this.level.getTargetY(), targetY: this.level.getTargetY(),
gravity: this.level.gravity, gravity: this.level.gravity,
matrix: matrix, matrix: matrix,
effects: this.level.fullscreenEffects.map((effect) => {return effect.getName()}),
}; };
return JSON.stringify(data); return JSON.stringify(data);
@ -105,6 +115,7 @@ export default class Tilorswift
{ {
const dialog = new LoadLevelDialog(); const dialog = new LoadLevelDialog();
dialog.onLoad = (json) => { dialog.onLoad = (json) => {
console.log(json);
this.tileset = new Tileset(JSON.parse(json).tileset); this.tileset = new Tileset(JSON.parse(json).tileset);
this.level = Level.createFromJson(json); this.level = Level.createFromJson(json);
this.loadLevel(); this.loadLevel();
@ -297,6 +308,25 @@ export default class Tilorswift
} }
); );
window.addEventListener(
TilorswiftEvent.MENU_EFFECTS_CLICKED,
() => {
const effects = [];
for (const effect of this.level.fullscreenEffects) {
effects.push(effect.getName());
}
new DialogEffects(
FullscreenEffectFactory.getNames(),
effects,
{
[SnowEffect.NAME]: 'Schnee',
}
);
}
);
window.addEventListener( window.addEventListener(
TilorswiftEvent.ADD_ROWS_CLICKED, TilorswiftEvent.ADD_ROWS_CLICKED,
() => { () => {
@ -318,6 +348,21 @@ export default class Tilorswift
} }
); );
window.addEventListener(
TilorswiftEvent.EFFECTS_UPDATED,
(event) => {
this.level.fullscreenEffects = [];
const effectFactory = new FullscreenEffectFactory();
for (const effectName of event.effectNames) {
this.level.fullscreenEffects.push(
effectFactory.getEffect(effectName)
);
}
}
);
window.addEventListener( window.addEventListener(
TilorswiftEvent.ADD_ROWS, TilorswiftEvent.ADD_ROWS,
(event) => { (event) => {

View File

@ -1,6 +1,7 @@
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 TilorswiftTilesetSelectedEvent from "../events/TilorswiftTilesetSelectedEvent.js"; import TilorswiftTilesetSelectedEvent from "../events/TilorswiftTilesetSelectedEvent.js";
import {Checkbox} from "./elements/Checkbox.js";
export default class Dialog export default class Dialog
{ {
@ -66,6 +67,16 @@ export default class Dialog
return htmlElementInput; return htmlElementInput;
} }
createCheckbox(label, value, isChecked = false, onClick = () => {})
{
const checkbox = new Checkbox(label, value, isChecked);
checkbox.onClick = onClick;
this.inputAreaElement.appendChild(checkbox.htmlElement);
return checkbox;
}
createTilesetSelector() createTilesetSelector()
{ {
let htmlElement = document.createElement('div'); let htmlElement = document.createElement('div');
@ -133,6 +144,8 @@ export default class Dialog
return htmlElement; return htmlElement;
} }
createFileInput(types = []) createFileInput(types = [])
{ {
let input = document.createElement('input'); let input = document.createElement('input');

View File

@ -0,0 +1,45 @@
import Dialog from "./Dialog.js";
import TilorswiftEffectsUpdatedEvent from "../events/TilorswiftEffectsUpdatedEvent.js";
export default class DialogEffects extends Dialog
{
constructor(effects, checked, translations)
{
super();
this.setMessage('Effekte');
this.effects = [];
for (const effect of effects) {
const checkbox = this.createCheckbox(
translations[effect],
effect,
checked.indexOf(effect) !== -1,
() => {
console.log(checkbox.name, 'is', checkbox.isChecked());
}
);
this.effects.push(checkbox);
this.inputAreaElement.appendChild(checkbox.htmlElement);
}
this.createButton('Abbrechen');
this.buttonOk = this.createButton('OK');
this.buttonOk.addEventListener(
'click',
() => {
const effectNames = [];
for (const effect of this.effects) {
if (effect.isChecked()) {
effectNames.push(effect.name);
}
}
window.dispatchEvent(
new TilorswiftEffectsUpdatedEvent(effectNames)
);
}
)
}
}

View File

@ -0,0 +1,29 @@
export class Checkbox
{
constructor(label, name, isChecked = false)
{
this.name = name;
this.htmlElement = document.createElement('div');
this.onClick = () => {};
this.checkbox = document.createElement('input');
this.checkbox.type = 'checkbox';
this.checkbox.checked = isChecked;
this.checkbox.onclick = () => {
this.onClick();
}
this.htmlLabel = document.createElement('label');
this.htmlLabel.innerText = label;
this.htmlElement.appendChild(this.checkbox);
this.htmlElement.appendChild(this.htmlLabel);
}
isChecked()
{
return this.checkbox.checked;
}
}

View File

@ -0,0 +1,9 @@
import TilorswiftEvent from "./TilorswiftEvent.js";
export default class TilorswiftEffectsUpdatedEvent extends Event
{
constructor(effectNames) {
super(TilorswiftEvent.EFFECTS_UPDATED);
this.effectNames = effectNames;
}
}

View File

@ -17,6 +17,7 @@ const TilorswiftEvent = {
TILESET_SELECTED: 'tilesetSelected', TILESET_SELECTED: 'tilesetSelected',
MENU_GRAVITY_CLICKED: 'menuGravityClicked', MENU_GRAVITY_CLICKED: 'menuGravityClicked',
GRAVITY_UPDATED: 'gravityUpdated', GRAVITY_UPDATED: 'gravityUpdated',
MENU_EFFECTS_CLICKED: 'menuEffectsClicked',
}; };
export default TilorswiftEvent; export default TilorswiftEvent;

View File

@ -0,0 +1,9 @@
import TilorswiftEvent from "./TilorswiftEvent.js";
export default class TilorswiftMenuEffectsClickedEvent extends Event
{
constructor()
{
super(TilorswiftEvent.MENU_EFFECTS_CLICKED);
}
}