diff --git a/main.ts b/main.ts index 7ca4ca9..016f5ed 100644 --- a/main.ts +++ b/main.ts @@ -1,85 +1,48 @@ namespace SpriteKind { + //% isKind export const Shader = SpriteKind.create(); } //% color="#9e6eb8" icon="\uf0eb" namespace shader { - const shade_1 = hex`0F0D0A0B0E0408060C060B0C0F0B0C0F` - const shade_2 = hex`0F0B0F0C0C0E0C080F080C0F0F0C0F0F` - const shade_3 = hex`0F0C0F0F0F0C0F0C0F0C0F0F0F0F0F0F` - const shade_4 = hex`00000000000000000000000000000000` + /* blank shade */ + const shadeNull = (hex``) /* null shade */ + const shadeDark100 = (hex`00000000000000000000000000000000`) /* blank shade */ + /* light shade */ + const shadeLight100 = (hex`01010101010101010101010101010101`) /* very light */ + const shadeLight75 = (hex`0D01050101010101010101010D01010D`) /* medium light */ + const shadeLight50 = (hex`0B010301050109010901050D0301050B`) /* low light */ + const shadeLight25 = (hex`0C01040503010709060103030B01040C`) /* a little light */ + /* dark shade */ + const shadeDark20 = (hex`000D0A0B0E0408060C060B0C0F0B0C0F`) /* a little dark */ + const shadeDark40 = (hex`000B0C0C0C0E0C080F080C0F0F0C0F0F`) /* low dark */ + const shadeDark60 = (hex`000C0F0F0F0C0F0C0F0C0F0F0F0F0F0F`) /* medium dark */ + const shadeDark80 = (hex`000F0F0F0F0F0F0F0F0F0F0F0F0F0F0F`) /* very dark */ + let screenRowsBuffer: Buffer; let maskRowsBuffer: Buffer; export enum ShadeLevel { - //% block="one" - One = 1, - //% block="two" - Two = 2, - //% block="three" - Three = 3, - //% block="four" - Four = 4 + //% block="dark 20%" + Dark20 = 0, + //% block="dark 40%" + Dark40 = 1, + //% block="dark 60%" + Dark60 = 2, + //% block="dark 80%" + Dark80 = 3, + //% block="dark 100%" + Dark100 = 4, + //% block="light 25%" + Light25 = -1, + //% block="light 50%" + Light50 = -2, + //% block="light 75%" + Light75 = -3, + //% block="light 100%" + Light100 = -4, } - class ShaderSprite extends Sprite { - protected shadePalette: Buffer; - shadeRectangle: boolean; - - constructor(image: Image, shadePalette: Buffer) { - super(image); - this.shadePalette = shadePalette; - this.shadeRectangle = true; - } - - __drawCore(camera: scene.Camera) { - if (this.isOutOfScreen(camera)) return; - - const ox = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetX; - const oy = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetY; - - const l = this.left - ox; - const t = this.top - oy; - - if (this.shadeRectangle) { - screen.mapRect(l, t, this.image.width, this.image.height, this.shadePalette); - } - else { - shadeImage(screen, l, t, this.image, this.shadePalette); - } - - - if (this.flags & SpriteFlag.ShowPhysics) { - const font = image.font5; - const margin = 2; - let tx = l; - let ty = t + this.height + margin; - screen.print(`${this.x >> 0},${this.y >> 0}`, tx, ty, 1, font); - tx -= font.charWidth; - if (this.vx || this.vy) { - ty += font.charHeight + margin; - screen.print(`v${this.vx >> 0},${this.vy >> 0}`, tx, ty, 1, font); - } - if (this.ax || this.ay) { - ty += font.charHeight + margin; - screen.print(`a${this.ax >> 0},${this.ay >> 0}`, tx, ty, 1, font); - } - } - - // debug info - if (game.debug) { - screen.drawRect( - Fx.toInt(this._hitbox.left) - ox, - Fx.toInt(this._hitbox.top) - oy, - Fx.toInt(this._hitbox.width), - Fx.toInt(this._hitbox.height), - 1 - ); - } - } - } - - function shadeImage(target: Image, left: number, top: number, mask: Image, palette: Buffer) { if (!screenRowsBuffer || screenRowsBuffer.length < target.height) { screenRowsBuffer = pins.createBuffer(target.height); @@ -110,24 +73,41 @@ namespace shader { } } + function shadeitem(shadeLevel: number): Buffer { + switch (shadeLevel) { + case 0: return shadeDark20 ; + case 1: return shadeDark40 ; + case 2: return shadeDark60 ; + case 3: return shadeDark80 ; + case 4: return shadeDark100 ; + case -1: return shadeLight25 ; + case -2: return shadeLight50 ; + case -3: return shadeLight75 ; + case -4: return shadeLight100; + } + if (shadeLevel < 0) return shadeLight100 + return shadeDark100 + } + + /** + * create shader sprite as rectangle image. + * @param width of ractangle image + * @param height of ractangle image + * @param shade level as enum or number + */ //% blockId=shader_createRectangularShaderSprite //% block="create rectangular shader with width $width height $height shade $shadeLevel" //% shadeLevel.shadow=shader_shadelevel //% width.defl=16 //% height.defl=16 + //% blockSetVariable=myShader //% weight=90 export function createRectangularShaderSprite(width: number, height: number, shadeLevel: number): Sprite { const scene = game.currentScene(); let palette: Buffer; - switch (shadeLevel) { - case 1: palette = shade_1; break; - case 2: palette = shade_2; break; - case 3: palette = shade_3; break; - case 4: - default: palette = shade_4; break; - } + palette = shadeitem(shadeLevel); const i = image.create(width, height); i.fill(3); @@ -138,23 +118,23 @@ namespace shader { return sprite } + /** + * create shader sprite as your image. + * @param image to render + * @param shade level as enum or number + */ //% blockId=shader_createImageShaderSprite //% block="create image shader with $image shade $shadeLevel" //% image.shadow=screen_image_picker //% shadeLevel.shadow=shader_shadelevel + //% blockSetVariable=myShader //% weight=100 export function createImageShaderSprite(image: Image, shadeLevel: number): Sprite { const scene = game.currentScene(); let palette: Buffer; - switch (shadeLevel) { - case 1: palette = shade_1; break; - case 2: palette = shade_2; break; - case 3: palette = shade_3; break; - case 4: - default: palette = shade_4; break; - } + palette = shadeitem(shadeLevel); const sprite = new ShaderSprite(image, palette) sprite.setKind(SpriteKind.Shader); @@ -164,11 +144,100 @@ namespace shader { return sprite } + /** + * setting shade level as enum or number for shader sprite. + * @param current shader sprite not original sprite + * @param new shade level as enum or number + */ + //% blockId=shader_setShadeLevel + //% block=" $spr set shade level to $shadeLevel=shader_shadelevel" + //% spr.shadow=variables_get spr.defl=myShader + //% weight=70 + export function setShade(spr: Sprite, shadeLevel: number) { + let palette: Buffer; + palette = shadeitem(shadeLevel) + spr.data["__palette__"] = palette as Buffer + if (spr instanceof ShaderSprite) { + (spr as ShaderSprite).onPaletteChanged(); // Update palette when set + } else { + throw(`this sprite is not an shader sprite ${spr}`); + } + } + + /** + * enum block shadow for shade level + * but not used it. + */ + //% blockHidden //% blockId=shader_shadelevel //% block="$level" //% shim=TD_ID - //% weight=80 + //% weight=50 export function _shadeLevel(level: ShadeLevel): number { return level; } -} \ No newline at end of file + + class ShaderSprite extends Sprite { + protected shadePalette: Buffer; + shadeRectangle: boolean; + + constructor(image: Image, shadePalette: Buffer) { + super(image); + this.data["__palette__"] = shadePalette as Buffer + this.shadePalette = shadePalette; + this.shadeRectangle = true; + this.onPaletteChanged(); + } + + + onPaletteChanged() { + if (this.shadePalette !== this.data["__palette__"]) this.shadePalette = this.data["__palette__"] as Buffer; + } + + __drawCore(camera: scene.Camera) { + if (this.isOutOfScreen(camera)) return; + + const ox = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetX; + const oy = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetY; + + const l = this.left - ox; + const t = this.top - oy; + + if (this.shadeRectangle) { + screen.mapRect(l, t, this.image.width, this.image.height, this.shadePalette); + } else { + shadeImage(screen, l, t, this.image, this.shadePalette); + } + + if (this.flags & SpriteFlag.ShowPhysics) { + const font = image.font5; + const margin = 2; + let tx = l; + let ty = t + this.height + margin; + screen.print(`${this.x >> 0},${this.y >> 0}`, tx, ty, 1, font); + tx -= font.charWidth; + if (this.vx || this.vy) { + ty += font.charHeight + margin; + screen.print(`v${this.vx >> 0},${this.vy >> 0}`, tx, ty, 1, font); + } + if (this.ax || this.ay) { + ty += font.charHeight + margin; + screen.print(`a${this.ax >> 0},${this.ay >> 0}`, tx, ty, 1, font); + } + } + + // debug info + if (game.debug) { + screen.drawRect( + Fx.toInt(this._hitbox.left) - ox, + Fx.toInt(this._hitbox.top) - oy, + Fx.toInt(this._hitbox.width), + Fx.toInt(this._hitbox.height), + 1 + ); + } + + } + } + +}