From 3026c463bd4b7372a9a404574075fd42091c731d Mon Sep 17 00:00:00 2001 From: MrKBear Date: Fri, 8 Apr 2022 21:46:33 +0800 Subject: [PATCH] Add combo input into parameter --- source/Behavior/BoundaryConstraint.ts | 51 +++++----- source/Behavior/Brownian.ts | 80 ++++++---------- source/Behavior/Dynamics.ts | 94 +++++++------------ source/Behavior/Template.ts | 78 ++++----------- source/Input/ComboInput/ComboInput.tsx | 2 +- source/Input/Parameter/Parameter.tsx | 88 +++++++++++++---- source/Localization/EN-US.ts | 1 + source/Localization/ZH-CN.ts | 1 + source/Model/Parameter.ts | 2 +- .../Panel/BehaviorDetails/BehaviorDetails.tsx | 2 +- 10 files changed, 181 insertions(+), 218 deletions(-) diff --git a/source/Behavior/BoundaryConstraint.ts b/source/Behavior/BoundaryConstraint.ts index 32c7c71..befd8c5 100644 --- a/source/Behavior/BoundaryConstraint.ts +++ b/source/Behavior/BoundaryConstraint.ts @@ -24,38 +24,10 @@ class BoundaryConstraint extends Behavior> = { - "$Title": { - "ZH_CN": "边界约束", - "EN_US": "Boundary constraint" - }, - "$range": { - "ZH_CN": "约束范围", - "EN_US": "Constraint range" - }, - "$Strength": { - "ZH_CN": "约束强度系数", - "EN_US": "Restraint strength coefficient" - }, - "$Intro": { - "ZH_CN": "个体越出边界后将主动返回", - "EN_US": "Individuals will return actively after crossing the border" - } - }; - public effect(individual: Individual, group: Group, model: Model, t: number): void { let rangeList: Range[] = this.parameter.range.objects; @@ -99,6 +71,25 @@ class BoundaryConstraint extends Behavior> = { + "$Title": { + "ZH_CN": "边界约束", + "EN_US": "Boundary constraint" + }, + "$range": { + "ZH_CN": "约束范围", + "EN_US": "Constraint range" + }, + "$Strength": { + "ZH_CN": "约束强度系数", + "EN_US": "Restraint strength coefficient" + }, + "$Intro": { + "ZH_CN": "个体越出边界后将主动返回", + "EN_US": "Individuals will return actively after crossing the border" + } + }; } export { BoundaryConstraint }; \ No newline at end of file diff --git a/source/Behavior/Brownian.ts b/source/Behavior/Brownian.ts index c468d20..62e04aa 100644 --- a/source/Behavior/Brownian.ts +++ b/source/Behavior/Brownian.ts @@ -25,37 +25,36 @@ class Brownian extends Behavior> = { + public effect(individual: Individual, group: Group, model: Model, t: number): void { + + const {maxFrequency, minFrequency, maxStrength, minStrength} = this.parameter; + + let nextTime = individual.getData("Brownian.nextTime") ?? + minFrequency + Math.random() * (maxFrequency - minFrequency); + let currentTime = individual.getData("Brownian.currentTime") ?? 0; + + currentTime += t; + if (currentTime > nextTime) { + individual.applyForce( + minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), + minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), + minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength) + ); + nextTime = minFrequency + Math.random() * (maxFrequency - minFrequency); + currentTime = 0; + } + + individual.setData("Brownian.nextTime", nextTime); + individual.setData("Brownian.currentTime", currentTime); + } + + public override terms: Record> = { "$Title": { "ZH_CN": "布朗运动", "EN_US": "Brownian motion" @@ -81,29 +80,6 @@ class Brownian extends Behavior nextTime) { - individual.applyForce( - minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), - minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength), - minStrength + (Math.random() * 2 - 1) * (maxStrength - minStrength) - ); - nextTime = minFrequency + Math.random() * (maxFrequency - minFrequency); - currentTime = 0; - } - - individual.setData("Brownian.nextTime", nextTime); - individual.setData("Brownian.currentTime", currentTime); - } } export { Brownian }; \ No newline at end of file diff --git a/source/Behavior/Dynamics.ts b/source/Behavior/Dynamics.ts index d41ef84..34c122a 100644 --- a/source/Behavior/Dynamics.ts +++ b/source/Behavior/Dynamics.ts @@ -25,67 +25,12 @@ class Dynamics extends Behavior> = { - "$Title": { - "ZH_CN": "动力学", - "EN_US": "Dynamics" - }, - "$Intro": { - "ZH_CN": "一切可以运动物体的必要行为,执行物理法则。", - "EN_US": "All necessary behaviors that can move objects and implement the laws of physics." - }, - "$Mass": { - "ZH_CN": "质量 (Kg)", - "EN_US": "Mass (Kg)" - }, - "$Max.Acceleration": { - "ZH_CN": "最大加速度 (m/s²)", - "EN_US": "Maximum acceleration (m/s²)" - }, - "$Max.Velocity": { - "ZH_CN": "最大速度 (m/s)", - "EN_US": "Maximum velocity (m/s)" - }, - "$Resistance": { - "ZH_CN": "阻力系数", - "EN_US": "Resistance coefficient" - }, - "$Physics": { - "ZH_CN": "物理", - "EN_US": "Physics" - } - }; - public override finalEffect(individual: Individual, group: Group, model: Model, t: number): void { // 计算当前速度 @@ -139,6 +84,37 @@ class Dynamics extends Behavior> = { + "$Title": { + "ZH_CN": "动力学", + "EN_US": "Dynamics" + }, + "$Intro": { + "ZH_CN": "一切可以运动物体的必要行为,执行物理法则。", + "EN_US": "All necessary behaviors that can move objects and implement the laws of physics." + }, + "$Mass": { + "ZH_CN": "质量 (Kg)", + "EN_US": "Mass (Kg)" + }, + "$Max.Acceleration": { + "ZH_CN": "最大加速度 (m/s²)", + "EN_US": "Maximum acceleration (m/s²)" + }, + "$Max.Velocity": { + "ZH_CN": "最大速度 (m/s)", + "EN_US": "Maximum velocity (m/s)" + }, + "$Resistance": { + "ZH_CN": "阻力系数", + "EN_US": "Resistance coefficient" + }, + "$Physics": { + "ZH_CN": "物理", + "EN_US": "Physics" + } + }; } export { Dynamics }; \ No newline at end of file diff --git a/source/Behavior/Template.ts b/source/Behavior/Template.ts index dff6373..48d75be 100644 --- a/source/Behavior/Template.ts +++ b/source/Behavior/Template.ts @@ -31,62 +31,24 @@ class Template extends Behavior> = { "$Title": { "ZH_CN": "行为", @@ -99,12 +61,12 @@ class Template extends Behavior { { this.props.value ? : - null + }
diff --git a/source/Input/Parameter/Parameter.tsx b/source/Input/Parameter/Parameter.tsx index 024195c..deb6c4b 100644 --- a/source/Input/Parameter/Parameter.tsx +++ b/source/Input/Parameter/Parameter.tsx @@ -4,9 +4,10 @@ import { AttrInput } from "@Input/AttrInput/AttrInput"; import { ObjectID } from "@Model/Renderer"; import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; -import { AllI18nKeys } from "@Component/Localization/Localization"; +import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; import { Message } from "@Input/Message/Message"; import { ColorInput } from "@Input/ColorInput/ColorInput"; +import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput"; import { IParameter, IParameterOption, IParameterOptionItem, IParameterValue, IParamValue, isObjectType, isVectorType @@ -18,7 +19,7 @@ interface IParameterProps

{ value: IParameterValue

; key: ObjectID; change: (key: K, val: IParamValue) => any; - i18n: (option: IParameterOptionItem, language: Language) => string; + i18n?: (key: string, language: Language) => string; title?: AllI18nKeys; titleOption?: Record; isFirst?: boolean; @@ -30,16 +31,29 @@ class Parameter

extends Component & IMi private renderParameter (key: K, option: IParameterOptionItem, value: IParamValue): ReactNode { + const language = this.props.setting?.language ?? "EN_US"; const indexKey = `${this.props.key}-${key}`; const type = option.type; - const i18nString = this.props.i18n(option, this.props.setting?.language ?? "EN_US"); + let keyI18n: string, keyI18nOption: Record | undefined; + + // Custom I18N + if (this.props.i18n) { + keyI18n = "Panel.Info.Behavior.Details.Parameter.Key"; + keyI18nOption = { + key: this.props.i18n(option.name, language) + }; + } + + else { + keyI18n = option.name; + } if (type === "number") { return extends Component & IMi return ?? ""} valueChange={(val) => { @@ -69,8 +83,8 @@ class Parameter

extends Component & IMi else if (type === "boolean") { return ?? false} @@ -87,8 +101,8 @@ class Parameter

extends Component & IMi return { @@ -106,8 +120,8 @@ class Parameter

extends Component & IMi return ?? false} valueChange={(val) => { @@ -116,10 +130,52 @@ class Parameter

extends Component & IMi /> } + else if (type === "option") { + + let allOption: IDisplayItem[] = []; + let focusKey: number = -1; + + if (option.allOption) { + for (let i = 0; i < option.allOption.length; i++) { + + if (this.props.i18n) { + allOption.push({ + i18nOption: { key: this.props.i18n(option.allOption[i].name, language) }, + i18n: "Panel.Info.Behavior.Details.Parameter.Key", + key: option.allOption[i].key + }) + } + + else { + allOption.push({ + i18n: option.allOption[i].name, + key: option.allOption[i].key + }) + } + + if (option.allOption[i].key === value) { + focusKey = i; + } + } + } + + return { + this.props.change(key, val.key as IParamValue); + }} + /> + } + else if (type === "vec") { type IObjectParamValue = IParamValue<"vec">; const typedValue = value as IObjectParamValue; + const i18nVal = I18N(this.props, keyI18n, keyI18nOption); return @@ -127,7 +183,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-X`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} @@ -144,7 +200,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-Y`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} @@ -161,7 +217,7 @@ class Parameter

extends Component & IMi key={`${indexKey}-Z`} id={indexKey} keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" - keyI18nOption={{ key: i18nString }} + keyI18nOption={{ key: i18nVal }} isNumber={true} step={option.numberStep} maxLength={option.maxLength} diff --git a/source/Localization/EN-US.ts b/source/Localization/EN-US.ts index b172fad..52e32be 100644 --- a/source/Localization/EN-US.ts +++ b/source/Localization/EN-US.ts @@ -25,6 +25,7 @@ const EN_US = { "Input.Error.Length": "The length of the input content must be less than {num}", "Input.Error.Length.Less": "The length of the input content must be greater than {num}", "Input.Error.Select": "Select object ...", + "Input.Error.Combo": "Select options ...", "Object.List.New.Group": "Group object {id}", "Object.List.New.Range": "Range object {id}", "Object.List.New.Label": "Label {id}", diff --git a/source/Localization/ZH-CN.ts b/source/Localization/ZH-CN.ts index 8403f11..3dd7c6b 100644 --- a/source/Localization/ZH-CN.ts +++ b/source/Localization/ZH-CN.ts @@ -25,6 +25,7 @@ const ZH_CN = { "Input.Error.Length": "输入内容长度须小于 {number}", "Input.Error.Length.Less": "输入内容长度须大于 {number}", "Input.Error.Select": "选择对象 ...", + "Input.Error.Combo": "选择选项 ...", "Object.List.New.Group": "群对象 {id}", "Object.List.New.Range": "范围对象 {id}", "Object.List.New.Label": "标签 {id}", diff --git a/source/Model/Parameter.ts b/source/Model/Parameter.ts index 8ab4192..54bf988 100644 --- a/source/Model/Parameter.ts +++ b/source/Model/Parameter.ts @@ -116,7 +116,7 @@ interface IParameterOptionItem { /** * 全部选项 */ - allOption?: string[]; + allOption?: Array<{key: string, name: string}>; } interface IParameter { diff --git a/source/Panel/BehaviorDetails/BehaviorDetails.tsx b/source/Panel/BehaviorDetails/BehaviorDetails.tsx index 7090ee8..e3490e9 100644 --- a/source/Panel/BehaviorDetails/BehaviorDetails.tsx +++ b/source/Panel/BehaviorDetails/BehaviorDetails.tsx @@ -65,7 +65,7 @@ class BehaviorDetails extends Component behavior.getTerms(option.name, language)} + i18n={(name, language) => behavior.getTerms(name, language)} title={"Panel.Info.Behavior.Details.Behavior.Props"} titleOption={{ behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language)