You've already forked Nitro_Render_V3
mirror of
https://github.com/duckietm/Nitro_Render_V3.git
synced 2026-06-20 07:26:18 +00:00
Move to Renderer V2
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": [ "@nitrots/eslint-config" ]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events*.json
|
||||
speed-measure-plugin*.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
.git
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
*.zip
|
||||
*.as
|
||||
*.bin
|
||||
@@ -0,0 +1 @@
|
||||
export * from './src';
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@nitrots/assets",
|
||||
"description": "Nitro assets module",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"compile": "tsc --project ./tsconfig.json --noEmit false",
|
||||
"eslint": "eslint ./src --fix"
|
||||
},
|
||||
"main": "./index",
|
||||
"dependencies": {
|
||||
"@nitrots/api": "1.0.0",
|
||||
"@nitrots/eslint-config": "1.0.0",
|
||||
"@nitrots/utils": "1.0.0",
|
||||
"pixi.js": "^8.0.4",
|
||||
"@pixi/gif": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "~5.4.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
import { IAssetData, IAssetManager, IGraphicAsset, IGraphicAssetCollection } from '@nitrots/api';
|
||||
import { NitroBundle, NitroLogger } from '@nitrots/utils';
|
||||
import '@pixi/gif';
|
||||
import { Assets, Spritesheet, SpritesheetData, Texture } from 'pixi.js';
|
||||
import { GraphicAssetCollection } from './GraphicAssetCollection';
|
||||
|
||||
export class AssetManager implements IAssetManager
|
||||
{
|
||||
private _textures: Map<string, Texture> = new Map();
|
||||
private _collections: Map<string, IGraphicAssetCollection> = new Map();
|
||||
|
||||
public getTexture(name: string): Texture
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
return this._textures.get(name);
|
||||
}
|
||||
|
||||
public setTexture(name: string, texture: Texture): void
|
||||
{
|
||||
if(!name || !texture) return;
|
||||
|
||||
texture.label = name;
|
||||
|
||||
this._textures.set(name, texture);
|
||||
}
|
||||
|
||||
public getAsset(name: string): IGraphicAsset
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
for(const collection of this._collections.values())
|
||||
{
|
||||
if(!collection) continue;
|
||||
|
||||
const existing = collection.getAsset(name);
|
||||
|
||||
if(!existing) continue;
|
||||
|
||||
return existing;
|
||||
}
|
||||
|
||||
NitroLogger.warn(`AssetManager: Asset not found: ${name}`);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public addAssetToCollection(collectionName: string, assetName: string, texture: Texture, override: boolean = true): boolean
|
||||
{
|
||||
const collection = this.getCollection(collectionName);
|
||||
|
||||
if(!collection) return false;
|
||||
|
||||
return collection.addAsset(assetName, texture, override, 0, 0, false, false);
|
||||
}
|
||||
|
||||
public getCollection(name: string): IGraphicAssetCollection
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
return this._collections.get(name);
|
||||
}
|
||||
|
||||
public createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection
|
||||
{
|
||||
if(!data) return null;
|
||||
|
||||
const collection = new GraphicAssetCollection(data, spritesheet);
|
||||
|
||||
for(const [name, texture] of collection.textures.entries()) this.setTexture(name, texture);
|
||||
|
||||
this._collections.set(collection.name, collection);
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
public async downloadAssets(urls: string[]): Promise<boolean>
|
||||
{
|
||||
if(!urls || !urls.length) return Promise.resolve(true);
|
||||
|
||||
try
|
||||
{
|
||||
await Promise.all(urls.map(url => this.downloadAsset(url)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
catch (err)
|
||||
{
|
||||
NitroLogger.error(err);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async downloadAsset(url: string): Promise<boolean>
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!url || !url.length) return false;
|
||||
|
||||
if(url.endsWith('.png') || url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif'))
|
||||
{
|
||||
const texture = await Assets.load<Texture>(url);
|
||||
|
||||
this.setTexture(url, texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const response = await fetch(url);
|
||||
|
||||
if(response.status !== 200 || !response.headers.has('Content-Type') || response.headers.get('Content-Type') !== 'application/octet-stream') return false;
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const nitroBundle = await NitroBundle.from(buffer);
|
||||
|
||||
await this.processAsset(nitroBundle.texture, nitroBundle.jsonFile as IAssetData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
catch (err)
|
||||
{
|
||||
NitroLogger.error(err);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async processAsset(texture: Texture, data: IAssetData): Promise<void>
|
||||
{
|
||||
let spritesheet: Spritesheet<SpritesheetData> = null;
|
||||
|
||||
if(texture && data?.spritesheet && Object.keys(data.spritesheet).length)
|
||||
{
|
||||
spritesheet = new Spritesheet(texture, data.spritesheet);
|
||||
|
||||
await spritesheet.parse();
|
||||
|
||||
spritesheet.textureSource.label = data.name ?? null;
|
||||
}
|
||||
|
||||
this.createCollection(data, spritesheet);
|
||||
}
|
||||
|
||||
public get collections(): Map<string, IGraphicAssetCollection>
|
||||
{
|
||||
return this._collections;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { AssetManager } from './AssetManager';
|
||||
|
||||
const assetManager = new AssetManager();
|
||||
|
||||
export const GetAssetManager = () => assetManager;
|
||||
@@ -0,0 +1,140 @@
|
||||
import { Rectangle, Texture } from 'pixi.js';
|
||||
import { IGraphicAsset } from '../../api/src/asset/IGraphicAsset';
|
||||
|
||||
export class GraphicAsset implements IGraphicAsset
|
||||
{
|
||||
private static GRAPHIC_POOL: GraphicAsset[] = [];
|
||||
|
||||
private _name: string;
|
||||
private _source: string;
|
||||
private _texture: Texture;
|
||||
private _usesPalette: boolean;
|
||||
private _x: number;
|
||||
private _y: number;
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
private _flipH: boolean;
|
||||
private _flipV: boolean;
|
||||
private _rectangle: Rectangle;
|
||||
private _initialized: boolean;
|
||||
|
||||
public static createAsset(name: string, source: string, texture: Texture, x: number, y: number, flipH: boolean = false, flipV: boolean = false, usesPalette: boolean = false): GraphicAsset
|
||||
{
|
||||
const graphicAsset = (GraphicAsset.GRAPHIC_POOL.length ? GraphicAsset.GRAPHIC_POOL.pop() : new GraphicAsset());
|
||||
|
||||
graphicAsset._name = name;
|
||||
graphicAsset._source = source || null;
|
||||
|
||||
if(texture)
|
||||
{
|
||||
graphicAsset._texture = texture;
|
||||
graphicAsset._initialized = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
graphicAsset._texture = null;
|
||||
graphicAsset._initialized = true;
|
||||
}
|
||||
|
||||
graphicAsset._usesPalette = usesPalette;
|
||||
graphicAsset._x = x;
|
||||
graphicAsset._y = y;
|
||||
graphicAsset._flipH = flipH;
|
||||
graphicAsset._flipV = flipV;
|
||||
graphicAsset._rectangle = null;
|
||||
|
||||
return graphicAsset;
|
||||
}
|
||||
|
||||
public recycle(): void
|
||||
{
|
||||
this._texture = null;
|
||||
|
||||
GraphicAsset.GRAPHIC_POOL.push(this);
|
||||
}
|
||||
|
||||
private initialize(): void
|
||||
{
|
||||
if(this._initialized || !this._texture) return;
|
||||
|
||||
this._width = this._texture.width;
|
||||
this._height = this._texture.height;
|
||||
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get source(): string
|
||||
{
|
||||
return this._source;
|
||||
}
|
||||
|
||||
public get texture(): Texture
|
||||
{
|
||||
return this._texture;
|
||||
}
|
||||
|
||||
public get usesPalette(): boolean
|
||||
{
|
||||
return this._usesPalette;
|
||||
}
|
||||
|
||||
public get x(): number
|
||||
{
|
||||
return this._x;
|
||||
}
|
||||
|
||||
public get y(): number
|
||||
{
|
||||
return this._y;
|
||||
}
|
||||
|
||||
public get width(): number
|
||||
{
|
||||
this.initialize();
|
||||
|
||||
return this._width;
|
||||
}
|
||||
|
||||
public get height(): number
|
||||
{
|
||||
this.initialize();
|
||||
|
||||
return this._height;
|
||||
}
|
||||
|
||||
public get offsetX(): number
|
||||
{
|
||||
if(!this._flipH) return this._x;
|
||||
|
||||
return (-(this._x));
|
||||
}
|
||||
|
||||
public get offsetY(): number
|
||||
{
|
||||
if(!this._flipV) return this._y;
|
||||
|
||||
return (-(this._y));
|
||||
}
|
||||
|
||||
public get flipH(): boolean
|
||||
{
|
||||
return this._flipH;
|
||||
}
|
||||
|
||||
public get flipV(): boolean
|
||||
{
|
||||
return this._flipV;
|
||||
}
|
||||
|
||||
public get rectangle(): Rectangle
|
||||
{
|
||||
if(!this._rectangle) this._rectangle = new Rectangle(0, 0, this.width, this.height);
|
||||
|
||||
return this._rectangle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
import { IAsset, IAssetData, IAssetPalette, IGraphicAsset, IGraphicAssetCollection, IGraphicAssetPalette } from '@nitrots/api';
|
||||
import { Dict, Spritesheet, Texture, TextureSource } from 'pixi.js';
|
||||
import { GraphicAsset } from './GraphicAsset';
|
||||
import { GraphicAssetPalette } from './GraphicAssetPalette';
|
||||
|
||||
export class GraphicAssetCollection implements IGraphicAssetCollection
|
||||
{
|
||||
private static PALETTE_ASSET_DISPOSE_THRESHOLD: number = 10;
|
||||
|
||||
private _referenceCount: number;
|
||||
|
||||
private _name: string;
|
||||
private _textureSource: TextureSource;
|
||||
private _data: IAssetData;
|
||||
private _textures: Map<string, Texture>;
|
||||
private _assets: Map<string, IGraphicAsset>;
|
||||
private _palettes: Map<string, IGraphicAssetPalette>;
|
||||
private _paletteAssetNames: string[];
|
||||
|
||||
constructor(data: IAssetData, spritesheet: Spritesheet)
|
||||
{
|
||||
if(!data) throw new Error('invalid_collection');
|
||||
|
||||
this._name = data.name;
|
||||
this._textureSource = ((spritesheet && spritesheet.textureSource) || null);
|
||||
this._data = data;
|
||||
this._textures = new Map();
|
||||
this._assets = new Map();
|
||||
this._palettes = new Map();
|
||||
this._paletteAssetNames = [];
|
||||
|
||||
if(spritesheet) this.addLibraryAsset(spritesheet.textures);
|
||||
|
||||
this.define(data);
|
||||
}
|
||||
|
||||
public static removeFileExtension(name: string): string
|
||||
{
|
||||
return (name.substring(0, name.lastIndexOf('.')) || name);
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
if(this._palettes) this._palettes.clear();
|
||||
|
||||
if(this._paletteAssetNames)
|
||||
{
|
||||
this.disposePaletteAssets();
|
||||
|
||||
this._paletteAssetNames = null;
|
||||
}
|
||||
|
||||
if(this._assets)
|
||||
{
|
||||
for(const asset of this._assets.values()) asset.recycle();
|
||||
|
||||
this._assets.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public addReference(): void
|
||||
{
|
||||
this._referenceCount++;
|
||||
}
|
||||
|
||||
public removeReference(): void
|
||||
{
|
||||
this._referenceCount--;
|
||||
|
||||
if(this._referenceCount <= 0)
|
||||
{
|
||||
this._referenceCount = 0;
|
||||
|
||||
this.disposePaletteAssets(false);
|
||||
}
|
||||
}
|
||||
|
||||
public define(data: IAssetData): void
|
||||
{
|
||||
const assets = data.assets;
|
||||
const palettes = data.palettes;
|
||||
|
||||
if(assets) this.defineAssets(assets);
|
||||
|
||||
if(palettes) this.definePalettes(palettes);
|
||||
}
|
||||
|
||||
private defineAssets(assets: { [index: string]: IAsset }): void
|
||||
{
|
||||
if(!assets) return;
|
||||
|
||||
for(const name in assets)
|
||||
{
|
||||
const asset = assets[name];
|
||||
|
||||
if(!asset) continue;
|
||||
|
||||
const x = (-(asset.x) || 0);
|
||||
const y = (-(asset.y) || 0);
|
||||
let flipH = false;
|
||||
const flipV = false;
|
||||
const usesPalette = (asset.usesPalette || false);
|
||||
let source = (asset.source || '');
|
||||
|
||||
if(asset.flipH && source.length) flipH = true;
|
||||
|
||||
// if(asset.flipV && source.length) flipV = true;
|
||||
|
||||
if(!source.length) source = name;
|
||||
|
||||
const texture = this.getLibraryAsset(source);
|
||||
|
||||
if(!texture) continue;
|
||||
|
||||
let didAddAsset = this.createAsset(name, source, texture, flipH, flipV, x, y, usesPalette);
|
||||
|
||||
if(!didAddAsset)
|
||||
{
|
||||
const existingAsset = this.getAsset(name);
|
||||
|
||||
if(existingAsset && (existingAsset.name !== existingAsset.source))
|
||||
{
|
||||
didAddAsset = this.replaceAsset(name, source, texture, flipH, flipV, x, y, usesPalette);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private definePalettes(palettes: { [index: string]: IAssetPalette }): void
|
||||
{
|
||||
if(!palettes) return;
|
||||
|
||||
for(const name in palettes)
|
||||
{
|
||||
const palette = palettes[name];
|
||||
|
||||
if(!palette) continue;
|
||||
|
||||
const id = palette.id.toString();
|
||||
|
||||
if(this._palettes.get(id)) continue;
|
||||
|
||||
let colorOne = 0xFFFFFF;
|
||||
let colorTwo = 0xFFFFFF;
|
||||
|
||||
let color = palette.color1;
|
||||
|
||||
if(color && color.length > 0) colorOne = parseInt(color, 16);
|
||||
|
||||
color = palette.color2;
|
||||
|
||||
if(color && color.length > 0) colorTwo = parseInt(color, 16);
|
||||
|
||||
this._palettes.set(id, new GraphicAssetPalette(palette.rgb, colorOne, colorTwo));
|
||||
}
|
||||
}
|
||||
|
||||
private createAsset(name: string, source: string, texture: Texture, flipH: boolean, flipV: boolean, x: number, y: number, usesPalette: boolean): boolean
|
||||
{
|
||||
if(this._assets.get(name)) return false;
|
||||
|
||||
const graphicAsset = GraphicAsset.createAsset(name, source, texture, x, y, flipH, flipV, usesPalette);
|
||||
|
||||
this._assets.set(name, graphicAsset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private replaceAsset(name: string, source: string, texture: Texture, flipH: boolean, flipV: boolean, x: number, y: number, usesPalette: boolean): boolean
|
||||
{
|
||||
const existing = this._assets.get(name);
|
||||
|
||||
if(existing)
|
||||
{
|
||||
this._assets.delete(name);
|
||||
|
||||
existing.recycle();
|
||||
}
|
||||
|
||||
return this.createAsset(name, source, texture, flipH, flipV, x, y, usesPalette);
|
||||
}
|
||||
|
||||
public getAsset(name: string): IGraphicAsset
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
const existing = this._assets.get(name);
|
||||
|
||||
if(!existing) return null;
|
||||
|
||||
return existing;
|
||||
}
|
||||
|
||||
public getAssetWithPalette(name: string, paletteName: string): IGraphicAsset
|
||||
{
|
||||
const saveName = (name + '@' + paletteName);
|
||||
|
||||
let asset = this.getAsset(saveName);
|
||||
|
||||
if(!asset)
|
||||
{
|
||||
asset = this.getAsset(name);
|
||||
|
||||
if(!asset || !asset.usesPalette) return asset;
|
||||
|
||||
const palette = this.getPalette(paletteName);
|
||||
|
||||
if(palette)
|
||||
{
|
||||
const texture = palette.applyPalette(asset.texture);
|
||||
|
||||
if(texture)
|
||||
{
|
||||
this._paletteAssetNames.push(saveName);
|
||||
|
||||
this.createAsset(saveName, (asset.source + '@' + paletteName), texture, asset.flipH, asset.flipV, asset.x, asset.y, false);
|
||||
|
||||
asset = this.getAsset(saveName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
public getTexture(name: string): Texture
|
||||
{
|
||||
return this._textures.get(name);
|
||||
}
|
||||
|
||||
public getPaletteNames(): string[]
|
||||
{
|
||||
return Array.from(this._palettes.keys());
|
||||
}
|
||||
|
||||
public getPaletteColors(paletteName: string): number[]
|
||||
{
|
||||
const palette = this.getPalette(paletteName);
|
||||
|
||||
if(palette) return [palette.primaryColor, palette.secondaryColor];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getPalette(name: string): IGraphicAssetPalette
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
return this._palettes.get(name);
|
||||
}
|
||||
|
||||
public addAsset(name: string, texture: Texture, override: boolean, x: number = 0, y: number = 0, flipH: boolean = false, flipV: boolean = false): boolean
|
||||
{
|
||||
if(!name || !texture) return false;
|
||||
|
||||
const existingTexture = this.getLibraryAsset(name);
|
||||
|
||||
if(!existingTexture)
|
||||
{
|
||||
this._textures.set(name, texture);
|
||||
|
||||
return this.createAsset(name, name, texture, flipH, flipV, x, y, false);
|
||||
}
|
||||
|
||||
if(override)
|
||||
{
|
||||
existingTexture.source = texture.source;
|
||||
|
||||
//@ts-ignore
|
||||
existingTexture.frame = texture.frame;
|
||||
|
||||
//@ts-ignore
|
||||
existingTexture.trim = texture.trim;
|
||||
|
||||
existingTexture.updateUvs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public disposeAsset(name: string): void
|
||||
{
|
||||
const existing = this._assets.get(name);
|
||||
|
||||
if(!existing) return;
|
||||
|
||||
this._assets.delete(name);
|
||||
|
||||
const texture = this.getLibraryAsset(existing.source);
|
||||
|
||||
if(texture)
|
||||
{
|
||||
this._textures.delete(existing.source);
|
||||
|
||||
texture.destroy(true);
|
||||
}
|
||||
|
||||
existing.recycle();
|
||||
}
|
||||
|
||||
public getLibraryAsset(name: string): Texture
|
||||
{
|
||||
if(!name) return null;
|
||||
|
||||
name = this._name + '_' + name;
|
||||
|
||||
const texture = this._textures.get(name);
|
||||
|
||||
if(!texture) return null;
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
private addLibraryAsset(textures: Dict<Texture>): void
|
||||
{
|
||||
if(!textures) return;
|
||||
|
||||
for(const name in textures)
|
||||
{
|
||||
const texture = textures[name];
|
||||
|
||||
if(!texture) continue;
|
||||
|
||||
this._textures.set(GraphicAssetCollection.removeFileExtension(name), texture);
|
||||
}
|
||||
}
|
||||
|
||||
private disposePaletteAssets(disposeAll: boolean = true): void
|
||||
{
|
||||
if(this._paletteAssetNames)
|
||||
{
|
||||
if(disposeAll || (this._paletteAssetNames.length > GraphicAssetCollection.PALETTE_ASSET_DISPOSE_THRESHOLD))
|
||||
{
|
||||
for(const name of this._paletteAssetNames) this.disposeAsset(name);
|
||||
|
||||
this._paletteAssetNames = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get referenceCount(): number
|
||||
{
|
||||
return this._referenceCount;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get textureSource(): TextureSource
|
||||
{
|
||||
return this._textureSource;
|
||||
}
|
||||
|
||||
public get data(): IAssetData
|
||||
{
|
||||
return this._data;
|
||||
}
|
||||
|
||||
public get textures(): Map<string, Texture>
|
||||
{
|
||||
return this._textures;
|
||||
}
|
||||
|
||||
public get assets(): Map<string, IGraphicAsset>
|
||||
{
|
||||
return this._assets;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { IGraphicAssetPalette } from '@nitrots/api';
|
||||
import { GetRenderer } from '@nitrots/utils';
|
||||
import { Texture } from 'pixi.js';
|
||||
|
||||
export class GraphicAssetPalette implements IGraphicAssetPalette
|
||||
{
|
||||
private _palette: [number, number, number][];
|
||||
private _primaryColor: number;
|
||||
private _secondaryColor: number;
|
||||
|
||||
constructor(palette: [number, number, number][], primaryColor: number, secondaryColor: number)
|
||||
{
|
||||
this._palette = palette;
|
||||
|
||||
while(this._palette.length < 256) this._palette.push([0, 0, 0]);
|
||||
|
||||
this._primaryColor = primaryColor;
|
||||
this._secondaryColor = secondaryColor;
|
||||
}
|
||||
|
||||
public applyPalette(texture: Texture): Texture
|
||||
{
|
||||
const canvas = GetRenderer().texture.generateCanvas(texture);
|
||||
const ctx = canvas.getContext('2d');
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for(let i = 0; i < imageData.data.length; i += 4)
|
||||
{
|
||||
let paletteColor = this._palette[imageData.data[i + 1]];
|
||||
|
||||
if(paletteColor === undefined) paletteColor = [0, 0, 0];
|
||||
|
||||
imageData.data[i] = paletteColor[0];
|
||||
imageData.data[i + 1] = paletteColor[1];
|
||||
imageData.data[i + 2] = paletteColor[2];
|
||||
}
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
|
||||
const newTexture = Texture.from(canvas);
|
||||
|
||||
//@ts-ignore
|
||||
newTexture.source.hitMap = imageData.data;
|
||||
|
||||
return newTexture;
|
||||
}
|
||||
|
||||
public get primaryColor(): number
|
||||
{
|
||||
return this._primaryColor;
|
||||
}
|
||||
|
||||
public get secondaryColor(): number
|
||||
{
|
||||
return this._secondaryColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './AssetManager';
|
||||
export * from './GetAssetManager';
|
||||
export * from './GraphicAsset';
|
||||
export * from './GraphicAssetCollection';
|
||||
export * from './GraphicAssetPalette';
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./src",
|
||||
"outDir": "./dist",
|
||||
"sourceMap": false,
|
||||
"declaration": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "Node",
|
||||
"esModuleInterop": true,
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"resolveJsonModule": true,
|
||||
"downlevelIteration": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"strict": false,
|
||||
"strictNullChecks": false,
|
||||
"target": "ES6",
|
||||
"lib": [
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"ESNext"
|
||||
],
|
||||
"module": "ES6"
|
||||
},
|
||||
"include": [
|
||||
"src" ]
|
||||
}
|
||||
Reference in New Issue
Block a user