fun: light

This commit is contained in:
cha0s 2024-07-17 05:07:50 -05:00
parent 578e796090
commit 0d8cdff6d7
11 changed files with 116 additions and 12 deletions

View File

@ -41,6 +41,7 @@ export default async function createPlayer(id) {
},
},
Health: {health: 100},
Light: {},
Magnet: {strength: 24},
Player: {},
Position: {x: 128, y: 128},

View File

@ -0,0 +1,7 @@
import Component from '@/ecs/component.js';
export default class Light extends Component {
static properties = {
radius: {type: 'uint8'},
};
}

View File

@ -5,6 +5,7 @@ import {useDebug} from '@/context/debug.js';
import {useMainEntity} from '@/context/main-entity.js';
import Emitter from './emitter.jsx';
import Light from './light.jsx';
import Sprite from './sprite.jsx';
function Aabb({color, width = 0.5, x0, y0, x1, y1, ...rest}) {
@ -66,6 +67,12 @@ function Entity({entity, ...rest}) {
entity={entity}
/>
)}
{entity.Light && (
<Light
x={entity.Position.x}
y={entity.Position.y}
/>
)}
{debug && entity.Position && (
<Crosshair x={entity.Position.x} y={entity.Position.y} />
)}

View File

@ -0,0 +1,27 @@
import {PixiComponent} from '@pixi/react';
let PointLight;
if ('undefined' !== typeof window) {
({PointLight} = await import('@pixi/lights'));
}
const LightInternal = PixiComponent('Light', {
create({x, y}) {
const light = new PointLight(0xffffff, 1);
light.position.set(x, y);
return light;
},
applyProps(light, oldProps, {x, y}) {
light.position.set(x, y);
},
});
export default function Light({x, y}) {
return (
<LightInternal
x={x}
y={y}
/>
)
}

View File

@ -58,7 +58,7 @@ export default function Pixi({applyFilters, camera, monopolizers, scale}) {
width={RESOLUTION.x}
height={RESOLUTION.y}
options={{
background: 0x1099bb,
background: 0x0,
}}
>
<Ecs

View File

@ -1,5 +1,6 @@
import { Application } from '@pixi/app';
import { Stage as LayerStage } from '@pixi/layers';
import { Layer, Stage as LayerStage } from '@pixi/layers';
import { Ticker } from '@pixi/ticker';
import { AppProvider, PixiFiber } from '@pixi/react';
@ -28,6 +29,11 @@ const PROPS_DISPLAY_OBJECT = {
y: 0,
};
let AmbientLight, diffuseGroup, normalGroup, lightGroup;
if ('undefined' !== typeof window) {
({AmbientLight, diffuseGroup, normalGroup, lightGroup} = await import('@pixi/lights'));
}
const noop = () => {};
/**
@ -134,7 +140,12 @@ class Stage extends React.Component
...options,
autoDensity: options?.autoDensity !== false,
});
this.app.stage = new LayerStage();
const stage = new LayerStage();
this.app.stage = stage;
stage.addChild(new Layer(diffuseGroup));
stage.addChild(new Layer(normalGroup));
stage.addChild(new Layer(lightGroup));
stage.addChild(new AmbientLight(0xffffff, 1));
if (process.env.NODE_ENV === 'development')
{

View File

@ -1,28 +1,43 @@
import {RenderTexture} from '@pixi/core';
import {Container} from '@pixi/display';
import {PixiComponent} from '@pixi/react';
import {PixiComponent, useApp} from '@pixi/react';
import {Sprite} from '@pixi/sprite';
import '@pixi/spritesheet'; // NECESSARY!
import {CompositeTilemap} from '@pixi/tilemap';
import {CHUNK_SIZE} from '@/constants.js';
import {useAsset} from '@/context/assets.js';
let diffuseGroup, normalGroup;
if ('undefined' !== typeof window) {
({diffuseGroup, normalGroup} = await import('@pixi/lights'));
}
const TileLayerInternal = PixiComponent('TileLayer', {
create: ({tileLayer}) => {
create: ({group, stage, tileLayer}) => {
const container = new Container();
const cy = Math.ceil(tileLayer.area.y / CHUNK_SIZE);
const cx = Math.ceil(tileLayer.area.x / CHUNK_SIZE);
for (let iy = 0; iy < cy; ++iy) {
for (let ix = 0; ix < cx; ++ix) {
const tilemap = new CompositeTilemap();
tilemap.x = tileLayer.tileSize.x * CHUNK_SIZE * ix;
tilemap.y = tileLayer.tileSize.y * CHUNK_SIZE * iy;
container.addChild(tilemap);
const renderTexture = RenderTexture.create({
width: tileLayer.tileSize.x * CHUNK_SIZE,
height: tileLayer.tileSize.y * CHUNK_SIZE,
});
const sprite = new Sprite(renderTexture);
sprite.x = tileLayer.tileSize.x * CHUNK_SIZE * ix;
sprite.y = tileLayer.tileSize.y * CHUNK_SIZE * iy;
sprite.parentGroup = group;
sprite.tilemap = tilemap;
container.addChild(sprite);
}
}
return container;
},
applyProps: (container, {tileLayer: oldTileLayer}, props) => {
const {asset, tileLayer} = props;
const {asset, group, renderer, tileLayer} = props;
const extless = tileLayer.source.slice('/assets/'.length, -'.json'.length);
const {textures} = asset;
if (tileLayer === oldTileLayer) {
@ -30,7 +45,7 @@ const TileLayerInternal = PixiComponent('TileLayer', {
}
for (const i in tileLayer.$$chunks) {
if (!oldTileLayer || oldTileLayer.$$chunks[i] !== tileLayer.$$chunks[i]) {
const tilemap = container.children[i];
const {texture, tilemap} = container.children[i];
tilemap.clear();
const ax = Math.ceil(tileLayer.area.x / CHUNK_SIZE);
const cy = Math.floor(i / ax);
@ -47,22 +62,34 @@ const TileLayerInternal = PixiComponent('TileLayer', {
) {
continue;
}
const parts = [
extless,
...(normalGroup === group ? ['normals'] : []),
tileLayer.data[ty * tileLayer.area.x + tx],
];
tilemap.tile(
textures[`${extless}/${tileLayer.data[ty * tileLayer.area.x + tx]}`],
textures[parts.join('/')],
tileLayer.tileSize.x * x,
tileLayer.tileSize.y * y,
{
tileWidth: 16,
tileHeight: 16,
},
);
}
}
renderer.render(tilemap, {renderTexture: texture});
}
}
},
});
export default function TileLayer(props) {
const {renderer, stage} = useApp();
const {tileLayer} = props;
const asset = useAsset(tileLayer.source);
if (!asset) {
const normalsAsset = useAsset([tileLayer.source.slice(0, -'.json'.length), 'normals.json'].join('.'));
if (!asset || !normalsAsset) {
return false;
}
return (
@ -70,6 +97,16 @@ export default function TileLayer(props) {
<TileLayerInternal
{...props}
asset={asset}
group={diffuseGroup}
renderer={renderer}
stage={stage}
/>
<TileLayerInternal
{...props}
asset={normalsAsset}
group={normalGroup}
renderer={renderer}
stage={stage}
/>
</>
);

12
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@pixi/filter-color-matrix": "^7.4.2",
"@pixi/filter-glow": "^5.2.1",
"@pixi/layers": "^2.1.0",
"@pixi/lights": "^4.1.0",
"@pixi/particle-emitter": "^5.0.8",
"@pixi/react": "^7.1.2",
"@pixi/spritesheet": "^7.4.2",
@ -3724,6 +3725,17 @@
"@pixi/display": "^7.0.0"
}
},
"node_modules/@pixi/lights": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@pixi/lights/-/lights-4.1.0.tgz",
"integrity": "sha512-UPY5/GTVZefev9iVY4zCgslHhxw5D196T8u/AP8X7T5rJQa9PNcGK9FS0aFnOg9dpX1PuPi3cs2cdtYMvYVDRw==",
"peerDependencies": {
"@pixi/core": "^7.0.0",
"@pixi/display": "^7.0.0",
"@pixi/layers": "^2.0.1",
"@pixi/mesh": "^7.0.0"
}
},
"node_modules/@pixi/math": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.4.2.tgz",

View File

@ -18,6 +18,7 @@
"@pixi/filter-color-matrix": "^7.4.2",
"@pixi/filter-glow": "^5.2.1",
"@pixi/layers": "^2.1.0",
"@pixi/lights": "^4.1.0",
"@pixi/particle-emitter": "^5.0.8",
"@pixi/react": "^7.1.2",
"@pixi/spritesheet": "^7.4.2",

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB