mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Multiple improvements
This commit is contained in:
@@ -4,10 +4,13 @@ import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Entity } from "../entity";
|
||||
import { formatBigNumber } from "../../core/utils";
|
||||
import { enumHubGoalRewardToString } from "../tutorial_goals";
|
||||
import { Loader } from "../../core/loader";
|
||||
|
||||
export class HubSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [HubComponent]);
|
||||
|
||||
this.hubSprite = Loader.getSprite("sprites/buildings/hub.png");
|
||||
}
|
||||
|
||||
draw(parameters) {
|
||||
@@ -40,6 +43,9 @@ export class HubSystem extends GameSystemWithFilter {
|
||||
|
||||
const pos = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
|
||||
|
||||
// Background
|
||||
staticComp.drawSpriteOnFullEntityBounds(parameters, this.hubSprite, 2.2);
|
||||
|
||||
const definition = this.root.hubGoals.currentGoal.definition;
|
||||
|
||||
definition.draw(pos.x - 25, pos.y - 10, parameters, 40);
|
||||
|
||||
114
src/js/game/systems/item_acceptor.js
Normal file
114
src/js/game/systems/item_acceptor.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Entity } from "../entity";
|
||||
import { enumDirectionToVector, enumDirectionToAngle } from "../../core/vector";
|
||||
import { ItemAcceptorComponent } from "../components/item_acceptor";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { drawRotatedSprite } from "../../core/draw_utils";
|
||||
import { Math_radians } from "../../core/builtins";
|
||||
|
||||
export class ItemAcceptorSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [ItemAcceptorComponent]);
|
||||
|
||||
this.underlayBeltSprites = [
|
||||
Loader.getSprite("sprites/belt/forward_0.png"),
|
||||
Loader.getSprite("sprites/belt/forward_1.png"),
|
||||
Loader.getSprite("sprites/belt/forward_2.png"),
|
||||
Loader.getSprite("sprites/belt/forward_3.png"),
|
||||
Loader.getSprite("sprites/belt/forward_4.png"),
|
||||
Loader.getSprite("sprites/belt/forward_5.png"),
|
||||
];
|
||||
}
|
||||
|
||||
update() {
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
const aceptorComp = entity.components.ItemAcceptor;
|
||||
|
||||
// Process item consumption animations to avoid items popping from the belts
|
||||
for (let animIndex = 0; animIndex < aceptorComp.itemConsumptionAnimations.length; ++animIndex) {
|
||||
const anim = aceptorComp.itemConsumptionAnimations[animIndex];
|
||||
anim.animProgress +=
|
||||
globalConfig.physicsDeltaSeconds * this.root.hubGoals.getBeltBaseSpeed() * 2;
|
||||
if (anim.animProgress > 1) {
|
||||
aceptorComp.itemConsumptionAnimations.splice(animIndex, 1);
|
||||
animIndex -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw(parameters) {
|
||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this));
|
||||
}
|
||||
|
||||
drawUnderlays(parameters) {
|
||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DrawParameters} parameters
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
drawEntity(parameters, entity) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const acceptorComp = entity.components.ItemAcceptor;
|
||||
|
||||
for (let animIndex = 0; animIndex < acceptorComp.itemConsumptionAnimations.length; ++animIndex) {
|
||||
const { item, slotIndex, animProgress, direction } = acceptorComp.itemConsumptionAnimations[
|
||||
animIndex
|
||||
];
|
||||
|
||||
const slotData = acceptorComp.slots[slotIndex];
|
||||
const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin);
|
||||
|
||||
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];
|
||||
const finalTile = slotWorldPos.subScalars(
|
||||
fadeOutDirection.x * (animProgress / 2 - 0.5),
|
||||
fadeOutDirection.y * (animProgress / 2 - 0.5)
|
||||
);
|
||||
item.draw(
|
||||
(finalTile.x + 0.5) * globalConfig.tileSize,
|
||||
(finalTile.y + 0.5) * globalConfig.tileSize,
|
||||
parameters
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DrawParameters} parameters
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
drawEntityUnderlays(parameters, entity) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const acceptorComp = entity.components.ItemAcceptor;
|
||||
|
||||
const underlays = acceptorComp.beltUnderlays;
|
||||
for (let i = 0; i < underlays.length; ++i) {
|
||||
const { pos, direction } = underlays[i];
|
||||
|
||||
const transformedPos = staticComp.localTileToWorld(pos);
|
||||
const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)];
|
||||
|
||||
// SYNC with systems/belt.js:drawSingleEntity!
|
||||
const animationIndex = Math.floor(
|
||||
(this.root.time.now() *
|
||||
this.root.hubGoals.getBeltBaseSpeed() *
|
||||
this.underlayBeltSprites.length *
|
||||
126) /
|
||||
42
|
||||
);
|
||||
|
||||
drawRotatedSprite({
|
||||
parameters,
|
||||
sprite: this.underlayBeltSprites[animationIndex % this.underlayBeltSprites.length],
|
||||
x: (transformedPos.x + 0.5) * globalConfig.tileSize,
|
||||
y: (transformedPos.y + 0.5) * globalConfig.tileSize,
|
||||
angle: Math_radians(angle),
|
||||
size: globalConfig.tileSize,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,14 +72,12 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
this.tryPassOverItem(
|
||||
ejectingItem,
|
||||
targetEntity,
|
||||
if (this.tryPassOverItem(ejectingItem, targetEntity, matchingSlot.index)) {
|
||||
targetAcceptorComp.onItemAccepted(
|
||||
matchingSlot.index,
|
||||
matchingSlot.acceptedDirection
|
||||
)
|
||||
) {
|
||||
matchingSlot.acceptedDirection,
|
||||
ejectingItem
|
||||
);
|
||||
ejectorSlot.item = null;
|
||||
continue;
|
||||
}
|
||||
@@ -92,9 +90,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
* @param {BaseItem} item
|
||||
* @param {Entity} receiver
|
||||
* @param {number} slotIndex
|
||||
* @param {string} localDirection
|
||||
*/
|
||||
tryPassOverItem(item, receiver, slotIndex, localDirection) {
|
||||
tryPassOverItem(item, receiver, slotIndex) {
|
||||
// Try figuring out how what to do with the item
|
||||
// TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell.
|
||||
// Also its just a few cases (hope it stays like this .. :x).
|
||||
@@ -102,8 +99,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
const beltComp = receiver.components.Belt;
|
||||
if (beltComp) {
|
||||
// Ayy, its a belt!
|
||||
if (beltComp.canAcceptNewItem(localDirection)) {
|
||||
beltComp.takeNewItem(item, localDirection);
|
||||
if (beltComp.canAcceptNewItem()) {
|
||||
beltComp.takeNewItem(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -111,7 +108,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
const itemProcessorComp = receiver.components.ItemProcessor;
|
||||
if (itemProcessorComp) {
|
||||
// Its an item processor ..
|
||||
if (itemProcessorComp.tryTakeItem(item, slotIndex, localDirection)) {
|
||||
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,16 @@
|
||||
import { Math_max } from "../../core/builtins";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { enumColorMixingResults } from "../colors";
|
||||
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
|
||||
import { Entity } from "../entity";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor";
|
||||
import { Math_max, Math_radians } from "../../core/builtins";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
import { enumDirectionToVector, enumDirection, enumDirectionToAngle } from "../../core/vector";
|
||||
import { ColorItem } from "../items/color_item";
|
||||
import { enumColorMixingResults } from "../colors";
|
||||
import { drawRotatedSprite } from "../../core/draw_utils";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
|
||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [ItemProcessorComponent]);
|
||||
|
||||
this.underlayBeltSprites = [
|
||||
Loader.getSprite("sprites/belt/forward_0.png"),
|
||||
Loader.getSprite("sprites/belt/forward_1.png"),
|
||||
Loader.getSprite("sprites/belt/forward_2.png"),
|
||||
Loader.getSprite("sprites/belt/forward_3.png"),
|
||||
Loader.getSprite("sprites/belt/forward_4.png"),
|
||||
Loader.getSprite("sprites/belt/forward_5.png"),
|
||||
];
|
||||
}
|
||||
|
||||
draw(parameters) {
|
||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this));
|
||||
}
|
||||
|
||||
drawUnderlays(parameters) {
|
||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this));
|
||||
}
|
||||
|
||||
update() {
|
||||
@@ -47,17 +26,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
processorComp.secondsUntilEject - globalConfig.physicsDeltaSeconds
|
||||
);
|
||||
|
||||
// Also, process item consumption animations to avoid items popping from the belts
|
||||
for (let animIndex = 0; animIndex < processorComp.itemConsumptionAnimations.length; ++animIndex) {
|
||||
const anim = processorComp.itemConsumptionAnimations[animIndex];
|
||||
anim.animProgress +=
|
||||
globalConfig.physicsDeltaSeconds * this.root.hubGoals.getBeltBaseSpeed() * 2;
|
||||
if (anim.animProgress > 1) {
|
||||
processorComp.itemConsumptionAnimations.splice(animIndex, 1);
|
||||
animIndex -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have any finished items we can eject
|
||||
if (
|
||||
processorComp.secondsUntilEject === 0 && // it was processed in time
|
||||
@@ -363,68 +331,4 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
processorComp.itemsToEject = outItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DrawParameters} parameters
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
drawEntity(parameters, entity) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const processorComp = entity.components.ItemProcessor;
|
||||
const acceptorComp = entity.components.ItemAcceptor;
|
||||
|
||||
for (let animIndex = 0; animIndex < processorComp.itemConsumptionAnimations.length; ++animIndex) {
|
||||
const { item, slotIndex, animProgress, direction } = processorComp.itemConsumptionAnimations[
|
||||
animIndex
|
||||
];
|
||||
|
||||
const slotData = acceptorComp.slots[slotIndex];
|
||||
const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin);
|
||||
|
||||
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];
|
||||
const finalTile = slotWorldPos.subScalars(
|
||||
fadeOutDirection.x * (animProgress / 2 - 0.5),
|
||||
fadeOutDirection.y * (animProgress / 2 - 0.5)
|
||||
);
|
||||
item.draw(
|
||||
(finalTile.x + 0.5) * globalConfig.tileSize,
|
||||
(finalTile.y + 0.5) * globalConfig.tileSize,
|
||||
parameters
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {DrawParameters} parameters
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
drawEntityUnderlays(parameters, entity) {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const processorComp = entity.components.ItemProcessor;
|
||||
|
||||
const underlays = processorComp.beltUnderlays;
|
||||
for (let i = 0; i < underlays.length; ++i) {
|
||||
const { pos, direction } = underlays[i];
|
||||
|
||||
const transformedPos = staticComp.localTileToWorld(pos);
|
||||
const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)];
|
||||
|
||||
// SYNC with systems/belt.js:drawSingleEntity!
|
||||
const animationIndex = Math.floor(
|
||||
(this.root.time.now() *
|
||||
this.root.hubGoals.getBeltBaseSpeed() *
|
||||
this.underlayBeltSprites.length *
|
||||
126) /
|
||||
42
|
||||
);
|
||||
|
||||
drawRotatedSprite({
|
||||
parameters,
|
||||
sprite: this.underlayBeltSprites[animationIndex % this.underlayBeltSprites.length],
|
||||
x: (transformedPos.x + 0.5) * globalConfig.tileSize,
|
||||
y: (transformedPos.y + 0.5) * globalConfig.tileSize,
|
||||
angle: Math_radians(angle),
|
||||
size: globalConfig.tileSize,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ export class StaticMapEntitySystem extends GameSystem {
|
||||
return;
|
||||
}
|
||||
|
||||
const drawEntitiesOutside = parameters.zoomLevel < globalConfig.mapChunkPrerenderMinZoom;
|
||||
const drawOutlinesOnly = parameters.zoomLevel < globalConfig.mapChunkOverviewMinZoom;
|
||||
|
||||
const contents = chunk.contents;
|
||||
@@ -54,17 +53,8 @@ export class StaticMapEntitySystem extends GameSystem {
|
||||
} else {
|
||||
const spriteKey = staticComp.spriteKey;
|
||||
if (spriteKey) {
|
||||
// Check if origin is contained to avoid drawing entities multiple times
|
||||
if (
|
||||
drawEntitiesOutside ||
|
||||
(staticComp.origin.x >= chunk.tileX &&
|
||||
staticComp.origin.x < chunk.tileX + globalConfig.mapChunkSize &&
|
||||
staticComp.origin.y >= chunk.tileY &&
|
||||
staticComp.origin.y < chunk.tileY + globalConfig.mapChunkSize)
|
||||
) {
|
||||
const sprite = Loader.getSprite(spriteKey);
|
||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
||||
}
|
||||
const sprite = Loader.getSprite(spriteKey);
|
||||
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user