public bool Attack() { //攻撃処理 var action = new CharacterAttackAction(this, this.Direction); var des = this.Position + this.Direction; var target = dungeon.Characters.FirstOrDefault(x => x.Position == des && !x.IsDeath); if (target != null && !target.IsDeath && !CheckWallForAction(des)) { //命中判定 var isHit = (int)UnityEngine.Random.Range(0, 100) >= Mathf.Clamp(target.Params.Agi - this.Params.Dex + 20, 0, 95); if (isHit) { var damage = Mathf.Max(1, (int)((this.Atk + this.WeaponAtk - target.Def / 2) * UnityEngine.Random.Range(0.95f, 1.05f))); target.ReduceHP(damage); action.SubActions.Add(new CharacterDamagedAction(target, this, damage, true, target.IsDeath)); //相手死亡判定 if (target.IsDeath) { action.SubActions.AddRange(KillCharacter(target)); } } else { action.SubActions.Add(new CharacterDamagedAction(target, this, 0, false, false)); } } ReservedActions.Add(action);//攻撃情報を登録 return(true); }
/// <summary> /// 攻撃アニメーション /// </summary> private IObservable <Unit> AttackAnimation(CharacterAttackAction action) { var frame = 16; var attackAnimation = Observable.EveryUpdate() .Take(frame) .Do(i => { var dis = 0; if (i < 2) { dis = 3 * (int)i; } else if (i >= frame - 3) { dis = 3 * (int)(frame - 1 - i); } else { dis = 3 * 2; } var move = action.Direction * dis; this.Presenter.transform.localPosition = new Vector3( this.Position.x * DungeonConstants.MAPTIP_PIXCEL_SIZE + 2 + move.x, this.Position.y * -DungeonConstants.MAPTIP_PIXCEL_SIZE - move.y, 0); }) .Last() .AsUnitObservable(); var damageAnimation = Observable.TimerFrame(4) .SelectMany(_ => { return(action.SubActions .Where(x => x as CharacterDamagedAction != null) .Select(x => DamageAnimation(x as CharacterDamagedAction)) .Concat()); }); var otherAnimation = ActionAnimations(action.SubActions.Where(x => x as CharacterDamagedAction == null).ToArray()); return(Observable.WhenAll(attackAnimation, damageAnimation) .SelectMany(otherAnimation).Last()); }