信号机调整

This commit is contained in:
fan 2023-12-25 14:02:31 +08:00
parent deb355c0f2
commit 559ffbd04b
4 changed files with 494 additions and 0 deletions

102
packages/Signal/Lamp.ts Normal file
View File

@ -0,0 +1,102 @@
import { Container } from '@pixi/display';
import { Graphics } from 'pixi.js';
const lampConsts = {
lampRadius: 8,
logicModeLineWidth: 2,
logicModeDistance: 5,
logicModeColor: '0x000000',
lampLineWidth: 1,
lampLineColor: '0x3149c3',
lampBadColor: '0xFF0000',
badStart: 10,
badEnd: 15,
};
export class Lamp extends Container {
circleLamp: Graphics = new Graphics();
logicMode: Graphics = new Graphics();
lampBad: Graphics = new Graphics();
radiusX = 0;
radiusY = 0;
constructor() {
super();
this.addChild(this.circleLamp);
this.addChild(this.logicMode);
this.addChild(this.lampBad);
}
paint(radiusX: number, radiusY: number) {
this.radiusX = radiusX;
this.radiusY = radiusY;
this.createLamp();
}
createLampBad() {
this.lampBad.clear();
this.lampBad.lineStyle(lampConsts.lampLineWidth, lampConsts.lampBadColor);
this.lampBad.moveTo(this.radiusX + lampConsts.badStart, this.radiusY);
this.lampBad.lineTo(this.radiusX + lampConsts.badEnd, this.radiusY);
this.lampBad.moveTo(this.radiusX - lampConsts.badStart, this.radiusY);
this.lampBad.lineTo(this.radiusX - lampConsts.badEnd, this.radiusY);
this.lampBad.moveTo(this.radiusX, this.radiusY + lampConsts.badStart);
this.lampBad.lineTo(this.radiusX, this.radiusY + lampConsts.badEnd);
this.lampBad.moveTo(this.radiusX, this.radiusY - lampConsts.badStart);
this.lampBad.lineTo(this.radiusX, this.radiusY - lampConsts.badEnd);
const xieStart = Math.sin(Math.PI / 4) * lampConsts.badStart;
const xieEnd = Math.sin(Math.PI / 4) * lampConsts.badEnd;
this.lampBad.moveTo(this.radiusX + xieStart, this.radiusY + xieStart);
this.lampBad.lineTo(this.radiusX + xieEnd, this.radiusY + xieEnd);
this.lampBad.moveTo(this.radiusX + xieStart, this.radiusY - xieStart);
this.lampBad.lineTo(this.radiusX + xieEnd, this.radiusY - xieEnd);
this.lampBad.moveTo(this.radiusX - xieStart, this.radiusY - xieStart);
this.lampBad.lineTo(this.radiusX - xieEnd, this.radiusY - xieEnd);
this.lampBad.moveTo(this.radiusX - xieStart, this.radiusY + xieStart);
this.lampBad.lineTo(this.radiusX - xieEnd, this.radiusY + xieEnd);
}
createLamp(color?: string) {
this.circleLamp.clear();
this.circleLamp.lineStyle(
lampConsts.lampLineWidth,
lampConsts.lampLineColor
);
if (!color) {
this.circleLamp.beginFill('0XFFFFFF', 0);
} else {
this.circleLamp.beginFill(color, 1);
}
this.circleLamp.drawCircle(
this.radiusX,
this.radiusY,
lampConsts.lampRadius
);
this.circleLamp.endFill();
}
createLogicMode() {
this.logicMode
.clear()
.lineStyle(lampConsts.logicModeLineWidth, lampConsts.logicModeColor)
.moveTo(
this.radiusX - lampConsts.logicModeDistance,
this.radiusY + lampConsts.logicModeDistance
)
.lineTo(
this.radiusX + lampConsts.logicModeDistance,
this.radiusY - lampConsts.logicModeDistance
)
.moveTo(
this.radiusX - lampConsts.logicModeDistance,
this.radiusY - lampConsts.logicModeDistance
)
.lineTo(
this.radiusX + lampConsts.logicModeDistance,
this.radiusY + lampConsts.logicModeDistance
);
}
logicModeClear() {
this.logicMode.clear();
}
lampClear() {
this.circleLamp.clear();
}
}

View File

@ -0,0 +1,123 @@
import { Graphics, Point, Container } from 'pixi.js';
import {
calculateMirrorPoint,
GraphicAnimation,
} from 'jl-graphic';
import { Lamp } from './Lamp';
import { SignalColorEnum, signalConsts, Model } from './Signal';
export class LampMainBody extends Container {
static Type = 'LampMainBody';
lampNum = 1;
lampPost: Graphics = new Graphics();
lamps: Lamp[] = [];
mirror = false;
deltaTime = 0;
constructor() {
super();
}
paint(mt: Model, mirror: boolean) {
this.mirror = mirror;
if (
mt === Model.HL ||
mt === Model.AB
) {
this.lampNum = 2;
} else {
this.lampNum = 3;
}
this.removeChildren(0);
this.lampPost = new Graphics();
let lpp = new Point(signalConsts.levelLampPostLength, 0);
if (mirror) {
lpp = calculateMirrorPoint(new Point(0, 0), lpp);
}
this.lampPost
.lineStyle(signalConsts.postLineWidth, SignalColorEnum.lampPostColor)
.moveTo(0, -signalConsts.verticalLampPostLength / 2)
.lineTo(0, signalConsts.verticalLampPostLength / 2)
.moveTo(0, 0)
.lineTo(lpp.x, lpp.y);
this.addChild(this.lampPost);
this.lamps = [];
for (let i = 0; i < this.lampNum; i++) {
const lamp = new Lamp();
this.addChild(lamp);
const radiusX =
(1 + i * 2) * signalConsts.lampRadius +
signalConsts.levelLampPostLength;
let lrp = new Point(radiusX, 0);
if (mirror) {
lrp = calculateMirrorPoint(new Point(0, 0), lrp);
}
lamp.paint(lrp.x, lrp.y);
this.lamps.push(lamp);
}
}
setStateH() {
this.lamps[0].createLamp(SignalColorEnum.redLamp);
this.lamps.forEach((lamp, index) => {
if (index !== 0) {
lamp.createLamp(SignalColorEnum.closeLamp);
}
});
}
setStateL() {
this.lamps[1].createLamp(SignalColorEnum.greenLamp);
this.lamps.forEach((lamp, index) => {
if(index !==1) {
lamp.createLamp(SignalColorEnum.closeLamp);
}
});
}
setStateU() {
this.lamps[2].createLamp(SignalColorEnum.yellowLamp);
this.lamps.forEach((lamp, index) => {
if (index !== 2) {
lamp.createLamp(SignalColorEnum.closeLamp);
}
})
}
setStateHu() {
this.lamps[0].createLamp(SignalColorEnum.redLamp);
this.lamps[1].createLamp(SignalColorEnum.closeLamp);
this.lamps[2].createLamp(SignalColorEnum.yellowLamp);
}
setStateA() {
this.lamps[0].createLamp(SignalColorEnum.blueLamp);
this.lamps[1].createLamp(SignalColorEnum.closeLamp);
}
setStateB() {
this.lamps[0].createLamp(SignalColorEnum.whiteLamp);
this.lamps[1].createLamp(SignalColorEnum.closeLamp);
}
setStateOff() {
this.lamps.forEach((lamp) =>
lamp.createLamp(SignalColorEnum.closeLamp)
);
}
createFlashAnmiation(
name: string,
color: string,
lampIndex: number
): GraphicAnimation {
const bgColor = '0X000000';
const flashAnmiation = GraphicAnimation.init({
name: name,
run: (dt: number) => {
this.deltaTime += dt;
if (this.deltaTime > 60) {
this.deltaTime = 0;
this.lamps[lampIndex].createLamp(color);
} else if (this.deltaTime > 30) {
this.lamps.forEach((lamp) => {
lamp.createLamp(bgColor);
});
}
},
});
return flashAnmiation;
}
}

228
packages/Signal/Signal.ts Normal file
View File

@ -0,0 +1,228 @@
import { GraphicData, calculateMirrorPoint } from 'jl-graphic'
import { Graphics, Point, Container } from 'pixi.js';
import { SignalCode } from './SignalCode';
import { LampMainBody } from './LampMainBody';
export enum Model {
HL = 0, // 红绿灯
HLU_FU = 1, // 红绿黄,封黄灯,无引导
HLU_DU_YY = 2, // 红绿黄,不封灯,有单黄,带引导
HLU_YY = 3, // 红绿黄,不封灯,无单黄,带引导
HLU_FL_DU_YY = 4, // 红绿黄,封绿灯,有单黄,带引导
HLU_DU = 5, // 红绿黄,不封灯,有单黄,无引导
AB = 6, // 蓝白
HBU_DU = 7 // 红白黄,不封灯,有单黄,无引导
}
export enum SignalColorEnum {
humanControlColor = '0xffff00',
fleetModeColor = '0x00ff00',
blockedColor = '0XFF0000',
defaultCodeColor = '0XFFFFFF',
lampPostColor = '0xFFFFFF',
redLamp = '0XFF0000',
greenLamp = '0X00FF00',
yellowLamp = '0XFFFF00',
whiteLamp = '0XFFFFFF',
blueLamp = '0X0033FF',
closeLamp = '0X000000',
logicModeColor = '0x000000',
lampLineColor = '0x3149c3',
}
export const signalConsts = {
fleetModeLength: 24,
fleetModeRadius: 8,
fleetModeLineWidth: 6,
humanControlRadius: 8,
codeOffset: 20,
codeFontSize: 11,
blockedLineWidth: 1,
verticalLampPostLength: 16,
levelLampPostLength: 4,
postLineWidth: 3,
lampRadius: 8,
logicModeLineWidth: 2,
logicModeDistance: 5,
lampLineWidth: 1,
};
export interface ISignalData extends GraphicData {
code: string
mirror: boolean;
mt: Model
}
export class Signal extends Container {
static Type = 'signal';
datas: ISignalData;
signalCode: SignalCode = new SignalCode();
humanControl: Graphics = new Graphics();
fleetMode: Graphics = new Graphics();
lampMainBody: LampMainBody = new LampMainBody();
blockedMode: Graphics = new Graphics();
constructor(datas: ISignalData) {
super();
this.datas = datas;
this.addChild(this.humanControl);
this.addChild(this.fleetMode);
this.addChild(this.lampMainBody);
this.addChild(this.signalCode);
}
doRepaint(): void {
const mirror = this.datas.mirror;
this.lampMainBody.paint(this.datas.mt, mirror);
this.signalCode.paint(this.datas);
const codeTransform = this.datas?.childTransforms?.find(
(item) => item.name === 'signalCode'
);
if (codeTransform) {
const position = codeTransform?.transform.position;
const rotation = codeTransform?.transform?.rotation;
this.signalCode.position.set(position?.x, position?.y);
this.signalCode.rotation = rotation || 0;
} else {
this.signalCode.position.set(0, signalConsts.codeOffset);
}
}
createFleetMode(): void {
const mirror = this.datas.mirror;
this.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1);
let lmp = new Point(
this.lampMainBody.width + signalConsts.fleetModeLength,
0
);
if (mirror) {
lmp = calculateMirrorPoint(new Point(0, 0), lmp);
}
drawArrow(
this.fleetMode,
lmp.x,
0,
signalConsts.fleetModeLength,
signalConsts.fleetModeRadius,
signalConsts.fleetModeLineWidth,
mirror
);
this.fleetMode.endFill();
}
createHumanControl(): void {
const mirror = this.datas.mirror;
this.humanControl.beginFill(SignalColorEnum.humanControlColor, 1);
if (this.humanControl.drawRegularPolygon) {
let hmp = new Point(-signalConsts.humanControlRadius, 0);
if (mirror) {
hmp = calculateMirrorPoint(new Point(0, 0), hmp);
}
this.humanControl.drawRegularPolygon(
hmp.x,
hmp.y,
signalConsts.humanControlRadius,
3,
(Math.PI / 2) * (mirror ? -1 : 1)
);
}
this.humanControl.endFill();
}
setStateBlocked() {
this.signalCode.createBlockedMode();
}
setStateH() {
this.lampMainBody.setStateH();
}
setStateL() {
this.lampMainBody.setStateL();
}
setStateU() {
this.lampMainBody.setStateU();
}
setStateHu() {
this.lampMainBody.setStateHu();
}
setStateA() {
this.lampMainBody.setStateA();
}
setStateB() {
this.lampMainBody.setStateB();
}
setStateOff() {
this.lampMainBody.setStateOff();
}
}
/**
*
* @param polygon
* @param x x坐标
* @param y y坐标
* @param length
* @param radius
* @param lineWidth 线
* @param mirror ()
*/
export function drawArrow(
polygon: Graphics,
x: number,
y: number,
length: number,
radius: number,
lineWidth: number,
mirror: boolean
) {
const trianglAcme = { x, y };
let triangleP1 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y + Math.cos(Math.PI / 6) * radius,
};
let triangleP2 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y - Math.cos(Math.PI / 6) * radius,
};
let lineP1 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y + lineWidth / 2,
};
let lineP2 = {
x: x - length,
y: y + lineWidth / 2,
};
let lineP3 = {
x: x - length,
y: y - lineWidth / 2,
};
let lineP4 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y - lineWidth / 2,
};
if (mirror) {
triangleP1 = calculateMirrorPoint(trianglAcme, triangleP1);
triangleP2 = calculateMirrorPoint(trianglAcme, triangleP2);
lineP1 = calculateMirrorPoint(trianglAcme, lineP1);
lineP2 = calculateMirrorPoint(trianglAcme, lineP2);
lineP3 = calculateMirrorPoint(trianglAcme, lineP3);
lineP4 = calculateMirrorPoint(trianglAcme, lineP4);
}
polygon.drawPolygon(
trianglAcme.x,
trianglAcme.y,
triangleP1.x,
triangleP1.y,
lineP1.x,
lineP1.y,
lineP2.x,
lineP2.y,
lineP3.x,
lineP3.y,
lineP4.x,
lineP4.y,
triangleP2.x,
triangleP2.y
);
}

View File

@ -0,0 +1,41 @@
import { Container, Graphics, Point } from 'pixi.js';
import { VectorText } from 'jl-graphic';
import {
ISignalData,
SignalColorEnum,
signalConsts,
} from './Signal';
export class SignalCode extends Container {
blockedMode: Graphics = new Graphics();
codeGraph: VectorText = new VectorText('');
name = 'signalCode';
constructor() {
super();
this.addChild(this.blockedMode);
this.addChild(this.codeGraph);
}
paint(datas: ISignalData) {
this.codeGraph.text = datas?.code || '信号机编号';
this.codeGraph.style.fill = SignalColorEnum.defaultCodeColor;
this.codeGraph.setVectorFontSize(signalConsts.codeFontSize);
this.codeGraph.anchor.set(0.5);
this.codeGraph.position.set(0, 0);
this.blockedMode.clear();
}
createBlockedMode() {
const codeRect = this.codeGraph.getBounds();
const rectP = this.screenToLocalPoint(new Point(codeRect.x, codeRect.y));
this.blockedMode.clear();
this.blockedMode.lineStyle(
signalConsts.blockedLineWidth,
SignalColorEnum.blockedColor
);
this.blockedMode.drawRect(
rectP.x,
rectP.y,
codeRect.width,
codeRect.height
);
}
}