/**
* @description 一些和显示相关的函数放到这里
* @author (pdh)
* @date 2020-11-05
* @class ShowUtil
*/
class ShowUtil {
private static instance: ShowUtil = null;
private hurtColorFilter = null;
private shadowColorFilter = null;
private shadeColors: number[] = [];
private shadeMap: {} = {};
private constructor() {
}
public static getInstance() {
if (!this.instance) {
this.instance = new ShowUtil();
}
return this.instance;
}
/**
* @description 沿着中心翻转
* @author (pdh)
* @date 2020-11-05
* @param {egret.DisplayObject} entity
* @param {boolean} [flipX=false]
* @param {boolean} [flipY=false]
* @memberof ShowUtil
*/
public centerFlip(entity: egret.DisplayObject, flipX: boolean = false, flipY: boolean = false): void {
if (!entity) {
return;
}
if (entity.anchorOffsetX === 0 && flipX) {
let offsetX = entity.width / 2.0;
entity.anchorOffsetX = offsetX;
entity.x += offsetX;
}
if (flipX) {
entity.scaleX = entity.scaleX * (-1);
}
if (entity.anchorOffsetY === 0 && flipY) {
let offsetY = entity.height / 2.0;
entity.anchorOffsetY = offsetY;
entity.y += offsetY;
}
if (flipY) {
entity.scaleY = entity.scaleY * (-1);
}
}
/**
* @description 更改锚点。更改后图标显示不移位,仍然按照原来位置显示,只是锚点更改了。
* @author (pdh)
* @date 2020-11-06
* @param {egret.DisplayObject} entity
* @param {number} anchorX
* @param {number} anchorY
* @memberof ShowUtil
*/
public setAnchor(entity: egret.DisplayObject, anchorX: number, anchorY: number): void {
let oldAnchorX = entity.anchorOffsetX;
let oldAnchorY = entity.anchorOffsetY;
entity.anchorOffsetX = anchorX;
entity.anchorOffsetY = anchorY;
entity.x += (anchorX - oldAnchorX);
entity.y += (anchorY - oldAnchorY);
}
/**
* @description 角度转弧度
* @author (pdh)
* @date 2020-11-09
* @param {number} angle
* @returns {number}
* @memberof ShowUtil
*/
public angle2radian(angle: number): number {
return angle * Math.PI / 180;
}
/**
* @description 弧度转角度
* @author (pdh)
* @date 2020-11-09
* @param {number} radian
* @returns {number}
* @memberof ShowUtil
*/
public radian2angle(radian: number): number {
let angle = radian * 180 / Math.PI; //弧度转角度,方便调试
return angle;
}
/**
* @description 将坐标控制在0~360度之间
* @author (pdh)
* @date 2020-11-09
* @private
* @param {number} angle
* @returns {number}
* @memberof ShowUtil
*/
public getRealAngle(angle: number): number {
let shang = parseInt(String(angle / 360));
angle = angle - shang * 360;
if (angle > 360) {
angle -= 360;
} else if (angle < 0) {
angle += 360;
}
return angle;
}
/**
* @description 两条线段是否相交。如果有相交点放在{@resultPoint}中返回。
* 只有return为true时,{@resultPoint}才有意义。
* @author (pdh)
* @date 2020-11-08
* @param {egret.Point} line1Start 线段1的起点
* @param {egret.Point} line1End 线段1的终点
* @param {egret.Point} line2Start 线段2的起点
* @param {egret.Point} line2End 线段2的终点
* @param {egret.Point} resultPoint 相交点
* @returns {boolean} 是否相交
* @memberof ShowUtil
*/
public crashLine(line1Start: egret.Point,
line1End: egret.Point,
line2Start: egret.Point,
line2End: egret.Point,
resultPoint: egret.Point): boolean {
let pt = resultPoint;
// line1's cpmponent
let x1 = line1End.x - line1Start.x;//b1
let y1 = line1End.y - line1Start.y;//a1
// line2's cpmponent
let x2 = line2End.x - line2Start.x;//b2
let y2 = line2End.y - line2Start.y;//a2
// distance of 1,2
let x21 = line2Start.x - line1Start.x;
let y21 = line2Start.y - line1Start.y;
// determinant
let D = y1 * x2 - y2 * x1;// a1b2-a2b1
//
if (0 != D) {
// cross point
pt.x = (x1 * x2 * y21 + y1 * x2 * line1Start.x - y2 * x1 * line2Start.x) / D;
// on screen y is down increased !
pt.y = -(y1 * y2 * x21 + x1 * y2 * line1Start.y - x2 * y1 * line2Start.y) / D;
// segments intersect.
if ((Math.abs(pt.x - line1Start.x - x1 / 2) <= Math.abs(x1 / 2)) &&
(Math.abs(pt.y - line1Start.y - y1 / 2) <= Math.abs(y1 / 2)) &&
(Math.abs(pt.x - line2Start.x - x2 / 2) <= Math.abs(x2 / 2)) &&
(Math.abs(pt.y - line2Start.y - y2 / 2) <= Math.abs(y2 / 2))) {
return true;
}
}
return false;
}
/**
* @description 计算夹角,沿X轴正向为0,逆时针增大
* @author (pdh)
* @date 2020-11-06
* @param {number} fromX
* @param {number} fromY
* @param {number} toX
* @param {number} toY
* @returns
* @memberof ShowUtil
*/
public getAngle(fromX: number, fromY: number, toX: number, toY: number) {
let x = toX - fromX;
let y = toY - fromY;//egret中左上角为原点,要做一下转换
let radian = Math.atan2(y, x);
let angle = this.radian2angle(radian); //弧度转角度,方便调试
angle = this.getRealAngle(angle);
return angle;
}
/**
* @description 以baseX、baseY为原点,旋转rotateAngle的角度,获得beforeX、beforeY旋转后的新坐标
* @author (pdh)
* @date 2020-12-20
* @param {number} baseX
* @param {number} baseY
* @param {number} beforeX
* @param {number} beforeY
* @param {number} rotateAngle
* @param {egret.Point} resultPos
* @returns {egret.Point}
* @memberof ShowUtil
*/
public rotateByBasePoint(baseX: number, baseY: number,
beforeX: number, beforeY: number,
rotateAngle: number,
resultPos: egret.Point): egret.Point {
let baseP: egret.Point = ObjectPool.pop(ObjectType.Point);
baseP.setTo(baseX, baseY);
let beforeP: egret.Point = ObjectPool.pop(ObjectType.Point);
beforeP.setTo(beforeX, beforeY);
let distance = egret.Point.distance(beforeP, baseP);
let beforeAngle = this.getAngle(baseX, baseY, beforeX, beforeY);
let afterAngle = this.getRealAngle(beforeAngle + rotateAngle);
let radian = this.angle2radian(afterAngle);
resultPos.x = Math.cos(radian) * distance + baseX;
resultPos.y = Math.sin(radian) * distance + baseY;
ObjectPool.push(baseP);
ObjectPool.push(beforeP);
return resultPos;
}
/**
* @description 炮弹射程1500就够了
* @author (pdh)
* @date 2020-11-08
* @static
* @returns {number}
* @memberof ShowUtil
*/
public getMaxDistance(): number {
let w = GDatas.getStageWidth();
let h = GDatas.getStageHeight();
let distance = Math.sqrt(w * w + h * h);
return distance + 100;
}
/**
* @description 判断点是否落在矩形内。 注意注意:矩形顶角坐标传入次序不要搞错
* @author (pdh)
* @date 2020-12-20
* @param {egret.Point} checkPoint 要检测的点
* @param {egret.Point} rectLT 左上角
* @param {egret.Point} rectRT 右上角
* @param {egret.Point} rectRB 右下角
* @param {egret.Point} rectLB 左下角
* @returns {boolean}
* @memberof ShowUtil
*/
public isPointInRect(checkPoint: egret.Point, rectLT: egret.Point, rectRT: egret.Point, rectRB: egret.Point, rectLB: egret.Point): boolean {
let isIn = false;
let dot: egret.Point = ObjectPool.pop(ObjectType.Point);
dot.setTo(checkPoint.x, checkPoint.y);
let lt: egret.Point = ObjectPool.pop(ObjectType.Point);
lt.setTo(rectLT.x, rectLT.y);
let rt: egret.Point = ObjectPool.pop(ObjectType.Point);
rt.setTo(rectRT.x, rectRT.y);
let rb: egret.Point = ObjectPool.pop(ObjectType.Point);
rb.setTo(rectRB.x, rectRB.y);
let lb: egret.Point = ObjectPool.pop(ObjectType.Point);
lb.setTo(rectLB.x, rectLB.y);
let angle = this.getAngle(lt.x, lt.y, rt.x, rt.y);
//以左上角lt为原点,将要判断的各个点转换为正常坐标系
this.rotateByBasePoint(lt.x, lt.y, rt.x, rt.y, -angle, rt);
this.rotateByBasePoint(lt.x, lt.y, rb.x, rb.y, -angle, rb);
this.rotateByBasePoint(lt.x, lt.y, lb.x, lb.y, -angle, lb);
this.rotateByBasePoint(lt.x, lt.y, dot.x, dot.y, -angle, dot);
let x = lt.x < rb.x ? lt.x : rb.x;
let y = lt.y < rb.y ? lt.y : rb.y;
let width = Math.abs(rb.x - lt.x);
let height = Math.abs(rb.y - lt.y);
if ((dot.x >= x && dot.x < (x + width))
&& (dot.y >= y && dot.y < (y + height))) {
isIn = true;
}
ObjectPool.push(lt);
ObjectPool.push(rt);
ObjectPool.push(rb);
ObjectPool.push(lb);
ObjectPool.push(dot);
return isIn;
}
碰撞、子弹路径、参考
最新推荐文章于 2024-04-08 13:32:44 发布
这篇博客主要介绍了如何计算子弹的运动轨迹,并结合参考播放动画来理解这一过程。内容包括动态模拟和视觉呈现方面的细节。
摘要由CSDN通过智能技术生成