Browse Source

Modern random numbers generator, deduplicate some code, Bonus class

Pabloader 5 years ago
parent
commit
b4ebec6437
13 changed files with 205 additions and 82 deletions
  1. 3
    1
      .vscode/c_cpp_properties.json
  2. 13
    0
      include/bonus.h
  3. 0
    10
      include/bug.h
  4. 23
    4
      include/debuggers.h
  5. 21
    4
      include/entity.h
  6. 2
    4
      include/programmer.h
  7. 0
    0
      res/bonuses.png
  8. 16
    0
      src/bonus.cpp
  9. 3
    40
      src/bug.cpp
  10. 63
    2
      src/debuggers.cpp
  11. 41
    3
      src/entity.cpp
  12. 4
    1
      src/player.cpp
  13. 16
    13
      src/programmer.cpp

+ 3
- 1
.vscode/c_cpp_properties.json View File

27
             "includePath": [
27
             "includePath": [
28
                 "${workspaceFolder}/**"
28
                 "${workspaceFolder}/**"
29
             ],
29
             ],
30
-            "defines": [],
30
+            "defines": [
31
+                "_DEBUG"
32
+            ],
31
             "compilerPath": "/usr/bin/gcc",
33
             "compilerPath": "/usr/bin/gcc",
32
             "cStandard": "c11",
34
             "cStandard": "c11",
33
             "cppStandard": "c++17",
35
             "cppStandard": "c++17",

+ 13
- 0
include/bonus.h View File

1
+#ifndef BONUS_H
2
+#define BONUS_H
3
+
4
+#include "entity.h"
5
+
6
+namespace pabloader {
7
+class Bonus : public Entity {
8
+public:
9
+    Bonus(Debuggers* game);
10
+};
11
+}
12
+
13
+#endif

+ 0
- 10
include/bug.h View File

7
 class Bug : public Entity {
7
 class Bug : public Entity {
8
 public:
8
 public:
9
     Bug(Debuggers* game);
9
     Bug(Debuggers* game);
10
-    void Update(float dt) override;
11
-    void Draw() override;
12
-    bool IsActive();
13
-    void ResetPosition();
14
-    void Kill();
15
-
16
-private:
17
-    int kind = 0;
18
-    float rotation = 0;
19
-    int8_t rotationSpeed;
20
 };
10
 };
21
 }
11
 }
22
 
12
 

+ 23
- 4
include/debuggers.h View File

1
 #ifndef DEBUGGERS_H
1
 #ifndef DEBUGGERS_H
2
 #define DEBUGGERS_H
2
 #define DEBUGGERS_H
3
 
3
 
4
-#include "bug.h"
5
 #include "olcPGEX_Sound.h"
4
 #include "olcPGEX_Sound.h"
6
 #include "olcPixelGameEngine.h"
5
 #include "olcPixelGameEngine.h"
7
-#include "programmer.h"
6
+
7
+#include "bonus.h"
8
+#include "bug.h"
8
 #include "player.h"
9
 #include "player.h"
9
-#include <vector>
10
+#include "programmer.h"
11
+
10
 #include <string>
12
 #include <string>
13
+#include <vector>
14
+#include <random>
15
+#include <chrono>
11
 
16
 
12
 namespace pabloader {
17
 namespace pabloader {
13
 class Debuggers : public olc::PixelGameEngine {
18
 class Debuggers : public olc::PixelGameEngine {
14
 private:
19
 private:
15
     std::vector<Programmer*> programmers;
20
     std::vector<Programmer*> programmers;
21
+    std::vector<Bonus*> bonuses;
22
+
16
     uint32_t bugsCatched = 0;
23
     uint32_t bugsCatched = 0;
17
     uint32_t bugsMissed = 0;
24
     uint32_t bugsMissed = 0;
18
 
25
 
19
     uint8_t linesOfCode = 5;
26
     uint8_t linesOfCode = 5;
20
     uint16_t totalLines;
27
     uint16_t totalLines;
21
     std::vector<std::string> sourceCode;
28
     std::vector<std::string> sourceCode;
29
+    std::random_device rd;
30
+    std::mt19937 generator;
22
 
31
 
23
 public:
32
 public:
24
-    Debuggers()
33
+    Debuggers(): generator(rd())
25
     {
34
     {
26
         sAppName = "Debuggers";
35
         sAppName = "Debuggers";
27
     }
36
     }
32
     bool OnUserDestroy() override;
41
     bool OnUserDestroy() override;
33
     int GameScreenHeight() { return ScreenHeight() - linesOfCode * 10; };
42
     int GameScreenHeight() { return ScreenHeight() - linesOfCode * 10; };
34
 
43
 
44
+    template <typename T>
45
+    T GetRandom(T from = 0, T to = 1);
46
+
35
 private:
47
 private:
36
     void SpawnProgrammer();
48
     void SpawnProgrammer();
37
     void SpawnBug();
49
     void SpawnBug();
50
+    void SpawnBonus();
38
     Bug* CreateBug();
51
     Bug* CreateBug();
52
+    Bonus* CreateBonus();
39
     bool GameOver();
53
     bool GameOver();
40
 
54
 
41
 public:
55
 public:
42
     std::vector<Bug*> bugs;
56
     std::vector<Bug*> bugs;
43
 
57
 
44
     olc::ResourcePack pack;
58
     olc::ResourcePack pack;
59
+
45
     olc::Sprite playerSprite;
60
     olc::Sprite playerSprite;
46
     olc::Sprite enemiesSprite;
61
     olc::Sprite enemiesSprite;
62
+    olc::Sprite bonusesSprite;
47
     olc::Sprite backgroundSprite;
63
     olc::Sprite backgroundSprite;
64
+
48
     int playerFallSample;
65
     int playerFallSample;
49
     int bugFallSample;
66
     int bugFallSample;
50
     int bugCatchSample;
67
     int bugCatchSample;
68
+
69
+    const int gravity = 30;
51
 };
70
 };
52
 }
71
 }
53
 
72
 

+ 21
- 4
include/entity.h View File

11
 class Entity {
11
 class Entity {
12
 protected:
12
 protected:
13
     Debuggers* game;
13
     Debuggers* game;
14
+    olc::Sprite* sprite;
14
     olc::GFX2D::Transform2D transform;
15
     olc::GFX2D::Transform2D transform;
15
     float x, y;
16
     float x, y;
16
-    float xv, yv;
17
+    float xv = 0, yv = 0;
17
     int w, h;
18
     int w, h;
18
 
19
 
20
+    uint8_t tileX = 0;
21
+    uint8_t tileY = 0;
22
+
23
+    uint8_t tileCols = 4;
24
+    uint8_t tileRows = 4;
25
+
26
+    float rotation = 0;
27
+    float rotationSpeed = 0;
28
+#ifdef _DEBUG
29
+    olc::Pixel DEBUG_COLOR;
30
+#endif
31
+
19
 public:
32
 public:
20
-    Entity(Debuggers* game_);
33
+    Entity(Debuggers* game, olc::Sprite* s);
21
     virtual ~Entity(){};
34
     virtual ~Entity(){};
22
 
35
 
23
-    virtual void Update(float dt) = 0;
24
-    virtual void Draw() = 0;
36
+    virtual void Update(float dt);
37
+    virtual void Draw();
25
 
38
 
26
     float GetX() { return x; }
39
     float GetX() { return x; }
27
     float GetY() { return y; }
40
     float GetY() { return y; }
28
 
41
 
29
     bool Collides(Entity* entity);
42
     bool Collides(Entity* entity);
30
     float Dist(Entity* entity) { return std::hypot(x - entity->x, y - entity->y); }
43
     float Dist(Entity* entity) { return std::hypot(x - entity->x, y - entity->y); }
44
+
45
+    virtual bool IsActive();
46
+    virtual void ResetPosition();
47
+    virtual void Kill();
31
 };
48
 };
32
 }
49
 }
33
 
50
 

+ 2
- 4
include/programmer.h View File

8
 
8
 
9
 class Programmer : public Entity {
9
 class Programmer : public Entity {
10
 protected:
10
 protected:
11
-    uint8_t tile = 0;
12
     uint32_t tileCounter = 0;
11
     uint32_t tileCounter = 0;
13
-    uint8_t skin = 0;
14
     bool onGround = false;
12
     bool onGround = false;
15
     bool doJump = false;
13
     bool doJump = false;
16
     bool walkLeft = false;
14
     bool walkLeft = false;
23
     virtual void Update(float dt) override;
21
     virtual void Update(float dt) override;
24
     virtual void Draw() override;
22
     virtual void Draw() override;
25
     bool IsOnGround() { return onGround; }
23
     bool IsOnGround() { return onGround; }
26
-    uint8_t GetSkin() { return skin; }
27
-    void UpgradeLevel() { skin = std::min(skin + 1, 2); }
24
+    uint8_t GetSkin() { return tileX; }
25
+    void UpgradeLevel() { tileX = std::min(tileX + 1, tileCols - 1); }
28
 };
26
 };
29
 }
27
 }
30
 
28
 

res/sprites.png → res/bonuses.png View File


+ 16
- 0
src/bonus.cpp View File

1
+#include "bug.h"
2
+#include "debuggers.h"
3
+#include <iostream>
4
+#include <random>
5
+
6
+namespace pabloader {
7
+Bonus::Bonus(Debuggers* game)
8
+    : Entity(game, &game->bonusesSprite)
9
+{
10
+    tileCols = 1;
11
+    tileRows = 1;
12
+#ifdef _DEBUG
13
+    DEBUG_COLOR = olc::YELLOW;
14
+#endif
15
+}
16
+}

+ 3
- 40
src/bug.cpp View File

5
 
5
 
6
 namespace pabloader {
6
 namespace pabloader {
7
 Bug::Bug(Debuggers* game)
7
 Bug::Bug(Debuggers* game)
8
-    : Entity(game)
9
-{
10
-    w = game->enemiesSprite.width / 4;
11
-    h = game->enemiesSprite.height / 4;
12
-}
13
-
14
-void Bug::Update(float dt)
15
-{
16
-    y += yv * dt;
17
-    yv += 30 * dt;
18
-
19
-    rotation += 3.14 / 8 * rotationSpeed * dt;
20
-
21
-    transform.Reset();
22
-    transform.Rotate(rotation);
23
-    transform.Translate(x, y);
24
-}
25
-
26
-void Bug::Draw()
8
+    : Entity(game, &game->enemiesSprite)
27
 {
9
 {
10
+    tileCols = 1;
28
 #ifdef _DEBUG
11
 #ifdef _DEBUG
29
-    game->DrawRect(x - w / 2, y - h / 2, w, h, olc::RED);
12
+    DEBUG_COLOR = olc::RED;
30
 #endif
13
 #endif
31
-    olc::GFX2D::DrawPartialSprite(&game->enemiesSprite, 0, kind * h, w, h, transform, true);
32
-}
33
-
34
-bool Bug::IsActive()
35
-{
36
-    return y - h / 2 < game->GameScreenHeight();
37
-}
38
-
39
-void Bug::ResetPosition()
40
-{
41
-    y = -20 - std::rand() % game->ScreenHeight();
42
-    x = w + std::rand() % (game->ScreenWidth() - w * 2);
43
-    yv = 0;
44
-    kind = std::rand() % 4;
45
-    rotationSpeed = -8 + rand()%17;
46
-}
47
-
48
-void Bug::Kill()
49
-{
50
-    y = game->GameScreenHeight() + 100;
51
 }
14
 }
52
 }
15
 }

+ 63
- 2
src/debuggers.cpp View File

63
         return false;
63
         return false;
64
     }
64
     }
65
 
65
 
66
+    // Load bonuses
67
+
68
+    fileName = "res/bonuses.pgs";
69
+    if (!bonusesSprite.LoadFromPGESprFile(fileName, &pack)) {
70
+        std::cerr << "[Load bonuses] File " << fileName << " is not found" << std::endl;
71
+        return false;
72
+    }
73
+
66
     // Load background
74
     // Load background
67
 
75
 
68
     fileName = "res/bg.pgs";
76
     fileName = "res/bg.pgs";
131
         }
139
         }
132
     }
140
     }
133
 
141
 
142
+    Programmer* player = programmers.at(0);
143
+
144
+    for (auto& bonus : bonuses) {
145
+        if (bonus->IsActive()) {
146
+            bonus->Update(fElapsedTime);
147
+            bonus->Draw();
148
+            if (player->Collides(bonus)) {
149
+                // TODO add to inventory
150
+                bonus->Kill();
151
+            }
152
+        }
153
+    }
154
+
134
     linesOfCode = (sourceCode.size() * 4 / totalLines) + 1;
155
     linesOfCode = (sourceCode.size() * 4 / totalLines) + 1;
135
 
156
 
136
     for (auto it = programmers.rbegin(); it != programmers.rend(); it++) {
157
     for (auto it = programmers.rbegin(); it != programmers.rend(); it++) {
140
         programmer->Draw();
161
         programmer->Draw();
141
     }
162
     }
142
 
163
 
143
-    Programmer* player = programmers.at(0);
144
-
145
     if (bugsSize == 0 && player->IsOnGround()) {
164
     if (bugsSize == 0 && player->IsOnGround()) {
146
         SpawnBug();
165
         SpawnBug();
147
     }
166
     }
155
 
174
 
156
 #ifdef _DEBUG
175
 #ifdef _DEBUG
157
     DrawString(1, 37, "Bugs: " + std::to_string(bugs.size()));
176
     DrawString(1, 37, "Bugs: " + std::to_string(bugs.size()));
177
+    DrawString(1, 46, "Progs: " + std::to_string(programmers.size()));
178
+    DrawString(1, 55, "Bonuses: " + std::to_string(bonuses.size()));
158
     if (GetKey(olc::B).bPressed) {
179
     if (GetKey(olc::B).bPressed) {
159
         SpawnBug();
180
         SpawnBug();
160
     }
181
     }
182
+    if (GetKey(olc::N).bPressed) {
183
+        SpawnBonus();
184
+    }
161
     if (GetKey(olc::P).bPressed) {
185
     if (GetKey(olc::P).bPressed) {
162
         SpawnProgrammer();
186
         SpawnProgrammer();
163
     }
187
     }
197
     bug->ResetPosition();
221
     bug->ResetPosition();
198
 }
222
 }
199
 
223
 
224
+void Debuggers::SpawnBonus()
225
+{
226
+    auto bonus = CreateBonus();
227
+    bonus->ResetPosition();
228
+}
229
+
200
 void Debuggers::SpawnProgrammer()
230
 void Debuggers::SpawnProgrammer()
201
 {
231
 {
202
     auto programmer = new Programmer(this);
232
     auto programmer = new Programmer(this);
214
     return bug;
244
     return bug;
215
 }
245
 }
216
 
246
 
247
+Bonus* Debuggers::CreateBonus()
248
+{
249
+    for (auto bonus : bonuses) {
250
+        if (!bonus->IsActive())
251
+            return bonus;
252
+    }
253
+    auto bonus = new Bonus(this);
254
+    bonuses.push_back(bonus);
255
+    return bonus;
256
+}
257
+
217
 bool Debuggers::OnUserDestroy()
258
 bool Debuggers::OnUserDestroy()
218
 {
259
 {
219
     olc::SOUND::DestroyAudio();
260
     olc::SOUND::DestroyAudio();
220
     return true;
261
     return true;
221
 }
262
 }
263
+
264
+template <>
265
+float Debuggers::GetRandom<float>(float from, float to)
266
+{
267
+    if (from > to) {
268
+        std::swap(from, to);
269
+    }
270
+    std::uniform_real_distribution<double> dist(from, to);
271
+    return dist(generator);
272
+}
273
+
274
+template <>
275
+int Debuggers::GetRandom<int>(int from, int to)
276
+{
277
+    if (from > to) {
278
+        std::swap(from, to);
279
+    }
280
+    std::uniform_int_distribution<int> dist(from, to - 1);
281
+    return dist(generator);
282
+}
222
 }
283
 }

+ 41
- 3
src/entity.cpp View File

1
 #include "entity.h"
1
 #include "entity.h"
2
+#include "debuggers.h"
2
 
3
 
3
 namespace pabloader {
4
 namespace pabloader {
4
-Entity::Entity(Debuggers* game)
5
+Entity::Entity(Debuggers* game, olc::Sprite* s): sprite(s), w(s->width / 4), h(s->height / 4)
5
 {
6
 {
6
-    xv = 0;
7
-    yv = 0;
8
     Entity::game = game;
7
     Entity::game = game;
9
 }
8
 }
10
 
9
 
10
+void Entity::Update(float dt)
11
+{
12
+    y += yv * dt;
13
+    yv += game->gravity * dt;
14
+
15
+    rotation += rotationSpeed * dt;
16
+
17
+    transform.Reset();
18
+    transform.Rotate(rotation);
19
+    transform.Translate(x, y);
20
+}
21
+
11
 bool Entity::Collides(Entity* entity)
22
 bool Entity::Collides(Entity* entity)
12
 {
23
 {
13
     bool collidesX = (x - w / 2 < entity->x + entity->w / 2) && (entity->x - entity->w / 2 < x + w / 2);
24
     bool collidesX = (x - w / 2 < entity->x + entity->w / 2) && (entity->x - entity->w / 2 < x + w / 2);
15
     return collidesX && collidesY;
26
     return collidesX && collidesY;
16
 }
27
 }
17
 
28
 
29
+void Entity::Draw()
30
+{
31
+#ifdef _DEBUG
32
+    game->DrawRect(x - w / 2, y - h / 2, w, h, DEBUG_COLOR);
33
+#endif
34
+    olc::GFX2D::DrawPartialSprite(sprite, tileX * w, tileY * h, w, h, transform, true);
35
+}
36
+
37
+bool Entity::IsActive()
38
+{
39
+    return y - h / 2 < game->GameScreenHeight();
40
+}
41
+
42
+void Entity::ResetPosition()
43
+{
44
+    y = game->GetRandom(-20, -game->ScreenHeight());
45
+    x = game->GetRandom(w, game->ScreenWidth() - w);
46
+    yv = 0;
47
+    tileX = game->GetRandom<int>(0, tileCols);
48
+    tileY = game->GetRandom<int>(0, tileRows);
49
+    rotationSpeed = game->GetRandom(-3.14f, 3.14f);
50
+}
51
+
52
+void Entity::Kill()
53
+{
54
+    y = game->ScreenHeight() + 100;
55
+}
18
 }
56
 }

+ 4
- 1
src/player.cpp View File

7
 Player::Player(Debuggers* game)
7
 Player::Player(Debuggers* game)
8
     : Programmer(game)
8
     : Programmer(game)
9
 {
9
 {
10
+#ifdef _DEBUG
11
+    DEBUG_COLOR = olc::BLUE;
12
+#endif
10
 }
13
 }
11
 
14
 
12
 void Player::Think()
15
 void Player::Think()
20
     // game->DrawString(1, 28, std::to_string(xv) + " " + std::to_string(yv));
23
     // game->DrawString(1, 28, std::to_string(xv) + " " + std::to_string(yv));
21
 
24
 
22
     if (game->GetKey(olc::J).bPressed) {
25
     if (game->GetKey(olc::J).bPressed) {
23
-        skin = (skin + 1) % 4;
26
+        tileX = (tileX + 1) % tileCols;
24
     }
27
     }
25
 #endif
28
 #endif
26
 }
29
 }

+ 16
- 13
src/programmer.cpp View File

5
 
5
 
6
 namespace pabloader {
6
 namespace pabloader {
7
 Programmer::Programmer(Debuggers* game)
7
 Programmer::Programmer(Debuggers* game)
8
-    : Entity(game)
8
+    : Entity(game, &game->playerSprite)
9
 {
9
 {
10
-    w = game->playerSprite.width / 4;
11
-    h = game->playerSprite.height / 4;
12
     x = (game->ScreenWidth() - w) / 2;
10
     x = (game->ScreenWidth() - w) / 2;
13
     y = h / 2;
11
     y = h / 2;
12
+    tileCols = 3;
13
+
14
+#ifdef _DEBUG
15
+    DEBUG_COLOR = olc::GREEN;
16
+#endif
14
 }
17
 }
15
 
18
 
16
 void Programmer::Think()
19
 void Programmer::Think()
46
     xv *= 1 - 0.2 * dt;
49
     xv *= 1 - 0.2 * dt;
47
 
50
 
48
     if (!onGround) {
51
     if (!onGround) {
49
-        yv += (70 + skin * 30) * dt;
52
+        yv += (70 + tileX * 30) * dt;
50
         yv *= 1 - 0.05 * dt;
53
         yv *= 1 - 0.05 * dt;
51
     } else {
54
     } else {
52
         xv *= 1 - dt;
55
         xv *= 1 - dt;
57
     bool userInput = false;
60
     bool userInput = false;
58
 
61
 
59
     if (doJump && onGround) {
62
     if (doJump && onGround) {
60
-        yv = -100 - 50 * skin;
63
+        yv = -100 - 50 * tileX;
61
         userInput = true;
64
         userInput = true;
62
     }
65
     }
63
 
66
 
64
     if (walkLeft) {
67
     if (walkLeft) {
65
-        xv -= (150 + skin * 50) * dt;
68
+        xv -= (150 + tileX * 50) * dt;
66
         userInput = true;
69
         userInput = true;
67
     }
70
     }
68
 
71
 
69
     if (walkRight) {
72
     if (walkRight) {
70
-        xv += (150 + skin * 50) * dt;
73
+        xv += (150 + tileX * 50) * dt;
71
         userInput = true;
74
         userInput = true;
72
     }
75
     }
73
 
76
 
74
     if (moveDown) {
77
     if (moveDown) {
75
         if (!onGround) {
78
         if (!onGround) {
76
-            yv += (150 + skin * 50) * dt;
79
+            yv += (150 + tileX * 50) * dt;
77
         }
80
         }
78
         userInput = true;
81
         userInput = true;
79
     }
82
     }
106
     onGround = newOnGround;
109
     onGround = newOnGround;
107
 
110
 
108
     if (onGround) {
111
     if (onGround) {
109
-        tile = 2;
112
+        tileY = 2;
110
         tileCounter = static_cast<uint32_t>(0.1 / dt);
113
         tileCounter = static_cast<uint32_t>(0.1 / dt);
111
     } else if (tileCounter <= 0) {
114
     } else if (tileCounter <= 0) {
112
-        tile = 0;
115
+        tileY = 0;
113
     } else {
116
     } else {
114
         tileCounter--;
117
         tileCounter--;
115
     }
118
     }
127
 {
130
 {
128
     int xOff = xv < 0 ? -1 : 0;
131
     int xOff = xv < 0 ? -1 : 0;
129
     if (std::abs(xv) < 1) {
132
     if (std::abs(xv) < 1) {
130
-        olc::GFX2D::DrawPartialSprite(&game->playerSprite, skin * w + xOff, h + tile * h, w - xOff, h, transform, true);
133
+        olc::GFX2D::DrawPartialSprite(&game->playerSprite, tileX * w + xOff, h + tileY * h, w - xOff, h, transform, true);
131
     } else {
134
     } else {
132
-        olc::GFX2D::DrawPartialSprite(&game->playerSprite, skin * w + xOff, 0 + tile * h, w - xOff, h, transform, true);
135
+        olc::GFX2D::DrawPartialSprite(&game->playerSprite, tileX * w + xOff, 0 + tileY * h, w - xOff, h, transform, true);
133
     }
136
     }
134
 #ifdef _DEBUG
137
 #ifdef _DEBUG
135
-    game->DrawRect(x - w / 2, y - h / 2, w, h, olc::GREEN);
138
+    game->DrawRect(x - w / 2, y - h / 2, w, h, DEBUG_COLOR);
136
 #endif
139
 #endif
137
 }
140
 }
138
 }
141
 }

Loading…
Cancel
Save