Spaces:
Paused
Paused
import { PixiComponent, applyDefaultProps } from '@pixi/react'; | |
import * as PIXI from 'pixi.js'; | |
import { AnimatedSprite, WorldMap } from '../../convex/aiTown/worldMap'; | |
import * as campfire from '../../data/animations/campfire.json'; | |
import * as gentlesparkle from '../../data/animations/gentlesparkle.json'; | |
import * as gentlewaterfall from '../../data/animations/gentlewaterfall.json'; | |
import * as gentlesplash from '../../data/animations/gentlesplash.json'; | |
import * as windmill from '../../data/animations/windmill.json'; | |
const animations = { | |
'campfire.json': { spritesheet: campfire, url: '/assets/spritesheets/campfire.png' }, | |
'gentlesparkle.json': { | |
spritesheet: gentlesparkle, | |
url: '/assets/spritesheets/gentlesparkle32.png', | |
}, | |
'gentlewaterfall.json': { | |
spritesheet: gentlewaterfall, | |
url: '/assets/spritesheets/gentlewaterfall32.png', | |
}, | |
'windmill.json': { spritesheet: windmill, url: '/assets/spritesheets/windmill.png' }, | |
'gentlesplash.json': { | |
spritesheet: gentlesplash, | |
url: '/assets/spritesheets/gentlewaterfall32.png', | |
}, | |
}; | |
export const PixiStaticMap = PixiComponent('StaticMap', { | |
create: (props: { map: WorldMap; [k: string]: any }) => { | |
const map = props.map; | |
const numxtiles = Math.floor(map.tileSetDimX / map.tileDim); | |
const numytiles = Math.floor(map.tileSetDimY / map.tileDim); | |
const bt = PIXI.BaseTexture.from(map.tileSetUrl, { | |
scaleMode: PIXI.SCALE_MODES.NEAREST, | |
}); | |
const tiles = []; | |
for (let x = 0; x < numxtiles; x++) { | |
for (let y = 0; y < numytiles; y++) { | |
tiles[x + y * numxtiles] = new PIXI.Texture( | |
bt, | |
new PIXI.Rectangle(x * map.tileDim, y * map.tileDim, map.tileDim, map.tileDim), | |
); | |
} | |
} | |
const screenxtiles = map.bgTiles[0].length; | |
const screenytiles = map.bgTiles[0][0].length; | |
const container = new PIXI.Container(); | |
const allLayers = [...map.bgTiles, ...map.objectTiles]; | |
// blit bg & object layers of map onto canvas | |
for (let i = 0; i < screenxtiles * screenytiles; i++) { | |
const x = i % screenxtiles; | |
const y = Math.floor(i / screenxtiles); | |
const xPx = x * map.tileDim; | |
const yPx = y * map.tileDim; | |
// Add all layers of backgrounds. | |
for (const layer of allLayers) { | |
const tileIndex = layer[x][y]; | |
// Some layers may not have tiles at this location. | |
if (tileIndex === -1) continue; | |
const ctile = new PIXI.Sprite(tiles[tileIndex]); | |
ctile.x = xPx; | |
ctile.y = yPx; | |
container.addChild(ctile); | |
} | |
} | |
// TODO: Add layers. | |
const spritesBySheet = new Map<string, AnimatedSprite[]>(); | |
for (const sprite of map.animatedSprites) { | |
const sheet = sprite.sheet; | |
if (!spritesBySheet.has(sheet)) { | |
spritesBySheet.set(sheet, []); | |
} | |
spritesBySheet.get(sheet)!.push(sprite); | |
} | |
for (const [sheet, sprites] of spritesBySheet.entries()) { | |
const animation = (animations as any)[sheet]; | |
if (!animation) { | |
console.error('Could not find animation', sheet); | |
continue; | |
} | |
const { spritesheet, url } = animation; | |
const texture = PIXI.BaseTexture.from(url, { | |
scaleMode: PIXI.SCALE_MODES.NEAREST, | |
}); | |
const spriteSheet = new PIXI.Spritesheet(texture, spritesheet); | |
spriteSheet.parse().then(() => { | |
for (const sprite of sprites) { | |
const pixiAnimation = spriteSheet.animations[sprite.animation]; | |
if (!pixiAnimation) { | |
console.error('Failed to load animation', sprite); | |
continue; | |
} | |
const pixiSprite = new PIXI.AnimatedSprite(pixiAnimation); | |
pixiSprite.animationSpeed = 0.1; | |
pixiSprite.autoUpdate = true; | |
pixiSprite.x = sprite.x; | |
pixiSprite.y = sprite.y; | |
pixiSprite.width = sprite.w; | |
pixiSprite.height = sprite.h; | |
container.addChild(pixiSprite); | |
pixiSprite.play(); | |
} | |
}); | |
} | |
container.x = 0; | |
container.y = 0; | |
// Set the hit area manually to ensure `pointerdown` events are delivered to this container. | |
container.interactive = true; | |
container.hitArea = new PIXI.Rectangle( | |
0, | |
0, | |
screenxtiles * map.tileDim, | |
screenytiles * map.tileDim, | |
); | |
return container; | |
}, | |
applyProps: (instance, oldProps, newProps) => { | |
applyDefaultProps(instance, oldProps, newProps); | |
}, | |
}); | |