feat: water
This commit is contained in:
parent
49e48d55c2
commit
2376b5b1c3
10
app/ecs-components/water.js
Normal file
10
app/ecs-components/water.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import Component from '@/ecs/component.js';
|
||||||
|
|
||||||
|
export default class Water extends Component {
|
||||||
|
static properties = {
|
||||||
|
water: {
|
||||||
|
type: 'map',
|
||||||
|
value: {type: 'uint8'},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
13
app/ecs-systems/water.js
Normal file
13
app/ecs-systems/water.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import {System} from '@/ecs/index.js';
|
||||||
|
|
||||||
|
export default class Water extends System {
|
||||||
|
|
||||||
|
tick(elapsed) {
|
||||||
|
const {Water} = this.ecs.get(1);
|
||||||
|
for (const tile in Water.water) {
|
||||||
|
Water.water[tile] = Math.max(0, Water.water[tile] - elapsed);
|
||||||
|
}
|
||||||
|
Water.water = {...Water.water};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -128,6 +128,7 @@ export default class Engine {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Water: {water: {}},
|
||||||
});
|
});
|
||||||
const defaultSystems = [
|
const defaultSystems = [
|
||||||
'ResetForces',
|
'ResetForces',
|
||||||
|
@ -142,6 +143,7 @@ export default class Engine {
|
||||||
'SpriteDirection',
|
'SpriteDirection',
|
||||||
'RunAnimations',
|
'RunAnimations',
|
||||||
'RunTickingPromises',
|
'RunTickingPromises',
|
||||||
|
'Water',
|
||||||
];
|
];
|
||||||
defaultSystems.forEach((defaultSystem) => {
|
defaultSystems.forEach((defaultSystem) => {
|
||||||
const System = ecs.system(defaultSystem);
|
const System = ecs.system(defaultSystem);
|
||||||
|
@ -162,9 +164,13 @@ export default class Engine {
|
||||||
Forces: {},
|
Forces: {},
|
||||||
Inventory: {
|
Inventory: {
|
||||||
slots: {
|
slots: {
|
||||||
1: {
|
// 1: {
|
||||||
qty: 10,
|
// qty: 10,
|
||||||
source: '/assets/potion/potion.json',
|
// source: '/assets/potion/potion.json',
|
||||||
|
// },
|
||||||
|
2: {
|
||||||
|
qty: 1,
|
||||||
|
source: '/assets/watering-can/watering-can.json',
|
||||||
},
|
},
|
||||||
3: {
|
3: {
|
||||||
qty: 1,
|
qty: 1,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Entities from './entities.jsx';
|
||||||
import TargetingGhost from './targeting-ghost.jsx';
|
import TargetingGhost from './targeting-ghost.jsx';
|
||||||
import TargetingGrid from './targeting-grid.jsx';
|
import TargetingGrid from './targeting-grid.jsx';
|
||||||
import TileLayer from './tile-layer.jsx';
|
import TileLayer from './tile-layer.jsx';
|
||||||
|
import Water from './water.jsx';
|
||||||
|
|
||||||
export default function EcsComponent() {
|
export default function EcsComponent() {
|
||||||
const [ecs] = useEcs();
|
const [ecs] = useEcs();
|
||||||
|
@ -40,7 +41,7 @@ export default function EcsComponent() {
|
||||||
const {Direction, Position, Wielder} = entity;
|
const {Direction, Position, Wielder} = entity;
|
||||||
const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction)
|
const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction)
|
||||||
const {Camera} = entity;
|
const {Camera} = entity;
|
||||||
const {TileLayers: {layers: [layer]}} = ecs.get(1);
|
const {TileLayers: {layers: [layer]}, Water: {water}} = ecs.get(1);
|
||||||
const [cx, cy] = [
|
const [cx, cy] = [
|
||||||
Math.round(Camera.x - RESOLUTION.x / 2),
|
Math.round(Camera.x - RESOLUTION.x / 2),
|
||||||
Math.round(Camera.y - RESOLUTION.y / 2),
|
Math.round(Camera.y - RESOLUTION.y / 2),
|
||||||
|
@ -51,6 +52,7 @@ export default function EcsComponent() {
|
||||||
y={-cy}
|
y={-cy}
|
||||||
>
|
>
|
||||||
<TileLayer tileLayer={layer} />
|
<TileLayer tileLayer={layer} />
|
||||||
|
<Water tileLayer={layer} water={water} />
|
||||||
{projected && (
|
{projected && (
|
||||||
<TargetingGrid
|
<TargetingGrid
|
||||||
tileLayer={layer}
|
tileLayer={layer}
|
||||||
|
|
51
app/react-components/water.jsx
Normal file
51
app/react-components/water.jsx
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import {Graphics} from '@pixi/react';
|
||||||
|
import {forwardRef, useCallback, useEffect, useRef, useState} from 'react';
|
||||||
|
|
||||||
|
const WaterTile = forwardRef(function WaterTile({height, width}, ref) {
|
||||||
|
const draw = useCallback((g) => {
|
||||||
|
g.clear();
|
||||||
|
g.beginFill(0x000000);
|
||||||
|
g.drawRect(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
}, [height, width]);
|
||||||
|
return <Graphics alpha={0} draw={draw} ref={ref} />
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function Water({tileLayer, water}) {
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
const waterTile = useRef();
|
||||||
|
const waterTiles = [];
|
||||||
|
if (mounted) {
|
||||||
|
for (const tileIndex in water) {
|
||||||
|
const tileIndexNumber = parseInt(tileIndex);
|
||||||
|
const tx = tileIndexNumber % tileLayer.area.x;
|
||||||
|
const ty = (tileIndexNumber - tx) / tileLayer.area.x;
|
||||||
|
waterTiles.push(
|
||||||
|
<Graphics
|
||||||
|
x={tx * tileLayer.tileSize.x}
|
||||||
|
y={ty * tileLayer.tileSize.y}
|
||||||
|
alpha={Math.floor(water[tileIndex]) / (256 * 2)}
|
||||||
|
key={tileIndex}
|
||||||
|
geometry={waterTile.current}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WaterTile
|
||||||
|
height={tileLayer.tileSize.y}
|
||||||
|
ref={waterTile}
|
||||||
|
width={tileLayer.tileSize.x}
|
||||||
|
/>
|
||||||
|
{waterTiles}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1 +1,20 @@
|
||||||
return 3 !== plant.stage
|
if (3 === plant.stage) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const {TileLayers, Water} = ecs.get(1);
|
||||||
|
const layer = TileLayers.layer(0)
|
||||||
|
const {Position} = ecs.get(plant.entity);
|
||||||
|
const x = (Position.x - layer.tileSize.x * 0.5) / layer.tileSize.x
|
||||||
|
const y = (Position.y - layer.tileSize.y * 0.5) / layer.tileSize.y
|
||||||
|
const tileIndex = layer.area.x * y + x
|
||||||
|
if (!Water.water[tileIndex]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (Water.water[tileIndex] < 32) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (Water.water[tileIndex] > 224) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
BIN
public/assets/watering-can/icon.png
Normal file
BIN
public/assets/watering-can/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 683 B |
10
public/assets/watering-can/projection-check.js
Normal file
10
public/assets/watering-can/projection-check.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
const filtered = []
|
||||||
|
|
||||||
|
for (let i = 0; i < projected.length; ++i) {
|
||||||
|
const tile = layer.tile(projected[i])
|
||||||
|
if ([7].includes(tile)) {
|
||||||
|
filtered.push(projected[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered
|
120
public/assets/watering-can/start.js
Normal file
120
public/assets/watering-can/start.js
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
const {Direction, Position, Wielder} = wielder
|
||||||
|
const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction)
|
||||||
|
if (projected?.length > 0) {
|
||||||
|
|
||||||
|
const {Controlled, Emitter, Sound, Sprite} = wielder
|
||||||
|
const {TileLayers, Water} = ecs.get(1)
|
||||||
|
const layer = TileLayers.layer(0)
|
||||||
|
|
||||||
|
Controlled.locked = 1
|
||||||
|
const [, direction] = Sprite.animation.split(':')
|
||||||
|
Sprite.animation = ['idle', direction].join(':');
|
||||||
|
|
||||||
|
const waterParticles = {
|
||||||
|
behaviors: [
|
||||||
|
{
|
||||||
|
type: 'moveAcceleration',
|
||||||
|
config: {
|
||||||
|
accel: {
|
||||||
|
x: 0,
|
||||||
|
y: 1500,
|
||||||
|
},
|
||||||
|
minStart: 0,
|
||||||
|
maxStart: 0,
|
||||||
|
rotate: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'moveSpeed',
|
||||||
|
config: {
|
||||||
|
speed: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
time: 0,
|
||||||
|
value: 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: 1,
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'scale',
|
||||||
|
config: {
|
||||||
|
scale: {
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
value: 0.25,
|
||||||
|
time: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0.125,
|
||||||
|
time: 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'textureSingle',
|
||||||
|
config: {
|
||||||
|
texture: 'tileset/38',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
lifetime: {
|
||||||
|
min: 0.25,
|
||||||
|
max: 0.25,
|
||||||
|
},
|
||||||
|
frequency: 0.01,
|
||||||
|
emitterLifetime: 0.25,
|
||||||
|
pos: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
rotation: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Sound.play('/assets/watering-can/water.wav');
|
||||||
|
for (let i = 0; i < 2; ++i) {
|
||||||
|
for (let i = 0; i < projected.length; ++i) {
|
||||||
|
Emitter.emit({
|
||||||
|
...waterParticles,
|
||||||
|
behaviors: [
|
||||||
|
...waterParticles.behaviors,
|
||||||
|
{
|
||||||
|
type: 'spawnShape',
|
||||||
|
config: {
|
||||||
|
type: 'rect',
|
||||||
|
data: {
|
||||||
|
x: projected[i].x * layer.tileSize.x,
|
||||||
|
y: projected[i].y * layer.tileSize.y - (layer.tileSize.y * 0.5),
|
||||||
|
w: layer.tileSize.x,
|
||||||
|
h: layer.tileSize.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await wait(0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < projected.length; ++i) {
|
||||||
|
const tileIndex = layer.area.x * projected[i].y + projected[i].x
|
||||||
|
let w;
|
||||||
|
if (Water.water[tileIndex]) {
|
||||||
|
w = Water.water[tileIndex]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = 0
|
||||||
|
}
|
||||||
|
Water.water[tileIndex] = Math.min(255, 64 + w);
|
||||||
|
}
|
||||||
|
|
||||||
|
Controlled.locked = 0;
|
||||||
|
|
||||||
|
}
|
BIN
public/assets/watering-can/water.wav
Normal file
BIN
public/assets/watering-can/water.wav
Normal file
Binary file not shown.
11
public/assets/watering-can/watering-can.json
Normal file
11
public/assets/watering-can/watering-can.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"icon": "/assets/watering-can/icon.png",
|
||||||
|
"projectionCheck": "/assets/watering-can/projection-check.js",
|
||||||
|
"projection": {
|
||||||
|
"distance": [1, 0],
|
||||||
|
"grid": [
|
||||||
|
[1]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"start": "/assets/watering-can/start.js"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user