source: 2015/26/MikkoL/JRPG/JRPG/JRPG/Battle/BattleView.cs @ 6281

Revision 6281, 15.9 KB checked in by mijoliim, 5 years ago (diff)

Wooo versionhallinta

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Jypeli;
6using Jypeli.Widgets;
7
8using Microsoft.Xna.Framework;
9using Microsoft.Xna.Framework.Graphics;
10
11public class BattleView : GameObject
12{
13    public static BattleView CurrentBattleView { get; set; }
14
15    public _Background Background;
16    public Image Background_Image;
17
18    public EnemyGroup _EnemyGroup { get; set; }
19
20    public List<CharacterBase> Allies = new List<CharacterBase>();
21    public List<BetterLabel> AllyNames = new List<BetterLabel>();
22    public List<EnemyBase> Enemies = new List<EnemyBase>();
23    public List<GameObject> EnemiesOnScreen = new List<GameObject>();
24
25    public bool IsAttackAnimationPlaying { get; set; }
26    public bool IsTimerActive { get; set; }
27    public bool IsInMenu { get; set; }
28
29    private SpecialQueue<CharacterBase> _AllyQueue = new SpecialQueue<CharacterBase>();
30    public SpecialQueue<Action<CharacterBase>> AllyQueue = new SpecialQueue<Action<CharacterBase>>();
31    public Queue<Action> ActionQueue = new Queue<Action>();
32
33    private Widget BattleHUD { get; set; }
34    private List<GameObject> ToDeleteOnExit = new List<GameObject>();
35    private ScrollingTextMenu BattleMenu { get; set; }
36
37    int SelectedEnemy;
38    int PrevSelectedEnemy = 0;
39
40    public BattleView()
41        : base(0, 0)
42    { }
43
44    public void LoadBattle(EnemyGroup _Enemies, Image BG_Image)
45    {
46        Background_Image = BG_Image;
47        LoadBattle(_Enemies);
48    }
49
50    public void LoadBattle(EnemyGroup _Enemies)
51    {
52        JRPG.Game.ClearControls();
53
54        CurrentBattleView = this;
55
56        _EnemyGroup = _Enemies;
57
58        Background = new _Background(JRPG.Game.Content.Load<Texture2D>("BG//bg_test"));
59        JRPG.Game.Add(Background, 1);
60
61        JRPG.Game.Keyboard.Listen(Key.Enter, ButtonState.Pressed, EndBattle, null);
62
63        Allies.Add(CharacterList.TestChar());
64        Allies.Add(CharacterList.TestChar());
65        Allies.Add(CharacterList.TestChar());
66
67        LoadEnemies(_Enemies);
68        LoadHUD();
69
70        Flags.InBattle = true;
71        IsTimerActive = true;
72    }
73
74    void LoadEnemies(EnemyGroup _Enemies)
75    {
76        for (int i = 0; i < _Enemies.Count; i++)
77        {
78           
79            _Enemies[i].EnemyOnScreen = new GameObject(_Enemies[i].Idle.Width, _Enemies[i].Idle.Height);
80            _Enemies[i].EnemyOnScreen.Image = _Enemies[i].Idle;
81
82            if (_Enemies.Count == 1)
83            {
84               
85                _Enemies[i].EnemyOnScreen.Position = JRPG.Game.Camera.Position + new Vector(-240, 0);
86               
87            }
88            else if (_Enemies.Count == 2)
89            {
90                _Enemies[i].EnemyOnScreen.Position = JRPG.Game.Camera.Position + new Vector(-160 - (i*100), 120 + (i*-160));
91            }
92            else if (_Enemies.Count == 3)
93            {
94                _Enemies[i].EnemyOnScreen.Position = JRPG.Game.Camera.Position + new Vector(-260+i*100, 160+i*-120);
95                if (i == 2)
96                {
97                    _Enemies[i].EnemyOnScreen.X = (_Enemies[0].EnemyOnScreen.Position.X + _Enemies[1].EnemyOnScreen.X) / 2;
98                }
99            }
100            else if (_Enemies.Count == 4)
101            {
102                _Enemies[i].EnemyOnScreen.Y = JRPG.Game.Camera.Position.Y - (100 * i - 200);
103                if (i % 2 == 0)
104                {
105                    _Enemies[i].EnemyOnScreen.X = JRPG.Game.Camera.Position.X - 160;
106                }
107                else if (i % 2 == 1)
108                {
109                    _Enemies[i].EnemyOnScreen.X = JRPG.Game.Camera.Position.X - 260;
110                }
111            }
112
113            Enemies.Add(_Enemies[i]);
114
115            JRPG.Game.Add(_Enemies[i].EnemyOnScreen, 2);
116            EnemiesOnScreen.Add(_Enemies[i].EnemyOnScreen);
117        }
118    }
119
120    void LoadHUD()
121    {
122        Vector Position = new Vector(-60, -235);
123        double Offset = 40;
124
125        BattleHUD = new Widget(Images.HUD.BattleHUD.Width, Images.HUD.BattleHUD.Height);
126        BattleHUD.Image = Images.HUD.BattleHUD;
127        BattleHUD.Position = Position + new Vector(64.5, -34.5);
128        JRPG.Game.Add(BattleHUD);
129
130        for (int i = 0; i < Allies.Count; i++)
131        {
132            int Index = i;
133
134            BetterLabel Name = new BetterLabel(JRPG.Game.MainFont, Position + new Vector(-200, i * -Offset), Allies[i].Name);
135            JRPG.Game.Add(Name);
136            AllyNames.Add(Name);
137
138            string HP = Allies[i].CurrentHP.Value.ToString() + "/" + Allies[i].CurrentHP.MaxValue.ToString();
139            BetterLabel HPMeter = new BetterLabel(JRPG.Game.MainFont, Position + new Vector(0, i * -Offset), HP);
140            HPMeter.BorderType = TextBorderType.Thick;
141            JRPG.Game.Add(HPMeter);
142
143            string SP = Allies[i].CurrentSP.Value.ToString();
144            BetterLabel SPMeter = new BetterLabel(JRPG.Game.MainFont, Position + new Vector(150, i * -Offset), SP);
145            SPMeter.BorderType = TextBorderType.Thick;
146            JRPG.Game.Add(SPMeter);
147
148            ProgressBar WaitBar = new ProgressBar(104, 12);
149            WaitBar.Position = Position + new Vector(280, i * -Offset);
150            WaitBar.BindTo(Allies[i].WaitTimeMeter);
151            WaitBar.BarImage = Images.HUD.Wait_Full;
152            WaitBar.Image = Images.HUD.Wait_Empty;
153            JRPG.Game.Add(WaitBar);
154
155            ToDeleteOnExit.Add(HPMeter);
156            ToDeleteOnExit.Add(SPMeter);
157            ToDeleteOnExit.Add(WaitBar);
158
159            Allies[Index].OnCurrentHPChange = delegate
160            {
161                HPMeter.Text = Allies[Index].CurrentHP.Value.ToString() + "/" + Allies[Index].CurrentHP.MaxValue.ToString();
162            };
163
164            Allies[Index].OnCurrentSPChange = delegate
165            {
166                SPMeter.Text = Allies[Index].CurrentSP.Value.ToString();
167            };
168        }
169    }
170
171    public void SelectSingleEnemyForAttackTarget(AttackBase ATK)
172    {
173        JRPG.Game.ClearControls();
174
175        SelectedEnemy = PrevSelectedEnemy;
176
177        BetterLabel EnemyName = new BetterLabel(JRPG.Game.MainFont, Vector.Zero, Enemies[SelectedEnemy].Name);
178        EnemyName.IsFlashing = true;
179        Pointer Pointer = new Pointer(Vector.Zero);
180        Pointer.IsFlashing = true;
181
182        JRPG.Game.Add(Pointer);
183        JRPG.Game.Add(EnemyName);
184
185        bool Selected = false;
186        bool Cancelled = false;
187
188        JRPG.Game.Keyboard.Listen(Key.Z, ButtonState.Pressed,
189            delegate
190            {
191                Selected = true;
192
193                if (!Cancelled)
194                {
195                    JRPG.Game.ClearControls();
196                    PrevSelectedEnemy = SelectedEnemy;
197
198                    double BaseDamage = ATK.BaseDamage(_AllyQueue.Peek().CurrentStats.Str, _AllyQueue.Peek().Level);
199                    int TrueDamage = 0;
200                    bool Crit = false;
201
202                    int r = RandomGen.NextInt(0, 100);
203
204                    if (r < BattleAlgorithms.CriticalRate(_AllyQueue.Peek().CurrentStats.Luck))
205                    {
206                        TrueDamage = BattleAlgorithms.DamageFromCriticalHit(BaseDamage, Enemies[SelectedEnemy].Stats.Def);
207                        Crit = true;
208                    }
209                    else TrueDamage = BattleAlgorithms.DamageFromBasicAttack(BaseDamage, Enemies[SelectedEnemy].Stats.Def);
210
211 
212                    IsInMenu = false;
213
214                    if (SoundEffects.Menu.Move.IsPlaying)
215                    {
216                        SoundEffects.Menu.Move.Stop();
217                    }
218                    SoundEffects.Menu.Move.Play();
219
220
221                    EnemyName.Destroy();
222                    Pointer.Destroy();
223
224                    AllyNames[_AllyQueue.Peek().Index].IsFlashing = false;
225                    AllyNames[_AllyQueue.Peek().Index].TextColor = Microsoft.Xna.Framework.Color.White;
226
227                   
228                    ActionQueue.Enqueue(delegate
229                    {
230                        IsAttackAnimationPlaying = false;
231                        IsTimerActive = true;
232
233                        DamageHitsplat(EnemiesOnScreen[SelectedEnemy].Position - JRPG.Game.Camera.Position, TrueDamage, Crit);
234                        Enemies[SelectedEnemy].Stats.HP -= TrueDamage;
235
236                        if (Enemies[SelectedEnemy].Stats.HP <= 0)
237                        {
238                            Enemies[SelectedEnemy].EnemyOnScreen.Destroy();
239                            Enemies.RemoveAt(SelectedEnemy);
240                            EnemiesOnScreen.RemoveAt(SelectedEnemy);
241                            PrevSelectedEnemy = 0;
242
243                            if (Enemies.Count == 0)
244                            {
245                                EndBattle();
246                            }
247                        }
248
249                        _AllyQueue.Peek().WaitTimeMeter.Value = 0;
250                        _AllyQueue.Dequeue().CanMakeAction = false;
251                         
252                    });
253                }
254            }
255        ,null);
256        JRPG.Game.Keyboard.Listen(Key.X, ButtonState.Pressed,
257            delegate
258            {
259                Cancelled = true;
260
261                if (!Selected)
262                {
263
264                    JRPG.Game.ClearControls();
265
266                    Pointer.Destroy();
267                    EnemyName.Destroy();
268
269                    LoadBattleMenu(_AllyQueue.Peek()).Invoke(_AllyQueue.Dequeue());
270
271                    if (SoundEffects.Menu.Cancel.IsPlaying)
272                    {
273                        SoundEffects.Menu.Cancel.Stop();
274                    }
275                    SoundEffects.Menu.Cancel.Play();
276                }
277            }
278        , null);
279
280        JRPG.Game.Keyboard.Listen(Key.Up, ButtonState.Pressed,
281            delegate
282            {
283                if (SelectedEnemy > 0)
284                {
285                    SelectedEnemy--; SetEnemyPointerPosition(Pointer, EnemyName);
286                    if (SoundEffects.Menu.Move.IsPlaying)
287                    {
288                        SoundEffects.Menu.Move.Stop();
289                    }
290                    SoundEffects.Menu.Move.Play();
291                }
292            }
293        ,null);
294        JRPG.Game.Keyboard.Listen(Key.Down, ButtonState.Pressed,
295            delegate
296            {
297                if (SelectedEnemy < Enemies.Count - 1)
298                {
299                    SelectedEnemy++; SetEnemyPointerPosition(Pointer, EnemyName);
300                    if (SoundEffects.Menu.Move.IsPlaying)
301                    {
302                        SoundEffects.Menu.Move.Stop();
303                    }
304                    SoundEffects.Menu.Move.Play();
305                }
306            }
307        , null);
308
309        SetEnemyPointerPosition(Pointer, EnemyName);
310    }
311
312    void SetEnemyPointerPosition(Pointer Pointer, BetterLabel EnemyName)
313    {
314        Pointer.BorderPosition = EnemiesOnScreen[SelectedEnemy].Position + new Vector(0, 20 + EnemiesOnScreen[SelectedEnemy].Height / 2) - JRPG.Game.Camera.Position;
315        EnemyName.Text = Enemies[SelectedEnemy].Name;
316        EnemyName.FontPosition = VectorConverter.JypeliVectorToXNA(Pointer.BorderPosition + new Vector(0, 25));
317        EnemyName.Alignment = TextAlignment.Center;
318    }
319
320    void DamageHitsplat(Vector StartingPosition, int Damage, bool Crit)
321    {
322        BetterLabel DMG = new BetterLabel(JRPG.Game.MainFont, StartingPosition, Damage.ToString(), TextAlignment.Center);
323        DMG.Position = StartingPosition;
324        if (Crit) DMG.TextColor = Microsoft.Xna.Framework.Color.Gold;
325        JRPG.Game.Add(DMG);
326
327        DMG.Hitsplat(350, 0.2f, 2f, delegate {
328            DMG.Destroy();
329        });
330    }
331
332    Action Flee()
333    {
334        return delegate
335        {
336            int r = RandomGen.NextInt(0, 100);
337
338            if (r < BattleAlgorithms.FleePercent(_EnemyGroup))
339            {
340                ActionQueue.Enqueue(delegate
341                {
342
343                });
344            }
345            else
346            {
347
348            }
349        };
350    }
351
352    void EndBattle()
353    {
354        Flags.InBattle = false;
355
356        for (int i = 0; i < AllyNames.Count; i++)
357        {
358            AllyNames[i].Destroy();
359        }
360
361        for (int i = 0; i < ToDeleteOnExit.Count; i++)
362        {
363            ToDeleteOnExit[i].Destroy();
364        }
365
366        BattleHUD.Destroy();
367        BattleMenu.Destroy();
368
369        JRPG.Game.ClearControls();
370        Background.Destroy();
371
372        JRPG.Game.LoadOWControlsKeyboard();
373        JRPG.Game.LoadOWControlsXboxController();
374    }
375
376    Action<CharacterBase> LoadBattleMenu(CharacterBase character)
377    {
378        return delegate
379        {
380            IsInMenu = true;
381
382            AllyNames[character.Index].IsFlashing = true;
383
384            BattleMenu = new ScrollingTextMenu();
385            BattleMenu.SetTextBases(JRPG.Game.MainFont, TextAlignment.Left);
386
387            for (int i = 0; i < character.LearnedAttacks.Count; i++)
388            {
389                int Index = i;
390
391                BattleMenu.AddMenuElement(character.LearnedAttacks[i].Name);
392                BattleMenu.ActionWhenSelected.Add(
393                    delegate {
394                        _AllyQueue.Cut(character);
395                        IsInMenu = true;
396                        AllyNames[character.Index].IsFlashing = true;
397                        character.LearnedAttacks[Index].OnUse(); }
398                    );
399            }
400
401            if (character.LearnedSkills.Count > 0)
402            {
403                BattleMenu.AddMenuElement("skills");
404                BattleMenu.ActionWhenSelected.Add(delegate { });
405            }
406            BattleMenu.AddMenuElement("items");
407            BattleMenu.ActionWhenSelected.Add(delegate { });
408            BattleMenu.AddMenuElement("flee");
409            BattleMenu.ActionWhenSelected.Add(Flee());
410
411            BattleMenu.ActionOnExit = delegate
412            {
413                IsInMenu = false;
414                AllyNames[character.Index].IsFlashing = false;
415                AllyNames[character.Index].TextColor = Microsoft.Xna.Framework.Color.White;
416            };
417
418            BattleMenu.LoadMenuElements();
419        };
420    }
421
422    void BattleTimer(double deltaTime)
423    {
424        for (int i = 0; i < Allies.Count; i++)
425        {
426            if (!Allies[i].CanMakeAction)
427            {
428                Allies[i].ElapsedTime += deltaTime;
429                Allies[i].WaitTimeMeter.Value += deltaTime;
430                if (Allies[i].ElapsedTime >= Allies[i].WaitTime)
431                {
432                    Allies[i].ElapsedTime = 0.0;
433                    Allies[i].CanMakeAction = true;
434                    _AllyQueue.Enqueue(Allies[i]);
435                    AllyQueue.Enqueue(LoadBattleMenu(Allies[i]));
436                }
437            }
438        }
439
440        for (int i = 0; i < Enemies.Count - 1; i++)
441        {
442            if (!Enemies[i].CanMakeAction)
443            {
444                Enemies[i].ElapsedTime += deltaTime;
445                if (Enemies[i].ElapsedTime >= Enemies[i].WaitTime)
446                {
447                    Enemies[i].ElapsedTime = 0.0;
448                    Enemies[i].CanMakeAction = true;
449                }
450            }
451        }
452    }
453
454    public override void Update(Time time)
455    {
456        if (Flags.InBattle)
457        {
458            if (AllyQueue.Count > 0 && !IsInMenu)
459            {
460                AllyQueue.Dequeue().Invoke(_AllyQueue.Peek());
461            }
462
463            if (ActionQueue.Count > 0 && !IsAttackAnimationPlaying)
464            {
465                IsAttackAnimationPlaying = true;
466                IsTimerActive = false;
467                ActionQueue.Dequeue().Invoke();
468            }
469
470            if (IsTimerActive)
471            {
472                double deltaTime = (float)time.SinceLastUpdate.TotalSeconds;
473                BattleTimer(deltaTime);
474            }
475        }
476
477        base.Update(time);
478    }
479}
Note: See TracBrowser for help on using the repository browser.