UNPKG

pxt-common-packages

Version:
157 lines (145 loc) 5.3 kB
namespace effects { //% fixedInstances export class ImageEffect implements BackgroundEffect { // If used in an animation, this should be used as the default delay between method calls protected preferredDelay: number; protected effect: (image: Image, fastRandom?: Math.FastRandom) => void; protected fastRandom: Math.FastRandom; private times: number; constructor(defaultRate: number, effectFactory: (image: Image, fastRandom?: Math.FastRandom) => void) { this.effect = effectFactory; this.fastRandom = new Math.FastRandom(); this.preferredDelay = defaultRate; this.times = undefined; } /** * Apply this effect to the image of the current sprite * @param sprite */ applyTo(sprite: Sprite) { if (!sprite || !sprite.image) return; const clonedImage = sprite.image.clone(); this.change(clonedImage) sprite.setImage(clonedImage); } /** * Change the given image with this effect * @param input */ change(input: Image) { this.effect(input, this.fastRandom); } /** * Make this effect occur repeatedly on the background image * @param times number of times effect should occur * @param delay delay between instances of the effect */ startScreenEffect(times?: number, delay?: number): void { if (!game.currentScene().background.hasBackgroundImage()) return; const wasRunning = this.times != undefined; this.times = times ? times : 15; if (!wasRunning) { control.runInParallel(() => { while (this.times > 0) { this.change(scene.backgroundImage()); pause(delay ? delay : this.preferredDelay); --this.times; } this.times = undefined; }); } } } //% fixedInstance whenUsed block="dissolve" export const dissolve = new ImageEffect(100, (input: Image, r: Math.FastRandom) => { for (let i = (input.width * input.height) >> 5; i > 0; --i) { const x = r.randomRange(0, input.width) const y = r.randomRange(0, input.height) const w = r.randomRange(1, 3); const h = r.randomRange(1, 3); input.drawRect(x, y, w, h, 0); } }); //% fixedInstance whenUsed block="melt" export const melt = new ImageEffect(125, (input: Image, r: Math.FastRandom) => { const rounds = (input.width * input.height) >> 5; for (let j = 0; j < rounds; ++j) { let x = r.randomRange(0, input.width - 1) let y = r.randomRange(0, input.height - 3) let c = input.getPixel(x, y) input.setPixel(x, y + 1, c) input.setPixel(x, y + 2, c) } }); //% fixedInstance whenUsed block="slash" export const slash = new ImageEffect(125, (input: Image, r: Math.FastRandom) => { const rounds = 12; for (let j = 0; j < rounds; ++j) { let horizontal = r.randomBool(); let length = r.randomRange(5, 50); let x = r.randomRange(0, input.width - (horizontal ? length : 1)); let y = r.randomRange(0, input.height - (horizontal ? 3 : length)); input.drawLine(x, y, horizontal ? x + length : x, horizontal ? y : y + length, 1); } }); //% fixedInstance whenUsed block="splatter" export const splatter = new ImageEffect(125, (input: Image, r: Math.FastRandom) => { const imgs: Image[] = [ img` . 1 . 1 1 1 . 1 1`, img` . 1 1 . 1 1 1 1 . 1 1 .`, img` . 1 1 1 . 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 . 1 1 1 .`, img` . . 1 1 . . . 1 1 1 1 . 1 1 1 1 1 1 1 1 1 1 1 1 . 1 1 1 1 . . . 1 1 . .`, img` . . 1 1 1. . . 1 1 1 1 1 . 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 . 1 1 1 1 1 . . . 1 1 1. .`, img` . . 1 1 1 1 . . . 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 . . . 1 1 1 1 . .`, img` . . . 1 1 1 . . . . . 1 1 1 1 1 . . . 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 . . . 1 1 1 1 1 . . . . . 1 1 1 . . .`, ]; const rounds = 12; for (let j = 0; j < rounds; ++j) { const im = imgs[r.randomRange(0, imgs.length - 1)]; const x = r.randomRange(0, input.width - im.width / 2); const y = r.randomRange(0, input.height - im.height / 2); input.drawTransparentImage(im, x, y); } }); }