1.根据权重获取不同的值:
算法思想:
代码实现:
_proto.randWeightEnemy = function (enemyIdMap, enemyIds, targetWeight, weightArray, monsterNumLimit) {
console.log("目标权重值"+targetWeight); //targetWeight的值为1700
var rd = utils.intRange(1, targetWeight + 1);
var index = 0;
for (var j = 0; j < weightArray.length; j++) { //weightArray=[1000,1500,1700]
if (rd < weightArray[j]) {
index = j;
break;
}
}
enemyId = enemyIds[index]; //根据不同权重的下标一一对应不同id
if (!enemyIdMap[enemyId]) {
enemyIdMap[enemyId] = 0;
}
//当前怪物id数量+1存为临时数量
var tmpCount = enemyIdMap[enemyId] + 1;
if (tmpCount > monsterNumLimit[index]) {
//超出限制
enemyId = this.randWeightEnemy(enemyIdMap, enemyIds, targetWeight, weightArray, monsterNumLimit); //嵌套执行
} else {
enemyIdMap[enemyId]++;
}
return enemyId; //不同id对应不同的权重值
};
2.自由落体:
(1)数据初始化定义:
//自由落体 0.5*a*t^2
//方向
//加速度 a
this.a = 1; //图片的像素移动 像素/ms
//初速度 v0 vt 当前速度 = v0 + at
this.v0 = 0;
(2)求自由落体 物体 y轴 坐标值的变化值:
/**
*求自由落体 Y轴 坐标值
* @param t0 帧时间差
*/
_proto.freeFall = function (fk, t1, t0) { //fk 是做自由落体的物体,t1 是上一帧动画所在的时间,t0是帧时间差
if(!fk)return;
//Math.pow(2,3) 8 js封装的求平方数的方法
fk.y += (this.v0 + this.a * t1 + 0.5 * this.a * t0) * t0;
}
(3)更新自由落体动画:
/**
* 更新下落动画
*/
_proto.updateFallAnim = function () {
if(!this.isPlayingFallAnim)return;
var fkIndex, row, vFk;
console.log("下落清单");
console.log(this.fall_list);
var deltaTime = Laya.timer.delta;//帧时间差ms
//单个方块移到目标点 完成单个动画播放 移除动画清单单个方块
var l = this.fall_list.length;
for (fkIndex = 0; fkIndex < l; fkIndex++) {
vFk = this.fall_list[fkIndex];
console.log("可以下落的方块");
console.log(vFk.fallMaxY);
row = this._getRow(vFk.fallMaxY);
this.markRow(vFk, row); //只是做了数据的标记和存储,没有做表现
this.freeFall(vFk, this.fallAnimTime, deltaTime);
if(vFk.y >= vFk.fallMaxY){ // vFk.fallMaxY 是做自由落体物品的目标Y值
this.fall_list.remove(vFk); //单个下落结束后,就把结束下落的方块从清单中移除
this.onSingleFallAimCompelete(vFk);
fkIndex--; //index 依赖于 l l必须更严谨,因为它被index依赖,所以l-- 放在 index--后边
l--; //重要性高,放后边处理,覆盖前边
}
}
this.fallAnimTime += deltaTime;//记录已播动画时长
}
3.角度和弧度的转换:
公式为:角度=180°×弧度÷π 弧度=角度×π÷180°
/** 弧度转角度换算单位 */
GameSetting$.ANGLE_1_RAD = 180 / Math.PI;
/** 角度转弧度换算单位 */
GameSetting$.RAD_1_ANGLE = Math.PI / 180;
4.两点之间距离的算法:
dx = Math.abs(p2.clientX - p1.clientX);
dy = Math.abs(p2.clientY - p1.clientY);
var dis = Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
5.根据两点间坐标,计算方向向量,转化为角度:
let dx = headPos.x - tailPos.x;
let dy = headPos.y - tailPos.y;
//2d方向向量
let angle = Math.atan2(dy,dx); //弧度
this.targetAngle$ = angle * GameSetting$.ANGLE_1_RAD-90;
6.已知起点坐标,角度,长度,求终点坐标:
/**
* 已知起点,角度,长度,求终点坐标
* @param {*} startPoint
* @param {*} angle 角度
* @param {*} distance
* @returns
*/
static calNewPointByAngle2$(startPoint, angle, distance) {
var endPoint = {};
// 角度转弧度
var radian = (angle * Math.PI) / 180;
// 计算新坐标(对于无限接近0的数字,此处没有优化)
endPoint.x = startPoint.x + distance * Math.sin(radian);
endPoint.y = startPoint.y + distance * Math.cos(radian);
return endPoint;
}
7.瞄准器脚本:鼠标移动画出2d的可控制角度的瞄准线
import GameSetting$ from "../../../Config/GameSetting";
import EventManager$ from "../../../Manager/EventManager";
import SSEVENT$ from "../../../Config/SSEVENT";
/**
* 触摸区域画轨迹线2d
* created by tcy 20210826
*/
export default class TouchDrawPoint2D$ extends Laya.Script {
constructor() {
super();
this._initData$();
}
_initData$() {
/**鼠标按下的点 */
this._touchDownPos$ = null;
/**鼠标区域box */
this._box$ = null;
/** 鼠标移动的方向 */
this._direction$ = new Laya.Vector2(0, 0);
/** 贴图路径 */
this.textureUrl$ = GameSetting$.LINE_TEXTURE_URL$;
/** 最大点数 */
this.maxPointCnt$ = GameSetting$.MAX_LINE_POINT_CNT$;
/**点的数量 */
this.pointCnt$ = 0;
/** 当前点的集合 */
this._curPoint$ = [];
/** Y轴方向点的间隔距离*/
this._pointDisY$ = 50;
/** 临时点变量 */
this._tempV2$ = new Laya.Point();
/** 临时点变量2 */
this._tempV2_2$ = new Laya.Point();
}
onAwake() {
this._box$ = this.owner;
}
onEnable() {
this.owner.on(Laya.Event.MOUSE_DOWN, this, this._onTouchDown$);
this.owner.on(Laya.Event.MOUSE_MOVE, this, this._onTouchMove$);
this.owner.on(Laya.Event.MOUSE_UP, this, this._onTouchUp$);
this.owner.on(Laya.Event.MOUSE_OUT, this, this._onTouchOut$);
}
onStart() {
this.loadResArray$();
}
/**
* 加载资源清单
*/
loadResArray$() {
Laya.loader.load(this.textureUrl$, Laya.Handler.create(this, this.onResLoaded$));
}
/**
* 当资源加载完成
*/
onResLoaded$() {
/** 贴图 */
this.texture$ = Laya.loader.getRes(this.textureUrl$);
}
_onTouchDown$(e) {
let t = this._box$.getMousePoint();
this._touchDownPos$ = new Laya.Point(t.x, t.y);
this.graphicsSp$ = this.owner.addChild(new Laya.Sprite());
this.graphicsSp$.x = this._touchDownPos$.x;
this.graphicsSp$.y = this._touchDownPos$.y;
this.drawSingleLine$(new Laya.Point(0, 0), 0);
}
_onTouchMove$(e) {
if (!this.graphicsSp$ || this.graphicsSp$.destroyed) return;
let t = this._box$.getMousePoint();
if (!this._touchDownPos$ || this._touchDownPos$.x === t.x && this._touchDownPos$.y === t.y) return false;
let i = new Laya.Point(t.x - this._touchDownPos$.x, t.y - this._touchDownPos$.y);
this._tempV2$.copy(i);
this._tempV2$.normalize();
this._direction$.setValue(this._tempV2$.x, this._tempV2$.y);
let dis = this._touchDownPos$.distance(t.x, t.y);
this._initRotation$ = Math.atan2(this._direction$.y, this._direction$.x);
//点数越多,点与点之间的间隔越大
if (!this.isFulll$() && dis > 50) {
let pointNum = Math.max(1, Math.floor(dis / 50));
for (var g = 1; g <= pointNum; g++) {
let point = new Laya.Point(0, this._pointDisY$ * g);
if (this._curPoint$.indexOf(point.y) != -1) continue;
this.drawSingleLine$(point, g);
}
}
this.graphicsSp$ && (this.graphicsSp$.rotation = this._initRotation$ * GameSetting$.ANGLE_1_RAD$);
this.resetPoint$(dis);
}
resetPoint$(dis) {
if (!this.graphicsSp$ || this.graphicsSp$.destroyed) return;
let pointNum = this.graphicsSp$._children.length;
let pointNode;
let index = Math.max(1, Math.floor(dis / 50));
let disY = this.pointCnt$ * 3 || 3;
for (var i = 0; i < pointNum; i++) {
pointNode = this.graphicsSp$._children[i];
let point = new Laya.Point(0, disY * i++);
let pointNew = this.getBPoint$(point, -this._initRotation$);
pointNode.x = pointNew.x;
pointNode.y = pointNew.y;
pointNode.index$ > index ? pointNode.visible = false : pointNode.visible = true;
}
}
_onTouchUp$(e) {
if (!this._touchDownPos$) return;
EventManager$.getInstance$().dispatchEvent$(SSEVENT$.PLAYER_JUMP$, [this._direction$, this.pointCnt$])
this.clearLines$();
}
_onTouchOut$() {
this.clearLines$();
}
getDirection$() {
return this._direction$;
}
/**
* 清除所有的线
*/
clearLines$() {
this.clearLineDatas$();
this.clearLinesGraphic$();
}
/**
* 清除线数据
*/
clearLineDatas$() {
this.pointCnt$ = 0;
this._curPoint$ = [];
}
/**
* 点数是否上限
*/
isFulll$() {
return this.maxPointCnt$ <= this.pointCnt$;
}
/**
*
* @param {*} source
* @param {*} angle Angle为正时逆时针转动, 单位为弧度
* @returns
*/
getBPoint$(source, angle) {
let R;
let rotation = Math.atan2(this._direction$.y, this._direction$.x);
rotation += angle//旋转
R = Math.sqrt(source.x * source.x + source.y * source.y)//半径
this._tempV2_2$.x = Math.cos(rotation) * R;
this._tempV2_2$.y = Math.sin(rotation) * R;
return this._tempV2_2$;
}
/**
* 画单条线
*/
drawSingleLine$(point, index) {
this.pointCnt$++;
this._curPoint$.push(point.y);
// let pointNew = this.getBPoint$(point, -this._initRotation$);
let newPoint = this.graphicsSp$.addChild(new Laya.Image(this.textureUrl$));
newPoint.index$ = index;
// newPoint.x = pointNew.x;
// newPoint.y = pointNew.y;
}
/**
* 清除线条图像
*/
clearLinesGraphic$() {
this.graphicsSp$ && this.graphicsSp$.destroy();
}
onDestroy() {
Laya.timer.clearAll(this);
this.owner.off(Laya.Event.MOUSE_DOWN, this, this._onTouchDown$);//按下
this.owner.off(Laya.Event.MOUSE_UP, this, this._onTouchUp$); //弹起
this.owner.off(Laya.Event.MOUSE_MOVE, this, this._onTouchMove$);//移动鼠标
this.owner.off(Laya.Event.MOUSE_OUT, this, this._onTouchOut$);
}
}