1 /// contains the simple box object class 2 module ysge.objects.simpleBox; 3 4 import ysge.project; 5 6 /// contains physics info 7 struct Physics { 8 Vec2!int velocity; 9 bool drag; 10 bool gravityOn; 11 Vec2!int gravity; 12 } 13 14 /// box object with AABB collision 15 class SimpleBox : GameObject { 16 SDL_Rect box; 17 bool physicsOn; 18 Physics physics; 19 RenderType renderType; 20 RenderValue render; 21 22 /// initialises with a box and a colour image 23 this(SDL_Rect pbox, SDL_Color colour) { 24 box = pbox; 25 renderType = RenderType.Colour; 26 render = RenderValue(colour); 27 } 28 29 /// initialises with a box and a texture 30 this(SDL_Rect pbox, SDL_Texture* texture) { 31 box = pbox; 32 renderType = RenderType.Texture; 33 render = RenderValue(texture); 34 } 35 36 /// makes the object render as a coloured box 37 void SetRenderColour(SDL_Color colour) { 38 renderType = RenderType.Colour; 39 render = RenderValue(colour); 40 } 41 42 /// makes the object render as a texture 43 void SetRenderTexture(SDL_Texture* texture) { 44 renderType = RenderType.Texture; 45 render = RenderValue(texture); 46 } 47 48 /// updates the object (physics etc) 49 override void Update(Project parent) { 50 if (physicsOn) { 51 int old; 52 53 old = box.x; 54 box.x += physics.velocity.x; 55 foreach (ref object ; parent.currentScene.objects) { 56 if (object is this) { 57 continue; 58 } 59 60 if (object.CollidesWith(this)) { 61 box.x = old; 62 physics.velocity.x = 0; 63 break; 64 } 65 } 66 67 old = box.y; 68 box.y += physics.velocity.y; 69 foreach (ref object ; parent.currentScene.objects) { 70 if (object is this) { 71 continue; 72 } 73 74 if (object.CollidesWith(this)) { 75 box.y = old; 76 physics.velocity.y = 0; 77 break; 78 } 79 } 80 81 if (physics.drag) { 82 if (physics.velocity.x > 0) { 83 -- physics.velocity.x; 84 } 85 if (physics.velocity.y > 0) { 86 -- physics.velocity.y; 87 } 88 if (physics.velocity.x < 0) { 89 ++ physics.velocity.x; 90 } 91 if (physics.velocity.y < 0) { 92 ++ physics.velocity.y; 93 } 94 } 95 96 if (physics.gravityOn) { 97 physics.velocity.x += physics.gravity.x; 98 physics.velocity.y += physics.gravity.y; 99 } 100 } 101 return; 102 } 103 104 /** 105 * move the box right while checking collision 106 * returns whether it did move 107 */ 108 bool MoveRight(Scene scene, int pixels) { 109 for (int i = 0; i < pixels; ++ i) { 110 int old = box.x; 111 ++ box.x; 112 113 foreach (ref object ; scene.objects) { 114 if (object is this) { 115 continue; 116 } 117 118 if (object.CollidesWith(this)) { 119 box.x = old; 120 return false; 121 } 122 } 123 } 124 125 return true; 126 } 127 128 /** 129 * move the box left while checking collision 130 * returns whether it did move 131 */ 132 bool MoveLeft(Scene scene, int pixels) { 133 for (int i = 0; i < pixels; ++ i) { 134 int old = box.x; 135 +--box.x; 136 137 foreach (ref object ; scene.objects) { 138 if (object is this) { 139 continue; 140 } 141 142 if (object.CollidesWith(this)) { 143 box.x = old; 144 return false; 145 } 146 } 147 } 148 149 return true; 150 } 151 152 /** 153 * move the box up while checking collision 154 * returns whether it did move 155 */ 156 bool MoveUp(Scene scene, int pixels) { 157 for (int i = 0; i < pixels; ++ i) { 158 int old = box.y; 159 -- box.y; 160 161 foreach (ref object ; scene.objects) { 162 if (object is this) { 163 continue; 164 } 165 166 if (object.CollidesWith(this)) { 167 box.y = old; 168 return false; 169 } 170 } 171 } 172 173 return true; 174 } 175 176 /** 177 * move the box down while checking collision 178 * returns whether it did move 179 */ 180 bool MoveDown(Scene scene, int pixels) { 181 for (int i = 0; i < pixels; ++ i) { 182 int old = box.y; 183 ++ box.y; 184 185 foreach (ref object ; scene.objects) { 186 if (object is this) { 187 continue; 188 } 189 190 if (object.CollidesWith(this)) { 191 box.y = old; 192 return false; 193 } 194 } 195 } 196 197 return true; 198 } 199 200 /// uses AABB to check if it collides with another box 201 override bool CollidesWith(SimpleBox other) { 202 return ( 203 (box.x < other.box.x + other.box.w) && 204 (box.x + box.w > other.box.x) && 205 (box.y < other.box.y + other.box.h) && 206 (box.y + box.h > other.box.y) 207 ); 208 } 209 210 /** 211 * renders the object 212 * should not be called by user 213 */ 214 override void Render(Project parent) { 215 SDL_Rect screenBox = box; 216 screenBox.x -= parent.currentScene.camera.x; 217 screenBox.y -= parent.currentScene.camera.y; 218 219 switch (renderType) { 220 case RenderType.Colour: { 221 SDL_SetRenderDrawColor( 222 parent.renderer, 223 render.colour.r, 224 render.colour.g, 225 render.colour.b, 226 render.colour.a 227 ); 228 SDL_RenderFillRect(parent.renderer, &screenBox); 229 break; 230 } 231 case RenderType.Texture: { 232 SDL_RenderCopy( 233 parent.renderer, render.texture, null, &screenBox 234 ); 235 break; 236 } 237 default: assert(0); 238 } 239 } 240 }