Browse Source

Bouncing ball controlled with keyboard

Pabloader 5 years ago
parent
commit
5c0574ded5
6 changed files with 164 additions and 53 deletions
  1. 1
    1
      Makefile
  2. 13
    12
      pge/include/olcPGEX_Graphics2D.h
  3. 70
    6
      pge/src/olcPGEX_Graphics2D.cpp
  4. BIN
      res/awoorwa.png
  5. 73
    26
      src/pabloader/awoorwae.cpp
  6. 7
    8
      src/pabloader/awoorwae.h

+ 1
- 1
Makefile View File

19
 	CPP=g++
19
 	CPP=g++
20
 endif
20
 endif
21
 ifeq ($(DEBUG),1)
21
 ifeq ($(DEBUG),1)
22
-	CPPFLAGS+=-g -Og
22
+	CPPFLAGS+=-g -Og -D_DEBUG
23
 else
23
 else
24
 	CPPFLAGS+=-flto -O3
24
 	CPPFLAGS+=-flto -O3
25
 endif
25
 endif

+ 13
- 12
pge/include/olcPGEX_Graphics2D.h View File

85
 		class Transform2D
85
 		class Transform2D
86
 		{
86
 		{
87
 		public:
87
 		public:
88
-			inline Transform2D();
88
+			Transform2D();
89
 
89
 
90
 		public:
90
 		public:
91
 			// Set this transformation to unity
91
 			// Set this transformation to unity
92
-			inline void Reset();
92
+			void Reset();
93
 			// Append a rotation of fTheta radians to this transform
93
 			// Append a rotation of fTheta radians to this transform
94
-			inline void Rotate(float fTheta);
94
+			void Rotate(float fTheta);
95
 			// Append a translation (ox, oy) to this transform
95
 			// Append a translation (ox, oy) to this transform
96
-			inline void Translate(float ox, float oy);
96
+			void Translate(float ox, float oy);
97
 			// Append a scaling operation (sx, sy) to this transform
97
 			// Append a scaling operation (sx, sy) to this transform
98
-			inline void Scale(float sx, float sy);
98
+			void Scale(float sx, float sy);
99
 			// Append a shear operation (sx, sy) to this transform
99
 			// Append a shear operation (sx, sy) to this transform
100
-			inline void Shear(float sx, float sy);
100
+			void Shear(float sx, float sy);
101
 
101
 
102
-			inline void Perspective(float ox, float oy);
102
+		    void Perspective(float ox, float oy);
103
 			// Calculate the Forward Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
103
 			// Calculate the Forward Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
104
-			inline void Forward(float in_x, float in_y, float &out_x, float &out_y);
104
+			void Forward(float in_x, float in_y, float &out_x, float &out_y);
105
 			// Calculate the Inverse Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
105
 			// Calculate the Inverse Transformation of the coordinate (in_x, in_y) -> (out_x, out_y)
106
-			inline void Backward(float in_x, float in_y, float &out_x, float &out_y);
106
+			void Backward(float in_x, float in_y, float &out_x, float &out_y);
107
 			// Regenerate the Inverse Transformation
107
 			// Regenerate the Inverse Transformation
108
-			inline void Invert();
108
+			void Invert();
109
 
109
 
110
 		private:
110
 		private:
111
-			inline void Multiply();
111
+			void Multiply();
112
 			float matrix[4][3][3];
112
 			float matrix[4][3][3];
113
 			int nTargetMatrix;
113
 			int nTargetMatrix;
114
 			int nSourceMatrix;
114
 			int nSourceMatrix;
117
 
117
 
118
 	public:
118
 	public:
119
 		// Draws a sprite with the transform applied
119
 		// Draws a sprite with the transform applied
120
-		inline static void DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform);
120
+		static void DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform, bool centered = false);
121
+		static void DrawPartialSprite(olc::Sprite *sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, olc::GFX2D::Transform2D &transform, bool centered = false);
121
 	};
122
 	};
122
 }
123
 }
123
 
124
 

+ 70
- 6
pge/src/olcPGEX_Graphics2D.cpp View File

2
 
2
 
3
 namespace olc
3
 namespace olc
4
 {
4
 {
5
-	void GFX2D::DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform)
5
+	void GFX2D::DrawSprite(olc::Sprite *sprite, olc::GFX2D::Transform2D &transform, bool centered)
6
 	{
6
 	{
7
 		if (sprite == nullptr)
7
 		if (sprite == nullptr)
8
 			return;
8
 			return;
12
 		float sx, sy;		
12
 		float sx, sy;		
13
 		float px, py;
13
 		float px, py;
14
 
14
 
15
-		transform.Forward(0.0f, 0.0f, sx, sy);
15
+		float x0 = 0;
16
+		float y0 = 0;
17
+		if (centered) 
18
+		{
19
+			x0 += sprite->width / 2;
20
+			y0 += sprite->height / 2;
21
+		}
22
+
23
+		transform.Forward(-x0, -y0, sx, sy);
24
+		px = sx; py = sy;
25
+		sx = std::min(sx, px); sy = std::min(sy, py);
26
+		ex = std::max(ex, px); ey = std::max(ey, py);
27
+		
28
+		transform.Forward((float)sprite->width-x0, (float)sprite->height-y0, px, py);
29
+		sx = std::min(sx, px); sy = std::min(sy, py);
30
+		ex = std::max(ex, px); ey = std::max(ey, py);
31
+
32
+		transform.Forward(-x0, (float)sprite->height-y0, px, py);
33
+		sx = std::min(sx, px); sy = std::min(sy, py);
34
+		ex = std::max(ex, px); ey = std::max(ey, py);
35
+
36
+		transform.Forward((float)sprite->width, -y0, px, py);
37
+		sx = std::min(sx, px); sy = std::min(sy, py);
38
+		ex = std::max(ex, px); ey = std::max(ey, py);
39
+
40
+		// Perform inversion of transform if required
41
+		transform.Invert();
42
+
43
+		if (ex < sx) 
44
+			std::swap(ex, sx);
45
+		if (ey < sy) 
46
+			std::swap(ey, sy);
47
+
48
+		// Iterate through render space, and sample Sprite from suitable texel location
49
+		for (float i = sx; i < ex; i++)
50
+		{
51
+			for (float j = sy; j < ey; j++)
52
+			{
53
+				float ox, oy;
54
+				transform.Backward(i, j, ox, oy);
55
+				pge->Draw((int32_t)i, (int32_t)j, sprite->GetPixel((int32_t)(x0+ox+0.5f), (int32_t)(y0+oy+0.5f)));
56
+			}
57
+		}
58
+	}
59
+
60
+	void GFX2D::DrawPartialSprite(olc::Sprite *sprite, int32_t x0, int32_t y0, int32_t w, int32_t h, olc::GFX2D::Transform2D &transform, bool centered)
61
+	{
62
+		if (sprite == nullptr)
63
+			return;
64
+
65
+		// Work out bounding rectangle of sprite
66
+		float ex, ey;
67
+		float sx, sy;		
68
+		float px, py;
69
+
70
+		float xOff = 0;
71
+		float yOff = 0;
72
+
73
+		if (centered) 
74
+		{
75
+			xOff += w / 2;
76
+			yOff += h / 2;
77
+		}
78
+
79
+		transform.Forward(-xOff, -yOff, sx, sy);
16
 		px = sx; py = sy;
80
 		px = sx; py = sy;
17
 		sx = std::min(sx, px); sy = std::min(sy, py);
81
 		sx = std::min(sx, px); sy = std::min(sy, py);
18
 		ex = std::max(ex, px); ey = std::max(ey, py);
82
 		ex = std::max(ex, px); ey = std::max(ey, py);
19
 		
83
 		
20
-		transform.Forward((float)sprite->width, (float)sprite->height, px, py);
84
+		transform.Forward((float)w-xOff, (float)h-yOff, px, py);
21
 		sx = std::min(sx, px); sy = std::min(sy, py);
85
 		sx = std::min(sx, px); sy = std::min(sy, py);
22
 		ex = std::max(ex, px); ey = std::max(ey, py);
86
 		ex = std::max(ex, px); ey = std::max(ey, py);
23
 
87
 
24
-		transform.Forward(0.0f, (float)sprite->height, px, py);
88
+		transform.Forward(-xOff, (float)h-yOff, px, py);
25
 		sx = std::min(sx, px); sy = std::min(sy, py);
89
 		sx = std::min(sx, px); sy = std::min(sy, py);
26
 		ex = std::max(ex, px); ey = std::max(ey, py);
90
 		ex = std::max(ex, px); ey = std::max(ey, py);
27
 
91
 
28
-		transform.Forward((float)sprite->width, 0.0f, px, py);
92
+		transform.Forward((float)w, -yOff, px, py);
29
 		sx = std::min(sx, px); sy = std::min(sy, py);
93
 		sx = std::min(sx, px); sy = std::min(sy, py);
30
 		ex = std::max(ex, px); ey = std::max(ey, py);
94
 		ex = std::max(ex, px); ey = std::max(ey, py);
31
 
95
 
44
 			{
108
 			{
45
 				float ox, oy;
109
 				float ox, oy;
46
 				transform.Backward(i, j, ox, oy);
110
 				transform.Backward(i, j, ox, oy);
47
-				pge->Draw((int32_t)i, (int32_t)j, sprite->GetPixel((int32_t)(ox+0.5f), (int32_t)(oy+0.5f)));
111
+				pge->Draw((int32_t)i, (int32_t)j, sprite->GetPixel((int32_t)(xOff+x0+ox+0.5f), (int32_t)(yOff+y0+oy+0.5f)));
48
 			}
112
 			}
49
 		}
113
 		}
50
 	}
114
 	}

BIN
res/awoorwa.png View File


+ 73
- 26
src/pabloader/awoorwae.cpp View File

4
 
4
 
5
 namespace pabloader {
5
 namespace pabloader {
6
 
6
 
7
-bool Awoorwae::OnUserCreate() {
7
+bool Awoorwae::OnUserCreate()
8
+{
8
     if (!player->Load()) {
9
     if (!player->Load()) {
9
         std::cerr << "Could not load awoorwa.spr" << std::endl;
10
         std::cerr << "Could not load awoorwa.spr" << std::endl;
10
         return false;
11
         return false;
24
     return true;
25
     return true;
25
 }
26
 }
26
 
27
 
27
-Entity::Entity(Awoorwae* game_, float x_, float y_)
28
+Entity::Entity(Awoorwae* game_)
28
     : game(game_)
29
     : game(game_)
29
-    , x(x_)
30
-    , y(y_)
31
-    , xv(50)
32
-    , yv(30)
33
-    , color(0)
34
 {
30
 {
35
-    xv = 10;
36
-    yv = 10;
31
+    xv = 0;
32
+    yv = 30;
33
+    x = game->ScreenWidth() / 2;
34
+    y = game->ScreenHeight() / 2;
37
 }
35
 }
38
 
36
 
39
-olc::rcode Entity::Load() 
37
+olc::rcode Entity::Load()
40
 {
38
 {
41
     return img.LoadFromPGESprFile("res/awoorwa.spr");
39
     return img.LoadFromPGESprFile("res/awoorwa.spr");
42
 }
40
 }
43
 
41
 
44
 void Entity::Update(float dt)
42
 void Entity::Update(float dt)
45
 {
43
 {
46
-    x += dt * xv;
47
-    y += dt * yv;
44
+    x += xv * dt;
45
+    y += yv * dt;
46
+
47
+    xv *= 1 - 0.2 * dt;
48
+
49
+    if (!onGround) {
50
+        yv += 50 * dt;
51
+        yv *= 1 - 0.05 * dt;
52
+    }
53
+
54
+    transform.Reset();
55
+
56
+    game->DrawString(1, 1, "A,D - move; SPACE - jump", olc::CYAN);
57
+
58
+#ifdef _DEBUG
59
+    game->DrawString(1, 10, std::to_string(x) + " " + std::to_string(y));
60
+    game->DrawString(1, 18, std::to_string(xv) + " " + std::to_string(yv));
61
+#endif
62
+    bool userInput = false;
63
+
64
+    if (game->GetKey(olc::SPACE).bHeld && onGround) {
65
+        yv = -100;
66
+        userInput = true;
67
+    }
48
 
68
 
49
-    if (x > game->ScreenWidth() - img.width) {
50
-        xv *= -1.1;
51
-        x = game->ScreenWidth() - img.width;
69
+    if (game->GetKey(olc::A).bHeld) {
70
+        xv -= 100 * dt;
71
+        userInput = true;
52
     }
72
     }
53
 
73
 
54
-    if (x < 0) {
55
-        xv *= -1.1;
56
-        x = 0;
74
+    if (game->GetKey(olc::D).bHeld) {
75
+        xv += 100 * dt;
76
+        userInput = true;
57
     }
77
     }
58
 
78
 
59
-    if (y > game->ScreenHeight() - img.height) {
60
-        yv *= -1.1;
61
-        y = game->ScreenHeight() - img.height;
79
+    if (x > game->ScreenWidth() - img.width / 2) {
80
+        xv *= -0.3;
81
+        x = game->ScreenWidth() - img.width / 2;
62
     }
82
     }
63
 
83
 
64
-    if (y < 0) {
65
-        yv *= -1.1;
66
-        y = 0;
84
+    if (x < img.width / 2) {
85
+        xv *= -0.3;
86
+        x = img.width / 2;
67
     }
87
     }
68
-    color = fmodf(color + 256 * dt, 256);
88
+
89
+    if (y > game->ScreenHeight() - img.height / 4) {
90
+        yv *= -0.3;
91
+
92
+        if (std::abs(yv) < 2) {
93
+            yv = 0;
94
+        }
95
+        y = game->ScreenHeight() - img.height / 4;
96
+    }
97
+
98
+    onGround = y >= game->ScreenHeight() - img.height / 4;
99
+
100
+    if (!userInput && std::abs(xv) < 2) {
101
+        xv = 0;
102
+    }
103
+    if (xv < 0) {
104
+        transform.Scale(-1, 1);
105
+    }
106
+    transform.Translate(x, y);
69
 }
107
 }
70
 
108
 
71
 void Entity::Draw()
109
 void Entity::Draw()
72
 {
110
 {
73
-    game->DrawSprite((int)x, (int)y, &img);
111
+    if (std::abs(xv) < 1) {
112
+        olc::GFX2D::DrawPartialSprite(&img, 0, img.height / 2, img.width, img.height / 2, transform, true);
113
+    } else {
114
+        olc::GFX2D::DrawPartialSprite(&img, 0, 0, img.width, img.height / 2, transform, true);
115
+    }
116
+#ifdef _DEBUG
117
+    float x, y;
118
+    transform.Forward(0, 0, x, y);
119
+    game->Draw((int)x, (int)y, olc::RED);
120
+#endif
74
 }
121
 }
75
 }
122
 }

+ 7
- 8
src/pabloader/awoorwae.h View File

11
 private:
11
 private:
12
     Awoorwae* game;
12
     Awoorwae* game;
13
     olc::Sprite img;
13
     olc::Sprite img;
14
-    float x;
15
-    float y;
16
-    float xv;
17
-    float yv;
18
-    float color;
14
+    olc::GFX2D::Transform2D transform;
15
+    float x, y;
16
+    float xv, yv;
17
+    bool onGround = false;
19
 
18
 
20
 public:
19
 public:
21
-    Entity(Awoorwae* game_, float x_, float y_);
20
+    Entity(Awoorwae* game_);
22
 
21
 
23
     void Update(float dt);
22
     void Update(float dt);
24
     void Draw();
23
     void Draw();
25
-    olc::rcode Load(); 
24
+    olc::rcode Load();
26
 };
25
 };
27
 
26
 
28
 class Awoorwae : public olc::PixelGameEngine {
27
 class Awoorwae : public olc::PixelGameEngine {
33
     Awoorwae()
32
     Awoorwae()
34
     {
33
     {
35
         sAppName = "Awoorwa";
34
         sAppName = "Awoorwa";
36
-        player = new Entity(this, 128, 128);
35
+        player = new Entity(this);
37
     }
36
     }
38
 
37
 
39
     ~Awoorwae()
38
     ~Awoorwae()

Loading…
Cancel
Save