Add actuator model
This commit is contained in:
parent
873a2a8d0a
commit
c811b5b1e5
@ -15,7 +15,7 @@ interface ICommandBarProps {
|
||||
}
|
||||
|
||||
@useSetting
|
||||
@useStatusWithEvent("mouseModChange")
|
||||
@useStatusWithEvent("mouseModChange", "actuatorStartChange")
|
||||
class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixinStatusProps> {
|
||||
|
||||
render(): ReactNode {
|
||||
@ -34,7 +34,13 @@ class CommandBar extends Component<ICommandBarProps & IMixinSettingProps & IMixi
|
||||
>
|
||||
<div>
|
||||
{this.getRenderButton({ iconName: "Save", i18NKey: "Command.Bar.Save.Info" })}
|
||||
{this.getRenderButton({ iconName: "Play", i18NKey: "Command.Bar.Play.Info" })}
|
||||
{this.getRenderButton({
|
||||
iconName: this.props.status?.actuator.start() ? "Pause" : "Play",
|
||||
i18NKey: "Command.Bar.Play.Info",
|
||||
click: () => this.props.status ? this.props.status.actuator.start(
|
||||
!this.props.status.actuator.start()
|
||||
) : undefined
|
||||
})}
|
||||
{this.getRenderButton({
|
||||
iconName: "HandsFree", i18NKey: "Command.Bar.Drag.Info",
|
||||
active: mouseMod === MouseMod.Drag,
|
||||
|
@ -42,7 +42,7 @@ class HeaderBar extends Component<
|
||||
return (t: number) => {
|
||||
let newState: HeaderBarState = {} as any;
|
||||
newState[type] = 1 / t;
|
||||
if (this.updateTime > 60) {
|
||||
if (this.updateTime > 20) {
|
||||
this.updateTime = 0;
|
||||
this.setState(newState);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import { I18N } from "@Component/Localization/Localization";
|
||||
import { superConnectWithEvent, superConnect } from "./Context";
|
||||
import { PopupController } from "./Popups";
|
||||
import { Behavior } from "@Model/Behavior";
|
||||
import { Actuator } from "@Model/Actuator";
|
||||
|
||||
function randomColor(unNormal: boolean = false) {
|
||||
const color = [
|
||||
@ -44,6 +45,7 @@ interface IStatusEvent {
|
||||
individualChange: void;
|
||||
behaviorChange: void;
|
||||
popupChange: void;
|
||||
actuatorStartChange: void;
|
||||
}
|
||||
|
||||
class Status extends Emitter<IStatusEvent> {
|
||||
@ -71,6 +73,11 @@ class Status extends Emitter<IStatusEvent> {
|
||||
*/
|
||||
public model: Model = new Model();
|
||||
|
||||
/**
|
||||
* 执行器
|
||||
*/
|
||||
public actuator: Actuator;
|
||||
|
||||
/**
|
||||
* 弹窗
|
||||
*/
|
||||
@ -104,8 +111,14 @@ class Status extends Emitter<IStatusEvent> {
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
// 初始化执行器
|
||||
this.actuator = new Actuator(this.model);
|
||||
|
||||
// 执行器开启事件
|
||||
this.actuator.on("startChange", () => { this.emit("actuatorStartChange") });
|
||||
|
||||
// 循环事件
|
||||
this.model.on("loop", (t) => { this.emit("physicsLoop", t) });
|
||||
this.actuator.on("loop", (t) => { this.emit("physicsLoop", t) });
|
||||
|
||||
// 对象变化事件
|
||||
this.model.on("objectChange", () => this.emit("objectChange"));
|
||||
|
125
source/Model/Actuator.ts
Normal file
125
source/Model/Actuator.ts
Normal file
@ -0,0 +1,125 @@
|
||||
import { Model } from "./Model";
|
||||
import { Emitter } from "./Emitter";
|
||||
|
||||
interface IActuatorEvent {
|
||||
startChange: boolean;
|
||||
loop: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型执行器
|
||||
*/
|
||||
class Actuator extends Emitter<IActuatorEvent> {
|
||||
|
||||
/**
|
||||
* 速度系数
|
||||
*/
|
||||
public speed: number = 1;
|
||||
|
||||
/**
|
||||
* 模拟帧率
|
||||
*/
|
||||
public fps: number = 24;
|
||||
|
||||
/**
|
||||
* 仿真是否进行
|
||||
*/
|
||||
private startFlag: boolean = false;
|
||||
|
||||
/**
|
||||
* 主时钟状态控制
|
||||
*/
|
||||
public start(start?: boolean): boolean {
|
||||
if (start === undefined) {
|
||||
return this.startFlag;
|
||||
} else {
|
||||
this.startFlag = start;
|
||||
this.lastTime = 0;
|
||||
this.alignTimer = 0;
|
||||
this.emit("startChange", start);
|
||||
return start;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定模型
|
||||
*/
|
||||
public model: Model;
|
||||
|
||||
/**
|
||||
* 上一帧的时间
|
||||
*/
|
||||
private lastTime: number = 0;
|
||||
|
||||
/**
|
||||
* 对其计时器
|
||||
*/
|
||||
private alignTimer: number = 0;
|
||||
|
||||
public tickerType: 1 | 2 = 1;
|
||||
|
||||
private ticker(t: number) {
|
||||
if (this.startFlag && t !== 0) {
|
||||
if (this.lastTime === 0) {
|
||||
this.lastTime = t;
|
||||
} else {
|
||||
let durTime = (t - this.lastTime) / 1000;
|
||||
this.lastTime = t;
|
||||
|
||||
// 丢帧判定
|
||||
if (durTime > 0.1) {
|
||||
console.log("Actuator: Ticker dur time error. dropping...")
|
||||
}
|
||||
|
||||
this.alignTimer += durTime;
|
||||
if (this.alignTimer > (1 / this.fps)) {
|
||||
this.model.update(this.alignTimer * this.speed);
|
||||
this.emit("loop", this.alignTimer);
|
||||
this.alignTimer = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.emit("loop", Infinity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 帧率对其时钟
|
||||
* 1、使用 requestAnimationFrame 保证最高的性能
|
||||
* 2、最大模拟帧率只能小于 60
|
||||
* 3、可能出现帧率对其问题
|
||||
*/
|
||||
private tickerAlign = (t: number) => {
|
||||
this.ticker(t);
|
||||
requestAnimationFrame(this.tickerAlign);
|
||||
}
|
||||
|
||||
/**
|
||||
* 精确时钟
|
||||
*/
|
||||
private tickerExp = () => {
|
||||
this.ticker(window.performance.now());
|
||||
setTimeout(this.tickerExp, (1 / this.fps) * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行器
|
||||
*/
|
||||
private runTicker = (t: number) => {
|
||||
if (this.tickerType === 1) {
|
||||
this.ticker(t);
|
||||
requestAnimationFrame(this.runTicker);
|
||||
} else {
|
||||
this.ticker(window.performance.now());
|
||||
setTimeout(this.runTicker, (1 / this.fps) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public constructor(model: Model) {
|
||||
super();
|
||||
this.model = model;
|
||||
this.runTicker(0);
|
||||
}
|
||||
}
|
||||
|
||||
export { Actuator }
|
@ -8,7 +8,6 @@ import { Label } from "./Label";
|
||||
import { Behavior, IAnyBehavior, IAnyBehaviorRecorder } from "./Behavior";
|
||||
|
||||
type ModelEvent = {
|
||||
loop: number;
|
||||
labelChange: Label[];
|
||||
objectChange: CtrlObject[];
|
||||
individualChange: Group;
|
||||
@ -280,8 +279,6 @@ class Model extends Emitter<ModelEvent> {
|
||||
}
|
||||
|
||||
this.draw();
|
||||
|
||||
this.emit("loop", t);
|
||||
}
|
||||
|
||||
public draw() {
|
||||
|
Loading…
Reference in New Issue
Block a user