ソースを参照

Bouncing ball controlled with keyboard

Pabloader 5年前
コミット
5c0574ded5
6個のファイルの変更164行の追加53行の削除
  1. 1
    1
      Makefile
  2. 13
    12
      pge/include/olcPGEX_Graphics2D.h
  3. 70
    6
      pge/src/olcPGEX_Graphics2D.cpp
  4. バイナリ
      res/awoorwa.png
  5. 73
    26
      src/pabloader/awoorwae.cpp
  6. 7
    8
      src/pabloader/awoorwae.h

+ 1
- 1
Makefile ファイルの表示

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

+ 13
- 12
pge/include/olcPGEX_Graphics2D.h ファイルの表示

@@ -85,30 +85,30 @@ namespace olc
85 85
 		class Transform2D
86 86
 		{
87 87
 		public:
88
-			inline Transform2D();
88
+			Transform2D();
89 89
 
90 90
 		public:
91 91
 			// Set this transformation to unity
92
-			inline void Reset();
92
+			void Reset();
93 93
 			// Append a rotation of fTheta radians to this transform
94
-			inline void Rotate(float fTheta);
94
+			void Rotate(float fTheta);
95 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 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 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 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 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 107
 			// Regenerate the Inverse Transformation
108
-			inline void Invert();
108
+			void Invert();
109 109
 
110 110
 		private:
111
-			inline void Multiply();
111
+			void Multiply();
112 112
 			float matrix[4][3][3];
113 113
 			int nTargetMatrix;
114 114
 			int nSourceMatrix;
@@ -117,7 +117,8 @@ namespace olc
117 117
 
118 118
 	public:
119 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 ファイルの表示

@@ -2,7 +2,7 @@
2 2
 
3 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 7
 		if (sprite == nullptr)
8 8
 			return;
@@ -12,20 +12,84 @@ namespace olc
12 12
 		float sx, sy;		
13 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 80
 		px = sx; py = sy;
17 81
 		sx = std::min(sx, px); sy = std::min(sy, py);
18 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 85
 		sx = std::min(sx, px); sy = std::min(sy, py);
22 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 89
 		sx = std::min(sx, px); sy = std::min(sy, py);
26 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 93
 		sx = std::min(sx, px); sy = std::min(sy, py);
30 94
 		ex = std::max(ex, px); ey = std::max(ey, py);
31 95
 
@@ -44,7 +108,7 @@ namespace olc
44 108
 			{
45 109
 				float ox, oy;
46 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
 	}

バイナリ
res/awoorwa.png ファイルの表示


+ 73
- 26
src/pabloader/awoorwae.cpp ファイルの表示

@@ -4,7 +4,8 @@
4 4
 
5 5
 namespace pabloader {
6 6
 
7
-bool Awoorwae::OnUserCreate() {
7
+bool Awoorwae::OnUserCreate()
8
+{
8 9
     if (!player->Load()) {
9 10
         std::cerr << "Could not load awoorwa.spr" << std::endl;
10 11
         return false;
@@ -24,52 +25,98 @@ bool Awoorwae::OnUserUpdate(float fElapsedTime)
24 25
     return true;
25 26
 }
26 27
 
27
-Entity::Entity(Awoorwae* game_, float x_, float y_)
28
+Entity::Entity(Awoorwae* game_)
28 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 39
     return img.LoadFromPGESprFile("res/awoorwa.spr");
42 40
 }
43 41
 
44 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 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 ファイルの表示

@@ -11,18 +11,17 @@ class Entity {
11 11
 private:
12 12
     Awoorwae* game;
13 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 19
 public:
21
-    Entity(Awoorwae* game_, float x_, float y_);
20
+    Entity(Awoorwae* game_);
22 21
 
23 22
     void Update(float dt);
24 23
     void Draw();
25
-    olc::rcode Load(); 
24
+    olc::rcode Load();
26 25
 };
27 26
 
28 27
 class Awoorwae : public olc::PixelGameEngine {
@@ -33,7 +32,7 @@ public:
33 32
     Awoorwae()
34 33
     {
35 34
         sAppName = "Awoorwa";
36
-        player = new Entity(this, 128, 128);
35
+        player = new Entity(this);
37 36
     }
38 37
 
39 38
     ~Awoorwae()

読み込み中…
キャンセル
保存