TypeScript 的运算符
算术运算符
// 基础运算 let damage: number = 50 + 25; // 加法: 75 let totalGold: number = 1000 - 100; // 减法: 900 let critDamage: number = damage * 2; // 乘法: 100 let splitGold: number = 1000 / 4; // 除法: 250 let remainder: number = 100 % 30; // 取余: 10 // 在游戏中的实际应用 let heroHealth: number = 1000; heroHealth = heroHealth - damage; // 扣血 let expNeeded: number = level * 100; // 计算升级所需经验 let bonusDamage: number = baseDamage * 1.5; // 计算暴击伤害
赋值运算符
// 基础赋值 let gold: number = 100; // 基本赋值 gold += 50; // 等同于 gold = gold + 50 gold -= 30; // 等同于 gold = gold - 30 gold *= 2; // 等同于 gold = gold * 2 gold /= 4; // 等同于 gold = gold / 4 // 在游戏中的应用 let mana: number = 100; mana -= 40; // 使用技能消耗魔法值 exp += killExp; // 获得经验值 attackSpeed *= 1.3; // 提升攻击速度
比较运算符
// 基础比较 let isMaxLevel: boolean = (level >= 25); // 大于等于 let canBuyItem: boolean = (gold >= 500); // 大于等于 let isDead: boolean = (health <= 0); // 小于等于 let isHero: boolean = (unitType === 'hero'); // 严格相等 let isNotFull: boolean = (hp !== maxHp); // 不相等 // 在游戏中的应用 if (heroLevel >= 6) { // 英雄达到6级可以学习大招 EnableUltimateSkill(); } if (currentGold < itemCost) { // 金币不足无法购买物品 DisplayError("金币不足"); }
逻辑运算符
// 与运算 && let canCastUltimate: boolean = (mana >= 100 && skillCooldown <= 0); // 或运算 || let shouldRetreat: boolean = (health <= 100 || isStunned); // 非运算 ! let isNotStunned: boolean = !isStunned; // 在游戏中的实际应用 if (health > 0 && mana >= skillCost && !isStunned) { // 单位存活、有足够魔法值且未被眩晕时可以施放技能 CastSpell(); } if (health <= 0 || isRemoved) { // 单位死亡或被移除时执行 RemoveUnit(); }
三元运算符
// 基础用法 let message: string = (gold >= itemCost) ? "可以购买" : "金币不足"; // 在游戏中的应用 let damageText: string = isDead ? "致命一击" : damage.toString(); let healAmount: number = isHero ? 100 : 50; // 英雄回复更多生命值
位运算符
// 在游戏中通常用于标志位 const BUFF_STUN: number = 1 << 0; // 眩晕: 1 const BUFF_SILENCE: number = 1 << 1; // 沉默: 2 const BUFF_DISARM: number = 1 << 2; // 缴械: 4 // 检查状态 let unitState: number = GetUnitState(unit); let isStunned: boolean = (unitState & BUFF_STUN) !== 0;
字符串运算符
// 字符串连接 let playerName: string = "玩家1"; let levelText: string = "等级"; let displayText: string = playerName + " " + levelText + " " + level; // 在游戏中的应用 let tooltipText: string = itemName + "\n" + // \n 表示换行 "价格: " + cost + " 金币\n" + "说明: " + description;
可选链运算符 (?.)
// 安全地访问可能为空的对象 let damage: number = hero?.weapon?.damage ?? 0; // 在游戏中的应用 let itemCount: number = inventory?.items?.length ?? 0;
空值合并运算符 (??)
// 提供默认值 let startingGold: number = configValue ?? 100; // 在游戏中的应用 let respawnTime: number = hero.respawnConfig ?? defaultRespawnTime;
实际应用示例:
class HeroSystem {
calculateDamage(attacker: unit, target: unit): number {
// 基础伤害计算
let baseDamage: number = GetUnitDamage(attacker);
let armor: number = GetUnitArmor(target);
// 暴击判定
let isCritical: boolean = (Math.random() < 0.2); // 20%暴击率
let finalDamage: number = isCritical ? baseDamage * 2 : baseDamage;
// 护甲减免
finalDamage *= (1 - (armor * 0.06) / (1 + armor * 0.06));
// 状态检查
if (IsUnitStunned(target) || IsUnitDisarmed(target)) {
finalDamage *= 1.5; // 目标被控制时伤害提升
}
return Math.max(finalDamage, 1); // 确保最少造成1点伤害
}
}
这些运算符在魔兽地图开发中经常用于:
- 伤害计算
- 状态判断
- 资源检查
- 等级和经验值计算
- 技能效果判定
- 物品系统逻辑
TypeScript 的条件语句
if 语句
// 基础 if 语句 if (heroLevel >= 6) { // 英雄达到6级可以学习大招 EnableUltimateSkill(); } // if-else 语句 if (playerGold >= itemCost) { BuyItem(); DisplayText("购买成功!"); } else { DisplayText("金币不足!"); } // if-else if-else 语句 if (unitHealth <= 0) { KillUnit(); DisplayText("单位已阵亡"); } else if (unitHealth < 100) { DisplayText("单位生命值危急"); } else { DisplayText("单位状态正常"); }
嵌套的 if 语句
// 技能释放判断 if (isAlive) { if (mana >= skillCost) { if (!isStunned) { if (!isSilenced) { CastSpell(); } else { DisplayText("单位被沉默"); } } else { DisplayText("单位被眩晕"); } } else { DisplayText("魔法值不足"); } }
使用逻辑运算符简化条件
// 使用 && 简化多重条件 if (isAlive && mana >= skillCost && !isStunned && !isSilenced) { CastSpell(); } else { DisplayText("无法释放技能"); } // 使用 || 简化多重条件 if (health <= 0 || isRemoved || isDestroyed) { RemoveUnit(); }
switch 语句
// 根据物品类型执行不同效果 switch (itemType) { case "Potion": RestoreHealth(100); break; case "Scroll": RestoreMana(50); break; case "Weapon": IncreaseAttack(30); break; default: DisplayText("未知物品类型"); break; } // 处理不同的单位类型 switch (GetUnitType(unit)) { case HERO_TYPE: // 英雄单位特殊处理 ApplyHeroBuffs(); break; case CREEP_TYPE: // 野怪单位处理 ApplyCreepAI(); break; case BUILDING_TYPE: // 建筑单位处理 UpdateBuildingState(); break; }
条件(三元)运算符
// 简单条件判断 let healAmount: number = isHero ? 200 : 100; // 状态文本显示 let statusText: string = isAlive ? "存活" : "死亡"; // 伤害计算 let finalDamage: number = isCritical ? baseDamage * 2 : baseDamage;
实际应用示例
class ItemSystem { useItem(unit: unit, item: item) { // 检查使用条件 if (!this.canUseItem(unit, item)) { return; } // 获取物品类型 let itemType = GetItemType(item); // 处理不同类型的物品效果 switch (itemType) { case ITEM_TYPE_INSTANT: if (IsHealingItem(item)) { // 治疗物品 let healAmount = IsHero(unit) ? 500 : 200; HealUnit(unit, healAmount); } else if (IsManaItem(item)) { // 魔法物品 RestoreMana(unit, 200); } break; case ITEM_TYPE_EQUIPMENT: if (this.hasEmptySlot(unit)) { EquipItem(unit, item); } else { DisplayText("装备栏已满"); } break; case ITEM_TYPE_CONSUMABLE: if (GetItemCharges(item) > 0) { UseConsumable(unit, item); RemoveCharge(item); } break; } } private canUseItem(unit: unit, item: item): boolean { // 多重条件检查 if (!IsUnitAlive(unit)) { DisplayText("单位已死亡"); return false; } if (IsUnitStunned(unit)) { DisplayText("单位被眩晕"); return false; } let itemLevel = GetItemLevel(item); let unitLevel = GetUnitLevel(unit); if (itemLevel > unitLevel) { DisplayText("等级不足"); return false; } return true; } }
最佳实践
// 1. 使用提前返回减少嵌套 function processUnit(unit: unit) { if (!unit) return; if (!IsUnitAlive(unit)) return; if (IsUnitStunned(unit)) return; // 处理正常单位逻辑... } // 2. 使用条件对象替代复杂的if-else const damageMultiplier = { 'hero': 1.5, 'creep': 1.0, 'building': 0.5 }; let finalDamage = baseDamage * (damageMultiplier[unitType] || 1.0); // 3. 使用布尔值简化条件 let canCastSpell = isAlive && hasMana && !isStunned && !isSilenced; if (canCastSpell) { CastSpell(); }
条件语句的关键点:
- 选择合适的条件语句类型
- 避免过度嵌套
- 使用逻辑运算符简化条件
- 注意条件的顺序和优先级
- 考虑代码的可读性和维护性
TypeScript 的循环语句
for 循环
// 基础for循环 // 创建多个单位 for (let i = 0; i < 5; i++) { let x = -500 + i * 100; // 计算位置 CreateUnit(player, FOOTMAN_ID, x, 0, 0); } // 遍历物品栏 for (let slot = 0; slot < 6; slot++) { let item = UnitItemInSlot(hero, slot); if (item) { // 处理每个物品 CheckItemDuration(item); } }
for...of 循环
// 遍历数组 let heroes: unit[] = GetPlayerHeroes(); for (let hero of heroes) { // 给所有英雄加buff AddHeroBuff(hero); } // 遍历物品列表 let items: item[] = GetGroundItems(); for (let item of items) { // 检查地上的物品 if (IsItemExpired(item)) { RemoveItem(item); } }
for...in 循环
// 遍历对象属性 let heroStats = { strength: 20, agility: 15, intelligence: 18 }; for (let stat in heroStats) { // 打印英雄属性 DisplayText(`${stat}: ${heroStats[stat]}`); }
while 循环
// 基础while循环 let remainingTime = 30; while (remainingTime > 0) { // 倒计时逻辑 DisplayTimer(remainingTime); remainingTime--; Wait(1.0); } // 条件判断的while循环 while (IsUnitAlive(boss)) { // boss战循环 UpdateBossAI(); Wait(0.5); }
do...while 循环
// 至少执行一次的循环 let attempts = 3; do { let success = TrySpawnUnit(); if (success) break; attempts--; } while (attempts > 0);
实际应用示例
class WaveSystem { private spawnPoints: point[] = []; private currentWave: number = 0; private maxWaves: number = 10; spawnWave() { // 增加当前波数 this.currentWave++; // 使用for循环在每个刷怪点生成怪物 for (let point of this.spawnPoints) { let count = this.getWaveUnitCount(); // 在每个点生成多个单位 for (let i = 0; i < count; i++) { let unitType = this.getRandomUnitType(); CreateUnit(computer, unitType, GetPointX(point), GetPointY(point), GetRandomReal(0, 360)); } } } checkWaveComplete(): boolean { let remainingUnits = 0; // 使用while循环检查所有单位 let unit = FirstOfGroup(this.waveUnits); while (unit) { if (IsUnitAliveBJ(unit)) { remainingUnits++; } unit = NextOfGroup(this.waveUnits); } return remainingUnits === 0; } async startWaveTimer() { // 使用do-while循环进行波次控制 do { // 显示波次信息 DisplayText(`第 ${this.currentWave + 1} 波即将开始!`); // 倒计时 let countdown = 10; while (countdown > 0) { DisplayText(`${countdown}...`); await Wait(1.0); countdown--; } // 生成这一波 this.spawnWave(); // 等待这一波结束 while (!this.checkWaveComplete()) { await Wait(1.0); } } while (this.currentWave < this.maxWaves); } }
循环控制语句
// break 语句 for (let i = 0; i < items.length; i++) { if (items[i].type === "legendary") { DisplayText("发现传说物品!"); break; // 找到后立即退出循环 } } // continue 语句 for (let unit of allUnits) { if (!IsUnitAlive(unit)) { continue; // 跳过死亡单位 } // 处理活着的单位 ProcessUnit(unit); }
嵌套循环
class MapSystem { createGrid(width: number, height: number) { // 创建地形网格 for (let x = 0; x < width; x++) { for (let y = 0; y < height; y++) { // 在每个格子执行操作 this.processGridCell(x, y); } } } findPath(start: point, end: point) { // 寻路算法中的嵌套循环 let openList: point[] = [start]; while (openList.length > 0) { let current = openList[0]; // 检查周围8个方向 for (let dx = -1; dx <= 1; dx++) { for (let dy = -1; dy <= 1; dy++) { if (dx === 0 && dy === 0) continue; // 处理每个相邻点 this.checkNeighbor(current, dx, dy); } } } } }
循环使用的关键点:
- 选择合适的循环类型
- 注意循环条件和终止条件
- 避免无限循环
- 合理使用循环控制语句
- 考虑性能影响,特别是在嵌套循环中