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 = [
|
||||
'ResetForces',
|
||||
|
@ -142,6 +143,7 @@ export default class Engine {
|
|||
'SpriteDirection',
|
||||
'RunAnimations',
|
||||
'RunTickingPromises',
|
||||
'Water',
|
||||
];
|
||||
defaultSystems.forEach((defaultSystem) => {
|
||||
const System = ecs.system(defaultSystem);
|
||||
|
@ -162,9 +164,13 @@ export default class Engine {
|
|||
Forces: {},
|
||||
Inventory: {
|
||||
slots: {
|
||||
1: {
|
||||
qty: 10,
|
||||
source: '/assets/potion/potion.json',
|
||||
// 1: {
|
||||
// qty: 10,
|
||||
// source: '/assets/potion/potion.json',
|
||||
// },
|
||||
2: {
|
||||
qty: 1,
|
||||
source: '/assets/watering-can/watering-can.json',
|
||||
},
|
||||
3: {
|
||||
qty: 1,
|
||||
|
|
|
@ -9,6 +9,7 @@ import Entities from './entities.jsx';
|
|||
import TargetingGhost from './targeting-ghost.jsx';
|
||||
import TargetingGrid from './targeting-grid.jsx';
|
||||
import TileLayer from './tile-layer.jsx';
|
||||
import Water from './water.jsx';
|
||||
|
||||
export default function EcsComponent() {
|
||||
const [ecs] = useEcs();
|
||||
|
@ -40,7 +41,7 @@ export default function EcsComponent() {
|
|||
const {Direction, Position, Wielder} = entity;
|
||||
const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction)
|
||||
const {Camera} = entity;
|
||||
const {TileLayers: {layers: [layer]}} = ecs.get(1);
|
||||
const {TileLayers: {layers: [layer]}, Water: {water}} = ecs.get(1);
|
||||
const [cx, cy] = [
|
||||
Math.round(Camera.x - RESOLUTION.x / 2),
|
||||
Math.round(Camera.y - RESOLUTION.y / 2),
|
||||
|
@ -51,6 +52,7 @@ export default function EcsComponent() {
|
|||
y={-cy}
|
||||
>
|
||||
<TileLayer tileLayer={layer} />
|
||||
<Water tileLayer={layer} water={water} />
|
||||
{projected && (
|
||||
<TargetingGrid
|
||||
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