-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBattleScene.cpp
More file actions
186 lines (148 loc) · 5.53 KB
/
Copy pathBattleScene.cpp
File metadata and controls
186 lines (148 loc) · 5.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "BattleScene.h"
#include "Action.h"
#include <iostream>
BattleScene::BattleScene()
{
TurnInputHandler_ = std::make_shared<class InputHandler>();
TurnInputHandler_->Subscribe(this);
}
void BattleScene::AddCharacter(SceneDef::TargetPtr&& Character) noexcept
{
Characters.push_back(Character);
Render_->AddCharacter(Character->Graphic);
}
/*THEME(Nick):Turn()
Problem 1:How to change targets without passing Characters to Hero Class
Problem 2:Attack and Defend consumes turn, while ChangeTarget doesn't
Problem 3:Skill system allows for multiple target types and multiple turn actions, which leads to bigger problem than problem 1
Solution 1(checking...):
Create Action queue and countdown param in Action (Done)
Create LoadAction() that loads Action list for scene(probably move to global scene load later)
Create ChooseAction() that returns Action(Command pattern) (Done)
Execute Action, which leads to finding out target and executing one of the functions in Hero (Done)
*/
/*THEME(Nick):ChooseAction()
The way is see it:
Battle starts->
Some Game function loads characters->
Scene setups characters Actions->(Check Root 2)
User chooses skill->
User chooses Targets->
Action executes->
Tasks being checked
Root 1: In current state scene should know about all actions for each actor
Solution 1:
Create set of actions {NextAction,PrevAction,ExecuteAction} and store actions in HeroClass
Argument:
This will keep Scene from knowing all actions, and leads to only 1 actions loading, on Character init
More over, it means, that scene doesn't have same Action patter in each battle
Despite it leads to storing copies of one Action in heroes, but their size is so small it will not became a problem
Solution 2:
Set of {Attack,Defend,Skill}. Attack and Defend execute Attack and Defend methods in Hero(or just call execute() on Action)
Skill calls LoadSkills for current Hero, creating new set of actions
Argument:
No copies of standard actions in standard encounters
This will move all Action resolving staff into Hero class, and easy to implement,
but I'l be stuck with same Attack,Defend, Skill (and future Party) pattern
Solution 3:
Keep it that way, and think of format, that can save all information needed
Argument:
Headers aren't this kind of problem you should be thinking of
Scenes than can have different set of actions for each encounter(And writing standard set in each standard battle)
Root 2: Where is loading actions supposed to happen?
Solution 1: On Character init (seems nice, but restrictive)
Argument:
Keeps character data in character class
Creates copies of standard actions(if second solutions isn't choosed)
Don't sure how to create special scene-based actions
Solution 2: On Scene init (seems really bad)
Argument:
Easy scene-based actions creation
Scene should know about all characters skills
Solution 3: On Calling Skill Action (seems interesting, but with ugly code)
Argument:
Easy scene-based and plot-based actions creation
Scene should know about all characters skills
Loads skills only if needed
Root 3: Separated Scene and render means InputHandler code duplication(Solved)
*/
BattleSceneDef::ActionPtr BattleScene::ChooseAction(const sf::Keyboard::Key Key)//TODO(Nick):Read about Factory method
{
//static auto I(0U);
if (Key==sf::Keyboard::Down)
{
return NextAction_;
}
if (Key ==sf::Keyboard::Up)
{
return PrevAction_;
}
if (Key == sf::Keyboard::Enter)
{
return ExecuteAction_;
}
return nullptr;
};
void BattleScene::Update(const sf::Keyboard::Key Key)
{
auto TurnAction = ChooseAction(Key);
if (TurnAction == nullptr) {
return;
}
TurnAction->Execute(*Characters.at(CurrentChar_));
if (TurnAction==ExecuteAction_)
{
Characters.at(CurrentChar_)->Graphic->LoadAnimation(AnimationState::Idle);
CurrentChar_++;
if (CurrentChar_ >= Characters.size())
{
CurrentChar_ = 0;
}
}
};
void BattleScene::UpdateScene()
{
TurnInputHandler_->HandleInput();
};
void BattleScene::Redraw()
{
Characters.at(CurrentChar_)->Graphic->LoadAnimation(AnimationState::Chosen);
Render_->RenderScene();
for (auto& Char:Characters)
{
Char->Graphic->Update();
}
};
void BattleScene::Load(const std::string& FileName)//TODO(Nick): Figure out normal loading variant
{
std::ifstream SceneFile;
SceneFile.open(FileName);
Render_ = std::make_unique<class Render>(400,400);
auto Characters=TagXmlParser::FindAllTags<std::string>(SceneFile,"Hero");
for (const auto& Char:Characters)
{
AddCharacter(std::make_shared<Hero>(Char));
}
SetupCharactersPosition();
this->Characters.at(CurrentChar_)->Graphic->LoadAnimation(AnimationState::Chosen);
SceneFile.close();
}
void BattleScene::SetupCharactersPosition() noexcept//NOTE(Nick):still not sure if this belongs here
{
auto HeroCount(0);
auto EnemyCount(0);
const auto SpriteSpace(100);
for (auto& Char : Characters)//NOTE(Nick): If I could guarantee that Characters list is order by side, I could move this to Render class
{
if (Char->Side == HeroDef::Hero) {
HeroCount++;
Char->Graphic->Sprite.setPosition(static_cast<float>(Render_->RenderWidth) / 2 - static_cast<float>(SpriteSpace * HeroCount),
static_cast<float>(Render_->RenderHeight) / 2);
}
else if (Char->Side == HeroDef::Enemy) {
EnemyCount++;
Char->Graphic->Sprite.setPosition(static_cast<float>(Render_->RenderWidth) / 2 + static_cast<float>(SpriteSpace * EnemyCount),
static_cast<float>(Render_->RenderHeight) / 2);
}
}
};