New rain and thunder effects added
This commit is contained in:
parent
a583005814
commit
f6ebd8f3aa
@ -74,7 +74,7 @@ export class Game
|
|||||||
|
|
||||||
for (const effect of this.level.fullscreenEffects) {
|
for (const effect of this.level.fullscreenEffects) {
|
||||||
effect.update(timestamp);
|
effect.update(timestamp);
|
||||||
effect.render(this.context);
|
effect.render(this.context, this.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.userInterface.draw(this.context);
|
this.userInterface.draw(this.context);
|
||||||
@ -238,6 +238,10 @@ export class Game
|
|||||||
|
|
||||||
this.isPaused = false;
|
this.isPaused = false;
|
||||||
|
|
||||||
|
for (const effect of this.level.fullscreenEffects) {
|
||||||
|
effect.init();
|
||||||
|
}
|
||||||
|
|
||||||
window.requestAnimationFrame(loopFunction);
|
window.requestAnimationFrame(loopFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,15 @@ export class FullscreenEffect
|
|||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
update(timestamp)
|
update(timestamp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
render(context)
|
render(context, camera)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import {SnowEffect} from "./SnowEffect.js";
|
import {SnowEffect} from "./SnowEffect.js";
|
||||||
|
import {RainEffect} from "./RainEffect.js";
|
||||||
|
import {ThunderstormEffect} from "./ThunderstormEffect.js";
|
||||||
|
|
||||||
export class FullscreenEffectFactory
|
export class FullscreenEffectFactory
|
||||||
{
|
{
|
||||||
static EFFECTS = {
|
static EFFECTS = {
|
||||||
[SnowEffect.NAME]: SnowEffect,
|
[SnowEffect.NAME]: SnowEffect,
|
||||||
|
[RainEffect.NAME]: RainEffect,
|
||||||
|
[ThunderstormEffect.NAME]: ThunderstormEffect,
|
||||||
}
|
}
|
||||||
|
|
||||||
getEffect(name)
|
getEffect(name)
|
||||||
@ -16,7 +20,6 @@ export class FullscreenEffectFactory
|
|||||||
const names = [];
|
const names = [];
|
||||||
|
|
||||||
for (const name in FullscreenEffectFactory.EFFECTS) {
|
for (const name in FullscreenEffectFactory.EFFECTS) {
|
||||||
console.log(name);
|
|
||||||
names.push(name);
|
names.push(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
js/effects/RainEffect.js
Normal file
51
js/effects/RainEffect.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import {FullscreenEffect} from "./FullscreenEffect.js";
|
||||||
|
|
||||||
|
export class RainEffect extends FullscreenEffect
|
||||||
|
{
|
||||||
|
static NAME = 'rain';
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.image = new Image();
|
||||||
|
this.image.src = 'js/effects/rain.png';
|
||||||
|
this.sound = new Audio('js/effects/rain.mp3');
|
||||||
|
this.sound.loop = true;
|
||||||
|
this.offset = 0;
|
||||||
|
this.speed = 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
this.sound.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
update(timestamp)
|
||||||
|
{
|
||||||
|
super.update(timestamp);
|
||||||
|
|
||||||
|
this.offsetX = (timestamp * 0.65 * this.speed) % this.image.width;
|
||||||
|
this.offsetY = (timestamp * 1.5 * this.speed) % this.image.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(context, camera)
|
||||||
|
{
|
||||||
|
super.render(context, camera);
|
||||||
|
|
||||||
|
const cameraX = -1 * (camera.position.x % this.image.width);
|
||||||
|
const cameraY = -1 * (camera.position.y % this.image.height);
|
||||||
|
|
||||||
|
for (let y = -1; y < Math.ceil(context.canvas.height / this.image.height) + 1; y++) {
|
||||||
|
for (let x = -1; x < Math.ceil(context.canvas.width / this.image.width) + 1; x++) {
|
||||||
|
context.drawImage(
|
||||||
|
this.image,
|
||||||
|
cameraX + this.offsetX + this.image.width * x,
|
||||||
|
cameraY + this.offsetY + this.image.height * y,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,24 +7,44 @@ export class SnowEffect extends FullscreenEffect
|
|||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.audio = new Audio('js/effects/storm.mp3');
|
||||||
|
this.audio.loop = true;
|
||||||
this.image = new Image();
|
this.image = new Image();
|
||||||
this.image.src = 'js/effects/snow.png';
|
this.image.src = 'js/effects/snow.png';
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
|
this.speed = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
this.audio.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(timestamp)
|
update(timestamp)
|
||||||
{
|
{
|
||||||
super.update(timestamp);
|
super.update(timestamp);
|
||||||
this.offset = timestamp % 512;
|
|
||||||
|
this.offsetX = (timestamp * 0.65 * this.speed) % this.image.width;
|
||||||
|
this.offsetY = (timestamp * 1.5 * this.speed) % this.image.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(context)
|
render(context, camera)
|
||||||
{
|
{
|
||||||
super.render(context);
|
super.render(context);
|
||||||
|
|
||||||
for (let y = -1; y < Math.ceil(context.canvas.height / 512); y++) {
|
const cameraX = -1 * (camera.position.x % this.image.width);
|
||||||
for (let x = -1; x < Math.ceil(context.canvas.width / 512); x++) {
|
const cameraY = -1 * (camera.position.y % this.image.height);
|
||||||
context.drawImage(this.image, this.offset + 512 * x, this.offset + 512 * y);
|
|
||||||
|
for (let y = -1; y < Math.ceil(context.canvas.height / this.image.height) + 1; y++) {
|
||||||
|
for (let x = -1; x < Math.ceil(context.canvas.width / this.image.width) + 1; x++) {
|
||||||
|
context.drawImage(
|
||||||
|
this.image,
|
||||||
|
cameraX + this.offsetX + this.image.width * x,
|
||||||
|
cameraY + this.offsetY + this.image.height * y,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
js/effects/ThunderstormEffect.js
Normal file
88
js/effects/ThunderstormEffect.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import {FullscreenEffect} from "./FullscreenEffect.js";
|
||||||
|
|
||||||
|
export class ThunderstormEffect extends FullscreenEffect
|
||||||
|
{
|
||||||
|
static NAME = 'thunderstorm';
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.currentAlpha = 0.0;
|
||||||
|
this.nextFlash = undefined;
|
||||||
|
this.duration = 150;
|
||||||
|
this.sounds = [
|
||||||
|
new Audio('js/effects/thunder01.mp3'),
|
||||||
|
new Audio('js/effects/thunder02.mp3'),
|
||||||
|
new Audio('js/effects/thunder03.mp3'),
|
||||||
|
new Audio('js/effects/thunder04.mp3'),
|
||||||
|
];
|
||||||
|
this.currentSound = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffleSounds(iterations = 10)
|
||||||
|
{
|
||||||
|
const buffer = this.sounds.slice(0, this.sounds.length - 1);
|
||||||
|
|
||||||
|
for (let i = 0; i < iterations; i++) {
|
||||||
|
buffer.sort(
|
||||||
|
(a, b) => {
|
||||||
|
return 1 - Math.round(Math.random()) * 2
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = 1 + Math.round(Math.random() * (buffer.length - 1));
|
||||||
|
|
||||||
|
this.sounds = buffer.slice(0, index)
|
||||||
|
.concat([this.sounds[this.sounds.length - 1]])
|
||||||
|
.concat(buffer.slice(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
update(timestamp)
|
||||||
|
{
|
||||||
|
super.update(timestamp);
|
||||||
|
|
||||||
|
if (this.nextFlash > timestamp) {
|
||||||
|
this.currentAlpha = 0.0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timestamp < this.nextFlash + this.duration) {
|
||||||
|
const progress = (timestamp - this.nextFlash) / this.duration;
|
||||||
|
|
||||||
|
this.currentAlpha = Math.sin(Math.PI * progress) * 0.75;
|
||||||
|
} else {
|
||||||
|
const duration = 3000 + Math.round(Math.random() * 27000);
|
||||||
|
|
||||||
|
this.nextFlash = timestamp + duration;
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
if (this.currentSound === 0) {
|
||||||
|
this.shuffleSounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sounds[this.currentSound].currentTime = 0;
|
||||||
|
this.sounds[this.currentSound].play();
|
||||||
|
|
||||||
|
this.currentSound = (this.currentSound + 1) % this.sounds.length;
|
||||||
|
},
|
||||||
|
duration + 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(context, camera)
|
||||||
|
{
|
||||||
|
super.render(context, camera);
|
||||||
|
|
||||||
|
if (this.currentAlpha === 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.fillStyle = 'rgba(255, 255, 255, ' + this.currentAlpha + ')';
|
||||||
|
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
|
||||||
|
}
|
||||||
|
}
|
BIN
js/effects/rain.mp3
Normal file
BIN
js/effects/rain.mp3
Normal file
Binary file not shown.
BIN
js/effects/rain.png
Normal file
BIN
js/effects/rain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
js/effects/storm.mp3
Normal file
BIN
js/effects/storm.mp3
Normal file
Binary file not shown.
BIN
js/effects/thunder01.mp3
Normal file
BIN
js/effects/thunder01.mp3
Normal file
Binary file not shown.
BIN
js/effects/thunder02.mp3
Normal file
BIN
js/effects/thunder02.mp3
Normal file
Binary file not shown.
BIN
js/effects/thunder03.mp3
Normal file
BIN
js/effects/thunder03.mp3
Normal file
Binary file not shown.
BIN
js/effects/thunder04.mp3
Normal file
BIN
js/effects/thunder04.mp3
Normal file
Binary file not shown.
@ -30,12 +30,16 @@ 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 {SnowEffect} from "../../js/effects/SnowEffect.js";
|
||||||
|
import {RainEffect} from "../../js/effects/RainEffect.js";
|
||||||
|
import {ThunderstormEffect} from "../../js/effects/ThunderstormEffect.js";
|
||||||
import {FullscreenEffectFactory} from "../../js/effects/FullscreenEffectFactory.js";
|
import {FullscreenEffectFactory} from "../../js/effects/FullscreenEffectFactory.js";
|
||||||
|
|
||||||
export default class Tilorswift
|
export default class Tilorswift
|
||||||
{
|
{
|
||||||
static EFFECT_NAMES = {
|
static EFFECT_NAMES = {
|
||||||
[SnowEffect.NAME]: 'Schnee',
|
[SnowEffect.NAME]: 'Schnee',
|
||||||
|
[RainEffect.NAME]: 'Regen',
|
||||||
|
[ThunderstormEffect.NAME]: 'Gewitter',
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(level) {
|
constructor(level) {
|
||||||
@ -320,9 +324,7 @@ export default class Tilorswift
|
|||||||
new DialogEffects(
|
new DialogEffects(
|
||||||
FullscreenEffectFactory.getNames(),
|
FullscreenEffectFactory.getNames(),
|
||||||
effects,
|
effects,
|
||||||
{
|
Tilorswift.EFFECT_NAMES,
|
||||||
[SnowEffect.NAME]: 'Schnee',
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user