summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation.cpp93
-rw-r--r--src/animation.h39
-rw-r--r--src/direction.h22
-rw-r--r--src/game.h2
-rw-r--r--src/main.cpp11
-rw-r--r--src/renderer.cpp22
-rw-r--r--src/renderer.h1
-rw-r--r--src/util.h35
8 files changed, 221 insertions, 4 deletions
diff --git a/src/animation.cpp b/src/animation.cpp new file mode 100644 index 0000000..fbf7ccf --- /dev/null +++ b/src/animation.cpp
@@ -0,0 +1,93 @@
1#include "animation.h"
2#include <string_view>
3#include <fstream>
4#include <stdexcept>
5#include <string>
6#include <regex>
7#include <list>
8#include "direction.h"
9#include "util.h"
10
11Animation::Animation(std::string_view path) {
12 std::ifstream datafile(path.data());
13 if (!datafile.is_open()) {
14 throw std::invalid_argument(std::string("Could not find sprite datafile: ") + path.data());
15 }
16
17 std::string animLine;
18 char ch;
19 int cellWidth;
20 int cellHeight;
21 datafile >> cellWidth;
22 datafile >> ch; //,
23 datafile >> cellHeight;
24 std::getline(datafile, animLine); // cell size
25
26 int framesPerRow;
27 datafile >> framesPerRow;
28 std::getline(datafile, animLine); // frames per row
29
30 int numFrames;
31 datafile >> numFrames;
32 std::getline(datafile, animLine); // frames
33 std::getline(datafile, animLine); // blank
34
35 for (int i=0; i<numFrames; i++) {
36 SDL_Rect srcRect;
37 srcRect.x = (i % framesPerRow) * cellWidth;
38 srcRect.y = (i / framesPerRow) * cellHeight;
39 srcRect.w = cellWidth;
40 srcRect.h = cellHeight;
41 frames_.push_back(srcRect);
42 }
43
44 while (std::getline(datafile, animLine)) {
45 std::regex re(R"(([a-z!._]+)\[([a-z_]+)\]: ([0-9,]+))");
46 std::smatch m;
47 std::regex_match(animLine, m, re);
48
49 std::string animName = m[1];
50 std::vector<int> anim;
51 auto framestrs = splitStr<std::list<std::string>>(m[3], ",");
52 for (const std::string& f : framestrs) {
53 anim.push_back(std::stoi(f));
54 }
55
56 int animId = animations_.size();
57 animations_.push_back(std::move(anim));
58
59 Direction dir = directionFromString(std::string(m[2]));
60 nameDirToAnim_[animName][dir] = animId;
61 }
62
63 updateAnim();
64}
65
66void Animation::setDirection(Direction dir) {
67 dir_ = dir;
68 updateAnim();
69}
70
71void Animation::setAnimation(std::string_view anim) {
72 animationName_ = anim;
73 updateAnim();
74}
75
76void Animation::update(int dt) {
77 animTimer_.accumulate(dt);
78
79 while (animTimer_.step()) {
80 animationFrame_++;
81
82 if (animationFrame_ >= animations_.at(animationId_).size()) {
83 animationFrame_ = 0;
84 }
85 }
86}
87
88void Animation::updateAnim() {
89 if (nameDirToAnim_.at(animationName_).at(dir_) != animationId_) {
90 animationId_ = nameDirToAnim_.at(animationName_).at(dir_);
91 animationFrame_ = 0;
92 }
93}
diff --git a/src/animation.h b/src/animation.h new file mode 100644 index 0000000..0108c12 --- /dev/null +++ b/src/animation.h
@@ -0,0 +1,39 @@
1#ifndef ANIMATION_H_332518EB
2#define ANIMATION_H_332518EB
3
4#include <string>
5#include <map>
6#include <vector>
7#include <string_view>
8#include <SDL.h>
9#include "direction.h"
10#include "timer.h"
11
12class Animation {
13public:
14 explicit Animation(std::string_view path);
15
16 void setDirection(Direction dir);
17 void setAnimation(std::string_view anim);
18
19 const SDL_Rect& getRenderRect() const {
20 return frames_.at(animations_.at(animationId_).at(animationFrame_));
21 }
22
23 void update(int dt);
24
25private:
26
27 void updateAnim();
28
29 std::vector<SDL_Rect> frames_;
30 std::vector<std::vector<int>> animations_;
31 std::map<std::string, std::map<Direction, int>> nameDirToAnim_;
32 Direction dir_ = Direction::down;
33 std::string animationName_ = "still";
34 int animationId_ = 0;
35 int animationFrame_ = 0;
36 Timer animTimer_ = {1000/5};
37};
38
39#endif /* end of include guard: ANIMATION_H_332518EB */
diff --git a/src/direction.h b/src/direction.h new file mode 100644 index 0000000..0fe3e5a --- /dev/null +++ b/src/direction.h
@@ -0,0 +1,22 @@
1#ifndef DIRECTION_H_42BDAFB9
2#define DIRECTION_H_42BDAFB9
3
4#include <string_view>
5#include <stdexcept>
6
7enum class Direction {
8 up,
9 down,
10 left,
11 right
12};
13
14inline Direction directionFromString(std::string_view str) {
15 if (str == "up") return Direction::up;
16 if (str == "right") return Direction::right;
17 if (str == "down") return Direction::down;
18 if (str == "left") return Direction::left;
19 throw std::invalid_argument("Invalid direction: " + std::string(str));
20}
21
22#endif /* end of include guard: DIRECTION_H_42BDAFB9 */
diff --git a/src/game.h b/src/game.h index c489afc..2fd0f05 100644 --- a/src/game.h +++ b/src/game.h
@@ -8,6 +8,7 @@
8#include "map.h" 8#include "map.h"
9#include "muxer.h" 9#include "muxer.h"
10#include "timer.h" 10#include "timer.h"
11#include "animation.h"
11 12
12const int GAME_WIDTH = 640*2; 13const int GAME_WIDTH = 640*2;
13const int GAME_HEIGHT = 480*2; 14const int GAME_HEIGHT = 480*2;
@@ -102,6 +103,7 @@ public:
102 int player_x = 0; 103 int player_x = 0;
103 int player_y = 0; 104 int player_y = 0;
104 bool renderPlayer = true; 105 bool renderPlayer = true;
106 Animation playerAnim {"../res/player_anim.txt"};
105 107
106 int maxZoom = INIT_ZOOM; 108 int maxZoom = INIT_ZOOM;
107 109
diff --git a/src/main.cpp b/src/main.cpp index 1805357..5178110 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -207,6 +207,7 @@ bool processKeys(Game& game, const Input& keystate)
207{ 207{
208 int px = game.player_x; 208 int px = game.player_x;
209 int py = game.player_y; 209 int py = game.player_y;
210 Direction dir = Direction::up;
210 211
211 if (keystate.up) 212 if (keystate.up)
212 { 213 {
@@ -216,20 +217,26 @@ bool processKeys(Game& game, const Input& keystate)
216 if (keystate.down) 217 if (keystate.down)
217 { 218 {
218 py++; 219 py++;
220 dir = Direction::down;
219 } 221 }
220 222
221 if (keystate.left) 223 if (keystate.left)
222 { 224 {
223 px--; 225 px--;
226 dir = Direction::left;
224 } 227 }
225 228
226 if (keystate.right) 229 if (keystate.right)
227 { 230 {
228 px++; 231 px++;
232 dir = Direction::right;
229 } 233 }
230 234
231 if (!(game.player_x == px && game.player_y == py)) 235 if (!(game.player_x == px && game.player_y == py))
232 { 236 {
237 game.playerAnim.setAnimation("walk");
238 game.playerAnim.setDirection(dir);
239
233 return movePlayer(game, px, py); 240 return movePlayer(game, px, py);
234 } else { 241 } else {
235 return false; 242 return false;
@@ -614,6 +621,8 @@ int main(int, char**)
614 { 621 {
615 game.firstInput = true; 622 game.firstInput = true;
616 game.lastInput = keystate; 623 game.lastInput = keystate;
624 } else if (losing == LoseState::None) {
625 game.playerAnim.setAnimation("still");
617 } 626 }
618 627
619 dustAcc += frameTime; 628 dustAcc += frameTime;
@@ -767,6 +776,8 @@ int main(int, char**)
767 zoomAcc -= zoomDt; 776 zoomAcc -= zoomDt;
768 } 777 }
769 778
779 game.playerAnim.update(frameTime);
780
770 game.muxer.update(); 781 game.muxer.update();
771 renderer.render(game, true); 782 renderer.render(game, true);
772 } 783 }
diff --git a/src/renderer.cpp b/src/renderer.cpp index 2dac07e..0aaa14a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -110,6 +110,18 @@ Renderer::Renderer()
110 110
111 SDL_SetRenderDrawColor(ren_.get(), 100, 100, 100, 255); 111 SDL_SetRenderDrawColor(ren_.get(), 100, 100, 100, 255);
112 SDL_RenderFillRect(ren_.get(), nullptr); 112 SDL_RenderFillRect(ren_.get(), nullptr);
113
114 {
115 surface_ptr pfs(IMG_Load("../res/player.png"));
116 if (!pfs)
117 {
118 throw img_error();
119 }
120
121 playerSheet_ = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get()));
122 }
123
124 SDL_SetTextureBlendMode(playerSheet_.get(), SDL_BLENDMODE_BLEND);
113} 125}
114 126
115void Renderer::render( 127void Renderer::render(
@@ -140,10 +152,7 @@ void Renderer::render(
140 { 152 {
141 bool draw = true; 153 bool draw = true;
142 154
143 if ((game.player_x == x && game.player_y == y) && game.renderPlayer) 155 if (!game.map.at(x,y).lit)
144 {
145 SDL_SetRenderDrawColor(ren_.get(), 255, 255, 0, 255);
146 } else if (!game.map.at(x,y).lit)
147 { 156 {
148 if (drawDark) 157 if (drawDark)
149 { 158 {
@@ -191,6 +200,11 @@ void Renderer::render(
191 TILE_HEIGHT}; 200 TILE_HEIGHT};
192 201
193 SDL_RenderFillRect(ren_.get(), &rect); 202 SDL_RenderFillRect(ren_.get(), &rect);
203
204 if ((game.player_x == x && game.player_y == y) && game.renderPlayer)
205 {
206 SDL_RenderCopy(ren_.get(), playerSheet_.get(), &game.playerAnim.getRenderRect(), &rect);
207 }
194 } 208 }
195 } 209 }
196 } 210 }
diff --git a/src/renderer.h b/src/renderer.h index a34b231..0416c9e 100644 --- a/src/renderer.h +++ b/src/renderer.h
@@ -129,6 +129,7 @@ private:
129 texture_ptr playerFade_; 129 texture_ptr playerFade_;
130 texture_ptr lampFade_; 130 texture_ptr lampFade_;
131 texture_ptr dustFade_; 131 texture_ptr dustFade_;
132 texture_ptr playerSheet_;
132}; 133};
133 134
134#endif /* end of include guard: RENDERER_H_6A58EC30 */ 135#endif /* end of include guard: RENDERER_H_6A58EC30 */
diff --git a/src/util.h b/src/util.h index 150a6a5..1eb2303 100644 --- a/src/util.h +++ b/src/util.h
@@ -1,6 +1,9 @@
1#ifndef UTIL_H_E9110D4C 1#ifndef UTIL_H_E9110D4C
2#define UTIL_H_E9110D4C 2#define UTIL_H_E9110D4C
3 3
4#include <string>
5#include <iterator>
6
4template <typename Container, typename Predicate> 7template <typename Container, typename Predicate>
5void erase_if(Container& items, const Predicate& predicate) 8void erase_if(Container& items, const Predicate& predicate)
6{ 9{
@@ -17,4 +20,36 @@ void erase_if(Container& items, const Predicate& predicate)
17 } 20 }
18}; 21};
19 22
23template <class OutputIterator>
24void splitStr(
25 std::string input,
26 std::string delimiter,
27 OutputIterator out) {
28 while (!input.empty()) {
29 int divider = input.find(delimiter);
30 if (divider == std::string::npos) {
31 *out = input;
32 out++;
33
34 input = "";
35 } else {
36 *out = input.substr(0, divider);
37 out++;
38
39 input = input.substr(divider+delimiter.length());
40 }
41 }
42}
43
44template <class Container>
45Container splitStr(
46 std::string input,
47 std::string delimiter) {
48 Container result;
49
50 splitStr(input, delimiter, std::back_inserter(result));
51
52 return result;
53}
54
20#endif /* end of include guard: UTIL_H_E9110D4C */ 55#endif /* end of include guard: UTIL_H_E9110D4C */