| @@ -89,13 +89,14 @@ $$ | |||
| 8. 翻窗 Climbing | |||
| ### 攻击 | |||
| - 攻击距离是指攻击(子弹)的移动距离,也就是说理论上最远被攻击的学生的中心与捣蛋鬼的中心=学生的半径+捣蛋鬼的半径+攻击距离+子弹半径(200)*2 | |||
| - 攻击类型CommonAttackOfTricker攻击未写完的作业,会造成对应攻击力的损坏 | |||
| - 捣蛋鬼攻击交互状态或前后摇的学生,将使学生眩晕4.3s | |||
| | 攻击(子弹)类型 |搞蛋鬼的一般攻击CommonAttackOfTricker| 飞刀FlyingKnife | 蹦蹦炸弹BombBomb | 小炸弹JumpyDumpty | | |||
| | :------------ | :--------------------- | :--------------------- | :--------------------- | :--------------------- | | |||
| | 子弹爆炸范围 | 0 | 0 | 2000 | 1000 | | |||
| | 子弹攻击距离 | 2200 | 78000 | 2200 | 4400 | | |||
| | 爆炸范围 | 0 | 0 | 2000 | 1000 | | |||
| | 攻击距离 | 2200 | 78000 | 2200 | 4400 | | |||
| | 攻击力 | 1500000 | 1200000 | 1800000 | 900000 | | |||
| | 移动速度/s | 7400 | 18500 | 6000 | 8600 | | |||
| | 前摇(ms) | 297 | 400 | 366 | - | | |||
| @@ -17,9 +17,11 @@ | |||
| - feat:增加了可选地图功能 | |||
| - **脚本RunServer(ForDebug).cmd/sh现在支持可选地图功能,但想选择地图,选手需要自行参照使用文档修改命令行或在云盘下载脚本** | |||
| # 5月9日更新 | |||
| # 5月9日19:30更新 | |||
| - docs:更新了 游戏机制与平衡性调整更新草案.pdf | |||
| - change:更改了地图的文件路径 | |||
| # 最新更新 | |||
| - | |||
| - fix:修复JumpyDumpty的初始位置错误的问题 | |||
| - fix:修正和重新说明攻击距离 | |||
| - **攻击距离是指攻击(子弹)的移动距离,也就是说理论上最远被攻击的学生的中心与捣蛋鬼的中心=学生的半径+捣蛋鬼的半径+攻击距离+子弹半径(200)×2** | |||
| @@ -10,7 +10,7 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange; | |||
| public override double AttackDistance => GameData.basicAttackShortRange; | |||
| public int ap = GameData.basicApOfGhost; | |||
| public override int AP | |||
| { | |||
| @@ -24,7 +24,7 @@ namespace GameClass.GameObj | |||
| public override int Speed => GameData.basicBulletMoveSpeed; | |||
| public override bool IsRemoteAttack => false; | |||
| public override int CastTime => (int)BulletAttackRange * 1000 / Speed; | |||
| public override int CastTime => (int)AttackDistance * 1000 / Speed; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public const int cd = GameData.basicBackswing; | |||
| @@ -57,7 +57,7 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => GameData.basicRemoteAttackRange * 13; | |||
| public override double AttackDistance => GameData.basicRemoteAttackRange * 13; | |||
| public int ap = GameData.basicApOfGhost * 4 / 5; | |||
| public override int AP | |||
| { | |||
| @@ -104,7 +104,7 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => GameData.basicBulletBombRange; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange; | |||
| public override double AttackDistance => GameData.basicAttackShortRange; | |||
| public int ap = (int)(GameData.basicApOfGhost * 6.0 / 5); | |||
| public override int AP | |||
| { | |||
| @@ -118,7 +118,7 @@ namespace GameClass.GameObj | |||
| public override int Speed => (int)(GameData.basicBulletMoveSpeed * 30 / 37); | |||
| public override bool IsRemoteAttack => false; | |||
| public override int CastTime => (int)(BulletAttackRange * 1000 / Speed); | |||
| public override int CastTime => (int)(AttackDistance * 1000 / Speed); | |||
| public override int Backswing => GameData.basicRecoveryFromHit; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public const int cd = GameData.basicCD; | |||
| @@ -149,7 +149,7 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => GameData.basicBulletBombRange / 2; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange * 2; | |||
| public override double AttackDistance => GameData.basicAttackShortRange * 2; | |||
| public int ap = (int)(GameData.basicApOfGhost * 0.6); | |||
| public override int AP | |||
| { | |||
| @@ -9,7 +9,7 @@ namespace GameClass.GameObj | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => 0; | |||
| public override double AttackDistance => 0; | |||
| public override int AP => 7220; | |||
| public override int Speed => 0; | |||
| public override bool IsRemoteAttack => false; | |||
| @@ -10,7 +10,7 @@ namespace GameClass.GameObj | |||
| /// //攻击力 | |||
| /// </summary> | |||
| public abstract double BulletBombRange { get; } | |||
| public abstract double BulletAttackRange { get; } | |||
| public abstract double AttackDistance { get; } | |||
| public abstract int AP { get; set; } | |||
| public abstract int Speed { get; } | |||
| public abstract bool IsRemoteAttack { get; } | |||
| @@ -91,7 +91,7 @@ namespace GameClass.GameObj | |||
| { | |||
| if (bulletNum == maxBulletNum) updateTimeOfBulletNum = time; | |||
| --bulletNum; | |||
| XY res = Position + new XY // 子弹紧贴人物生成。 | |||
| ( | |||
| (int)(Math.Abs((Radius + BulletFactory.BulletRadius(bulletOfPlayer)) * Math.Cos(angle))) * Math.Sign(Math.Cos(angle)), | |||
| @@ -99,7 +99,7 @@ namespace GameClass.GameObj | |||
| ); | |||
| Bullet? bullet = BulletFactory.GetBullet(this, res); | |||
| if (bullet == null) return null; | |||
| facingDirection = new(angle, bullet.BulletAttackRange); | |||
| facingDirection = new(angle, bullet.AttackDistance); | |||
| return bullet; | |||
| } | |||
| else | |||
| @@ -330,7 +330,7 @@ namespace GameClass.GameObj | |||
| { | |||
| lock (actionLock) | |||
| { | |||
| stateNum= Interlocked.Increment(ref stateNum); | |||
| ++stateNum; | |||
| whatInteractingWith = gameObj; | |||
| if (value != PlayerStateType.Moving) | |||
| IsMoving = false; | |||
| @@ -355,7 +355,7 @@ namespace GameClass.GameObj | |||
| { | |||
| lock (actionLock) | |||
| { | |||
| stateNum= Interlocked.Increment(ref stateNum); | |||
| ++stateNum; | |||
| whatInteractingWith = null; | |||
| IsMoving = false; | |||
| playerState = PlayerStateType.Null; | |||
| @@ -11,9 +11,13 @@ namespace GameClass.GameObj | |||
| private readonly ReaderWriterLockSlim moveReaderWriterLock = new(); | |||
| public ReaderWriterLockSlim MoveReaderWriterLock => moveReaderWriterLock; | |||
| protected long stateNum = 0; | |||
| public long StateNum | |||
| public long StateNum | |||
| { | |||
| get=>Interlocked.Read(ref stateNum); | |||
| get | |||
| { | |||
| lock (actionLock) | |||
| return stateNum; | |||
| } | |||
| } | |||
| //规定moveReaderWriterLock>actionLock | |||
| @@ -39,15 +39,15 @@ namespace Gaming | |||
| this.characterManager = characterManager; | |||
| } | |||
| public void ProduceBulletNaturally(BulletType bulletType, Character player, double angle,XY pos) | |||
| public void ProduceBulletNaturally(BulletType bulletType, Character player, double angle, XY pos) | |||
| { | |||
| // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | |||
| if (bulletType == BulletType.Null)return; | |||
| if (bulletType == BulletType.Null) return; | |||
| Bullet? bullet = BulletFactory.GetBullet(player, pos); | |||
| if (bullet == null) return; | |||
| Debugger.Output(bullet, "Attack in " + pos.ToString()); | |||
| gameMap.Add(bullet); | |||
| moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(bulletType)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| } | |||
| private void BombObj(Bullet bullet, GameObj objBeingShot) | |||
| @@ -141,7 +141,7 @@ namespace Gaming | |||
| ); | |||
| ProduceBulletNaturally(BulletType.JumpyDumpty, (Character)bullet.Parent, angle, pos); | |||
| angle = bullet.FacingDirection.Angle() + Math.PI * 3.0 / 2.0; | |||
| angle = bullet.FacingDirection.Angle() + Math.PI * 3.0 / 2.0; | |||
| pos = bullet.Position + new XY // 子弹紧贴人物生成。 | |||
| ( | |||
| (int)(Math.Abs((bullet.Radius + BulletFactory.BulletRadius(BulletType.JumpyDumpty)) * Math.Cos(angle))) * Math.Sign(Math.Cos(angle)), | |||
| @@ -196,7 +196,7 @@ namespace Gaming | |||
| Debugger.Output(bullet, "Attack in " + bullet.Position.ToString()); | |||
| bullet.AP += player.TryAddAp() ? GameData.ApPropAdd : 0; | |||
| gameMap.Add(bullet); | |||
| moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(bullet.TypeOfBullet)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| if (bullet.CastTime > 0) | |||
| { | |||
| characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | |||