贝塞尔曲线
This commit is contained in:
@@ -34,8 +34,8 @@
|
|||||||
- [x] 系统列表
|
- [x] 系统列表
|
||||||
- [x] 被动系统
|
- [x] 被动系统
|
||||||
- [x] 协调系统
|
- [x] 协调系统
|
||||||
- [ ] 数学库
|
- [x] 数学库
|
||||||
- [ ] 贝塞尔曲线
|
- [x] 贝塞尔曲线
|
||||||
- [ ] 快速随机数类
|
- [ ] 快速随机数类
|
||||||
|
|
||||||
## 作者其他库(egret)
|
## 作者其他库(egret)
|
||||||
|
|||||||
16
demo/libs/framework/framework.d.ts
vendored
16
demo/libs/framework/framework.d.ts
vendored
@@ -473,6 +473,13 @@ declare class Mover extends Component {
|
|||||||
applyMovement(motion: Vector2): void;
|
applyMovement(motion: Vector2): void;
|
||||||
move(motion: Vector2): CollisionResult;
|
move(motion: Vector2): CollisionResult;
|
||||||
}
|
}
|
||||||
|
declare class ProjectileMover extends Component {
|
||||||
|
private _tempTriggerList;
|
||||||
|
private _collider;
|
||||||
|
onAddedToEntity(): void;
|
||||||
|
move(motion: Vector2): boolean;
|
||||||
|
private notifyTriggerListeners;
|
||||||
|
}
|
||||||
declare abstract class Collider extends Component {
|
declare abstract class Collider extends Component {
|
||||||
shape: Shape;
|
shape: Shape;
|
||||||
physicsLayer: number;
|
physicsLayer: number;
|
||||||
@@ -787,6 +794,14 @@ declare class WindTransition extends SceneTransition {
|
|||||||
constructor(sceneLoadAction: Function);
|
constructor(sceneLoadAction: Function);
|
||||||
onBeginTransition(): Promise<void>;
|
onBeginTransition(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
declare class Bezier {
|
||||||
|
static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2;
|
||||||
|
static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2;
|
||||||
|
static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2;
|
||||||
|
static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2;
|
||||||
|
static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, end: Vector2, distanceTolerance?: number): Vector2[];
|
||||||
|
private static recursiveGetOptimizedDrawingPoints;
|
||||||
|
}
|
||||||
declare class Flags {
|
declare class Flags {
|
||||||
static isFlagSet(self: number, flag: number): boolean;
|
static isFlagSet(self: number, flag: number): boolean;
|
||||||
static isUnshiftedFlagSet(self: number, flag: number): boolean;
|
static isUnshiftedFlagSet(self: number, flag: number): boolean;
|
||||||
@@ -806,6 +821,7 @@ declare class MathHelper {
|
|||||||
static clamp(value: number, min: number, max: number): number;
|
static clamp(value: number, min: number, max: number): number;
|
||||||
static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2;
|
static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2;
|
||||||
static isEven(value: number): boolean;
|
static isEven(value: number): boolean;
|
||||||
|
static clamp01(value: number): number;
|
||||||
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
||||||
}
|
}
|
||||||
declare class Matrix2D {
|
declare class Matrix2D {
|
||||||
|
|||||||
@@ -2137,6 +2137,47 @@ var Mover = (function (_super) {
|
|||||||
};
|
};
|
||||||
return Mover;
|
return Mover;
|
||||||
}(Component));
|
}(Component));
|
||||||
|
var ProjectileMover = (function (_super) {
|
||||||
|
__extends(ProjectileMover, _super);
|
||||||
|
function ProjectileMover() {
|
||||||
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
_this._tempTriggerList = [];
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
ProjectileMover.prototype.onAddedToEntity = function () {
|
||||||
|
this._collider = this.entity.getComponent(Collider);
|
||||||
|
if (!this._collider)
|
||||||
|
console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!");
|
||||||
|
};
|
||||||
|
ProjectileMover.prototype.move = function (motion) {
|
||||||
|
if (!this._collider)
|
||||||
|
return false;
|
||||||
|
var didCollide = false;
|
||||||
|
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||||
|
var neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||||
|
for (var i = 0; i < neighbors.colliders.length; i++) {
|
||||||
|
var neighbor = neighbors.colliders[i];
|
||||||
|
if (this._collider.overlaps(neighbor)) {
|
||||||
|
didCollide = true;
|
||||||
|
this.notifyTriggerListeners(this._collider, neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return didCollide;
|
||||||
|
};
|
||||||
|
ProjectileMover.prototype.notifyTriggerListeners = function (self, other) {
|
||||||
|
other.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(self, other);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
this.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(other, self);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
};
|
||||||
|
return ProjectileMover;
|
||||||
|
}(Component));
|
||||||
var Collider = (function (_super) {
|
var Collider = (function (_super) {
|
||||||
__extends(Collider, _super);
|
__extends(Collider, _super);
|
||||||
function Collider() {
|
function Collider() {
|
||||||
@@ -3509,6 +3550,54 @@ var WindTransition = (function (_super) {
|
|||||||
};
|
};
|
||||||
return WindTransition;
|
return WindTransition;
|
||||||
}(SceneTransition));
|
}(SceneTransition));
|
||||||
|
var Bezier = (function () {
|
||||||
|
function Bezier() {
|
||||||
|
}
|
||||||
|
Bezier.getPoint = function (p0, p1, p2, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMinusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMinusT * oneMinusT), p0), Vector2.multiply(new Vector2(2 * oneMinusT * t), p1)), Vector2.multiply(new Vector2(t * t), p2));
|
||||||
|
};
|
||||||
|
Bezier.getFirstDerivative = function (p0, p1, p2, t) {
|
||||||
|
return Vector2.add(Vector2.multiply(new Vector2(2 * (1 - t)), Vector2.subtract(p1, p0)), Vector2.multiply(new Vector2(2 * t), Vector2.subtract(p2, p1)));
|
||||||
|
};
|
||||||
|
Bezier.getFirstDerivativeThree = function (start, firstControlPoint, secondControlPoint, end, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT), Vector2.subtract(firstControlPoint, start)), Vector2.multiply(new Vector2(6 * oneMunusT * t), Vector2.subtract(secondControlPoint, firstControlPoint))), Vector2.multiply(new Vector2(3 * t * t), Vector2.subtract(end, secondControlPoint)));
|
||||||
|
};
|
||||||
|
Bezier.getPointThree = function (start, firstControlPoint, secondControlPoint, end, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMunusT * oneMunusT * oneMunusT), start), Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), Vector2.multiply(new Vector2(3 * oneMunusT * t * t), secondControlPoint)), Vector2.multiply(new Vector2(t * t * t), end));
|
||||||
|
};
|
||||||
|
Bezier.getOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, distanceTolerance) {
|
||||||
|
if (distanceTolerance === void 0) { distanceTolerance = 1; }
|
||||||
|
var points = ListPool.obtain();
|
||||||
|
points.push(start);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance);
|
||||||
|
points.push(end);
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
Bezier.recursiveGetOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance) {
|
||||||
|
var pt12 = Vector2.divide(Vector2.add(start, firstCtrlPoint), new Vector2(2));
|
||||||
|
var pt23 = Vector2.divide(Vector2.add(firstCtrlPoint, secondCtrlPoint), new Vector2(2));
|
||||||
|
var pt34 = Vector2.divide(Vector2.add(secondCtrlPoint, end), new Vector2(2));
|
||||||
|
var pt123 = Vector2.divide(Vector2.add(pt12, pt23), new Vector2(2));
|
||||||
|
var pt234 = Vector2.divide(Vector2.add(pt23, pt34), new Vector2(2));
|
||||||
|
var pt1234 = Vector2.divide(Vector2.add(pt123, pt234), new Vector2(2));
|
||||||
|
var deltaLine = Vector2.subtract(end, start);
|
||||||
|
var d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
var d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) {
|
||||||
|
points.push(pt1234);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
|
||||||
|
};
|
||||||
|
return Bezier;
|
||||||
|
}());
|
||||||
var Flags = (function () {
|
var Flags = (function () {
|
||||||
function Flags() {
|
function Flags() {
|
||||||
}
|
}
|
||||||
@@ -3563,6 +3652,13 @@ var MathHelper = (function () {
|
|||||||
MathHelper.isEven = function (value) {
|
MathHelper.isEven = function (value) {
|
||||||
return value % 2 == 0;
|
return value % 2 == 0;
|
||||||
};
|
};
|
||||||
|
MathHelper.clamp01 = function (value) {
|
||||||
|
if (value < 0)
|
||||||
|
return 0;
|
||||||
|
if (value > 1)
|
||||||
|
return 1;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
MathHelper.angleBetweenVectors = function (from, to) {
|
MathHelper.angleBetweenVectors = function (from, to) {
|
||||||
return Math.atan2(to.y - from.y, to.x - from.x);
|
return Math.atan2(to.y - from.y, to.x - from.x);
|
||||||
};
|
};
|
||||||
|
|||||||
2
demo/libs/framework/framework.min.js
vendored
2
demo/libs/framework/framework.min.js
vendored
File diff suppressed because one or more lines are too long
16
source/bin/framework.d.ts
vendored
16
source/bin/framework.d.ts
vendored
@@ -473,6 +473,13 @@ declare class Mover extends Component {
|
|||||||
applyMovement(motion: Vector2): void;
|
applyMovement(motion: Vector2): void;
|
||||||
move(motion: Vector2): CollisionResult;
|
move(motion: Vector2): CollisionResult;
|
||||||
}
|
}
|
||||||
|
declare class ProjectileMover extends Component {
|
||||||
|
private _tempTriggerList;
|
||||||
|
private _collider;
|
||||||
|
onAddedToEntity(): void;
|
||||||
|
move(motion: Vector2): boolean;
|
||||||
|
private notifyTriggerListeners;
|
||||||
|
}
|
||||||
declare abstract class Collider extends Component {
|
declare abstract class Collider extends Component {
|
||||||
shape: Shape;
|
shape: Shape;
|
||||||
physicsLayer: number;
|
physicsLayer: number;
|
||||||
@@ -787,6 +794,14 @@ declare class WindTransition extends SceneTransition {
|
|||||||
constructor(sceneLoadAction: Function);
|
constructor(sceneLoadAction: Function);
|
||||||
onBeginTransition(): Promise<void>;
|
onBeginTransition(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
declare class Bezier {
|
||||||
|
static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2;
|
||||||
|
static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2;
|
||||||
|
static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2;
|
||||||
|
static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2;
|
||||||
|
static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, end: Vector2, distanceTolerance?: number): Vector2[];
|
||||||
|
private static recursiveGetOptimizedDrawingPoints;
|
||||||
|
}
|
||||||
declare class Flags {
|
declare class Flags {
|
||||||
static isFlagSet(self: number, flag: number): boolean;
|
static isFlagSet(self: number, flag: number): boolean;
|
||||||
static isUnshiftedFlagSet(self: number, flag: number): boolean;
|
static isUnshiftedFlagSet(self: number, flag: number): boolean;
|
||||||
@@ -806,6 +821,7 @@ declare class MathHelper {
|
|||||||
static clamp(value: number, min: number, max: number): number;
|
static clamp(value: number, min: number, max: number): number;
|
||||||
static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2;
|
static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2;
|
||||||
static isEven(value: number): boolean;
|
static isEven(value: number): boolean;
|
||||||
|
static clamp01(value: number): number;
|
||||||
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
static angleBetweenVectors(from: Vector2, to: Vector2): number;
|
||||||
}
|
}
|
||||||
declare class Matrix2D {
|
declare class Matrix2D {
|
||||||
|
|||||||
@@ -2137,6 +2137,47 @@ var Mover = (function (_super) {
|
|||||||
};
|
};
|
||||||
return Mover;
|
return Mover;
|
||||||
}(Component));
|
}(Component));
|
||||||
|
var ProjectileMover = (function (_super) {
|
||||||
|
__extends(ProjectileMover, _super);
|
||||||
|
function ProjectileMover() {
|
||||||
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
_this._tempTriggerList = [];
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
ProjectileMover.prototype.onAddedToEntity = function () {
|
||||||
|
this._collider = this.entity.getComponent(Collider);
|
||||||
|
if (!this._collider)
|
||||||
|
console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!");
|
||||||
|
};
|
||||||
|
ProjectileMover.prototype.move = function (motion) {
|
||||||
|
if (!this._collider)
|
||||||
|
return false;
|
||||||
|
var didCollide = false;
|
||||||
|
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||||
|
var neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||||
|
for (var i = 0; i < neighbors.colliders.length; i++) {
|
||||||
|
var neighbor = neighbors.colliders[i];
|
||||||
|
if (this._collider.overlaps(neighbor)) {
|
||||||
|
didCollide = true;
|
||||||
|
this.notifyTriggerListeners(this._collider, neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return didCollide;
|
||||||
|
};
|
||||||
|
ProjectileMover.prototype.notifyTriggerListeners = function (self, other) {
|
||||||
|
other.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(self, other);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
this.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (var i = 0; i < this._tempTriggerList.length; i++) {
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(other, self);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
};
|
||||||
|
return ProjectileMover;
|
||||||
|
}(Component));
|
||||||
var Collider = (function (_super) {
|
var Collider = (function (_super) {
|
||||||
__extends(Collider, _super);
|
__extends(Collider, _super);
|
||||||
function Collider() {
|
function Collider() {
|
||||||
@@ -3509,6 +3550,54 @@ var WindTransition = (function (_super) {
|
|||||||
};
|
};
|
||||||
return WindTransition;
|
return WindTransition;
|
||||||
}(SceneTransition));
|
}(SceneTransition));
|
||||||
|
var Bezier = (function () {
|
||||||
|
function Bezier() {
|
||||||
|
}
|
||||||
|
Bezier.getPoint = function (p0, p1, p2, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMinusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMinusT * oneMinusT), p0), Vector2.multiply(new Vector2(2 * oneMinusT * t), p1)), Vector2.multiply(new Vector2(t * t), p2));
|
||||||
|
};
|
||||||
|
Bezier.getFirstDerivative = function (p0, p1, p2, t) {
|
||||||
|
return Vector2.add(Vector2.multiply(new Vector2(2 * (1 - t)), Vector2.subtract(p1, p0)), Vector2.multiply(new Vector2(2 * t), Vector2.subtract(p2, p1)));
|
||||||
|
};
|
||||||
|
Bezier.getFirstDerivativeThree = function (start, firstControlPoint, secondControlPoint, end, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT), Vector2.subtract(firstControlPoint, start)), Vector2.multiply(new Vector2(6 * oneMunusT * t), Vector2.subtract(secondControlPoint, firstControlPoint))), Vector2.multiply(new Vector2(3 * t * t), Vector2.subtract(end, secondControlPoint)));
|
||||||
|
};
|
||||||
|
Bezier.getPointThree = function (start, firstControlPoint, secondControlPoint, end, t) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
var oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMunusT * oneMunusT * oneMunusT), start), Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), Vector2.multiply(new Vector2(3 * oneMunusT * t * t), secondControlPoint)), Vector2.multiply(new Vector2(t * t * t), end));
|
||||||
|
};
|
||||||
|
Bezier.getOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, distanceTolerance) {
|
||||||
|
if (distanceTolerance === void 0) { distanceTolerance = 1; }
|
||||||
|
var points = ListPool.obtain();
|
||||||
|
points.push(start);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance);
|
||||||
|
points.push(end);
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
Bezier.recursiveGetOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance) {
|
||||||
|
var pt12 = Vector2.divide(Vector2.add(start, firstCtrlPoint), new Vector2(2));
|
||||||
|
var pt23 = Vector2.divide(Vector2.add(firstCtrlPoint, secondCtrlPoint), new Vector2(2));
|
||||||
|
var pt34 = Vector2.divide(Vector2.add(secondCtrlPoint, end), new Vector2(2));
|
||||||
|
var pt123 = Vector2.divide(Vector2.add(pt12, pt23), new Vector2(2));
|
||||||
|
var pt234 = Vector2.divide(Vector2.add(pt23, pt34), new Vector2(2));
|
||||||
|
var pt1234 = Vector2.divide(Vector2.add(pt123, pt234), new Vector2(2));
|
||||||
|
var deltaLine = Vector2.subtract(end, start);
|
||||||
|
var d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
var d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) {
|
||||||
|
points.push(pt1234);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
|
||||||
|
};
|
||||||
|
return Bezier;
|
||||||
|
}());
|
||||||
var Flags = (function () {
|
var Flags = (function () {
|
||||||
function Flags() {
|
function Flags() {
|
||||||
}
|
}
|
||||||
@@ -3563,6 +3652,13 @@ var MathHelper = (function () {
|
|||||||
MathHelper.isEven = function (value) {
|
MathHelper.isEven = function (value) {
|
||||||
return value % 2 == 0;
|
return value % 2 == 0;
|
||||||
};
|
};
|
||||||
|
MathHelper.clamp01 = function (value) {
|
||||||
|
if (value < 0)
|
||||||
|
return 0;
|
||||||
|
if (value > 1)
|
||||||
|
return 1;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
MathHelper.angleBetweenVectors = function (from, to) {
|
MathHelper.angleBetweenVectors = function (from, to) {
|
||||||
return Math.atan2(to.y - from.y, to.x - from.x);
|
return Math.atan2(to.y - from.y, to.x - from.x);
|
||||||
};
|
};
|
||||||
|
|||||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -23,11 +23,12 @@ class Mover extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移动所有的非触发碰撞器并获得最近的碰撞
|
||||||
let colliders: Collider[] = this.entity.getComponents(Collider);
|
let colliders: Collider[] = this.entity.getComponents(Collider);
|
||||||
for (let i = 0; i < colliders.length; i ++){
|
for (let i = 0; i < colliders.length; i ++){
|
||||||
let collider = colliders[i];
|
let collider = colliders[i];
|
||||||
|
|
||||||
// 不检测触发器
|
// 不检测触发器 在我们移动后会重新访问它
|
||||||
if (collider.isTrigger)
|
if (collider.isTrigger)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -63,13 +64,23 @@ class Mover extends Component {
|
|||||||
return {collisionResult: collisionResult, motion: motion};
|
return {collisionResult: collisionResult, motion: motion};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将calculatemomovement应用到实体并更新triggerHelper
|
||||||
|
* @param motion
|
||||||
|
*/
|
||||||
public applyMovement(motion: Vector2){
|
public applyMovement(motion: Vector2){
|
||||||
|
// 移动实体到它的新位置,如果我们有一个碰撞,否则移动全部数量。当碰撞发生时,运动被更新
|
||||||
this.entity.position = Vector2.add(this.entity.position, motion);
|
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||||
|
|
||||||
|
// 对所有是触发器的碰撞器与所有宽相位碰撞器进行重叠检查。任何重叠都会导致触发事件。
|
||||||
if (this._triggerHelper)
|
if (this._triggerHelper)
|
||||||
this._triggerHelper.update();
|
this._triggerHelper.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过调用calculateMovement和applyMovement来移动考虑碰撞的实体;
|
||||||
|
* @param motion
|
||||||
|
*/
|
||||||
public move(motion: Vector2){
|
public move(motion: Vector2){
|
||||||
let movementResult = this.calculateMovement(motion);
|
let movementResult = this.calculateMovement(motion);
|
||||||
let collisionResult = movementResult.collisionResult;
|
let collisionResult = movementResult.collisionResult;
|
||||||
|
|||||||
56
source/src/ECS/Components/Physics/ProjectileMover.ts
Normal file
56
source/src/ECS/Components/Physics/ProjectileMover.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 只向itriggerlistener报告冲突的移动器
|
||||||
|
* 该对象将始终移动完整的距离
|
||||||
|
*/
|
||||||
|
class ProjectileMover extends Component {
|
||||||
|
private _tempTriggerList: ITriggerListener[] = [];
|
||||||
|
private _collider: Collider;
|
||||||
|
|
||||||
|
public onAddedToEntity(){
|
||||||
|
this._collider = this.entity.getComponent<Collider>(Collider);
|
||||||
|
if (!this._collider)
|
||||||
|
console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动考虑碰撞的实体
|
||||||
|
* @param motion
|
||||||
|
*/
|
||||||
|
public move(motion: Vector2): boolean{
|
||||||
|
if (!this._collider)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let didCollide = false;
|
||||||
|
|
||||||
|
// 获取我们在新位置可能发生碰撞的任何东西
|
||||||
|
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||||
|
|
||||||
|
// 获取任何可能在新位置发生碰撞的东西
|
||||||
|
let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||||
|
for (let i = 0; i < neighbors.colliders.length; i ++){
|
||||||
|
let neighbor = neighbors.colliders[i];
|
||||||
|
if (this._collider.overlaps(neighbor)){
|
||||||
|
didCollide = true;
|
||||||
|
this.notifyTriggerListeners(this._collider, neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return didCollide;
|
||||||
|
}
|
||||||
|
|
||||||
|
private notifyTriggerListeners(self: Collider, other: Collider){
|
||||||
|
// 通知我们重叠的碰撞器实体上的任何侦听器
|
||||||
|
other.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(self, other);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
|
||||||
|
// 通知此实体上的任何侦听器
|
||||||
|
this.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||||
|
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||||
|
this._tempTriggerList[i].onTriggerEnter(other, self);
|
||||||
|
}
|
||||||
|
this._tempTriggerList.length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
121
source/src/Math/Bezier.ts
Normal file
121
source/src/Math/Bezier.ts
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/** 贝塞尔帮助类 */
|
||||||
|
class Bezier {
|
||||||
|
/**
|
||||||
|
* 二次贝塞尔曲线
|
||||||
|
* @param p0
|
||||||
|
* @param p1
|
||||||
|
* @param p2
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2 {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
let oneMinusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMinusT * oneMinusT), p0),
|
||||||
|
Vector2.multiply(new Vector2(2 * oneMinusT * t), p1)), Vector2.multiply(new Vector2(t * t), p2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到二次贝塞尔函数的一阶导数
|
||||||
|
* @param p0
|
||||||
|
* @param p1
|
||||||
|
* @param p2
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number) {
|
||||||
|
return Vector2.add(Vector2.multiply(new Vector2(2 * (1 - t)), Vector2.subtract(p1, p0)),
|
||||||
|
Vector2.multiply(new Vector2(2 * t), Vector2.subtract(p2, p1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到一个三次贝塞尔函数的一阶导数
|
||||||
|
* @param start
|
||||||
|
* @param firstControlPoint
|
||||||
|
* @param secondControlPoint
|
||||||
|
* @param end
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2,
|
||||||
|
end: Vector2, t: number) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
let oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT), Vector2.subtract(firstControlPoint, start)),
|
||||||
|
Vector2.multiply(new Vector2(6 * oneMunusT * t), Vector2.subtract(secondControlPoint, firstControlPoint))),
|
||||||
|
Vector2.multiply(new Vector2(3 * t * t), Vector2.subtract(end, secondControlPoint)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算一个三次贝塞尔
|
||||||
|
* @param start
|
||||||
|
* @param firstControlPoint
|
||||||
|
* @param secondControlPoint
|
||||||
|
* @param end
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
public static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2,
|
||||||
|
end: Vector2, t: number) {
|
||||||
|
t = MathHelper.clamp01(t);
|
||||||
|
let oneMunusT = 1 - t;
|
||||||
|
return Vector2.add(Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMunusT * oneMunusT * oneMunusT), start),
|
||||||
|
Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)),
|
||||||
|
Vector2.multiply(new Vector2(3 * oneMunusT * t * t), secondControlPoint)),
|
||||||
|
Vector2.multiply(new Vector2(t * t * t), end));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归地细分bezier曲线,直到满足距离校正
|
||||||
|
* 在这种算法中,平面切片的点要比曲面切片少。返回完成后应返回到ListPool的合并列表。
|
||||||
|
* @param start
|
||||||
|
* @param firstCtrlPoint
|
||||||
|
* @param secondCtrlPoint
|
||||||
|
* @param end
|
||||||
|
* @param distanceTolerance
|
||||||
|
*/
|
||||||
|
public static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2,
|
||||||
|
end: Vector2, distanceTolerance: number = 1) {
|
||||||
|
let points = ListPool.obtain<Vector2>();
|
||||||
|
points.push(start);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance);
|
||||||
|
points.push(end);
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归地细分bezier曲线,直到满足距离校正。在这种算法中,平面切片的点要比曲面切片少。
|
||||||
|
* @param start
|
||||||
|
* @param firstCtrlPoint
|
||||||
|
* @param secondCtrlPoint
|
||||||
|
* @param end
|
||||||
|
* @param points
|
||||||
|
* @param distanceTolerance
|
||||||
|
*/
|
||||||
|
private static recursiveGetOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2,
|
||||||
|
end: Vector2, points: Vector2[], distanceTolerance: number) {
|
||||||
|
// 计算线段的所有中点
|
||||||
|
let pt12 = Vector2.divide(Vector2.add(start, firstCtrlPoint), new Vector2(2));
|
||||||
|
let pt23 = Vector2.divide(Vector2.add(firstCtrlPoint, secondCtrlPoint), new Vector2(2));
|
||||||
|
let pt34 = Vector2.divide(Vector2.add(secondCtrlPoint, end), new Vector2(2));
|
||||||
|
|
||||||
|
// 计算新半直线的中点
|
||||||
|
let pt123 = Vector2.divide(Vector2.add(pt12, pt23), new Vector2(2));
|
||||||
|
let pt234 = Vector2.divide(Vector2.add(pt23, pt34), new Vector2(2));
|
||||||
|
|
||||||
|
// 最后再细分最后两个中点。如果我们满足我们的距离公差,这将是我们使用的最后一点。
|
||||||
|
let pt1234 = Vector2.divide(Vector2.add(pt123, pt234), new Vector2(2));
|
||||||
|
|
||||||
|
// 试着用一条直线来近似整个三次曲线
|
||||||
|
let deltaLine = Vector2.subtract(end, start);
|
||||||
|
|
||||||
|
let d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
let d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x));
|
||||||
|
|
||||||
|
if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) {
|
||||||
|
points.push(pt1234);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续细分
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
|
||||||
|
this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,6 +58,20 @@ class MathHelper {
|
|||||||
return value % 2 == 0;
|
return value % 2 == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数值限定在0-1之间
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public static clamp01(value: number){
|
||||||
|
if (value < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (value > 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public static angleBetweenVectors(from: Vector2, to: Vector2){
|
public static angleBetweenVectors(from: Vector2, to: Vector2){
|
||||||
return Math.atan2(to.y - from.y, to.x - from.x);
|
return Math.atan2(to.y - from.y, to.x - from.x);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user