lash_game_sprite.cpp (9214B)
1 #include <stdint.h> 2 #include <string.h> 3 #include <stdio.h> 4 #include <math.h> 5 #include "lash_game_sprite.h" 6 #include "liblashgame/lash_game_standard.h" 7 8 /// \todo allow velocity formulas for arcs, circle, bezier 9 /// \todo flip friction modifiers for negative acceleration 10 11 Lash_Sprite_2D_Simple::Lash_Sprite_2D_Simple() { 12 } 13 14 Lash_Sprite_2D_Simple::Lash_Sprite_2D_Simple(const uint32_t initw, const uint32_t inith, const float inita, const float inca) { 15 init(initw, inith, inita, inca); 16 } 17 18 int Lash_Sprite_2D_Simple::init(const uint32_t initw, const uint32_t inith, const float inita, const float inca) { 19 h = inith; 20 w = initw; 21 clear(); 22 a_init = inita; 23 a = inca; 24 return 0; 25 } 26 27 void Lash_Sprite_2D_Simple::clear() { 28 coords.x = 0.f; 29 coords.y = 0.f; 30 v = 0.f; 31 rv = 0.f; 32 ra = 0.f; 33 m = 0.f; 34 f = 0.f; 35 state = LASH_GAME_SPRITE_SIMPLE_STATE_STILL; 36 } 37 38 int32_t Lash_Sprite_2D_Simple::getXPixels() { 39 return round(coords.x); 40 } 41 42 float Lash_Sprite_2D_Simple::getX() { 43 return coords.x; 44 } 45 46 void Lash_Sprite_2D_Simple::setX(const int32_t newx) { 47 coords.x = (float)newx; 48 } 49 50 void Lash_Sprite_2D_Simple::setX(const float newx) { 51 coords.x = newx; 52 } 53 54 int32_t Lash_Sprite_2D_Simple::getYPixels() { 55 return round(coords.y); 56 } 57 58 float Lash_Sprite_2D_Simple::getY() { 59 return coords.y; 60 } 61 62 void Lash_Sprite_2D_Simple::setY(const int32_t newy) { 63 coords.y = (float)newy; 64 } 65 66 void Lash_Sprite_2D_Simple::setY(const float newy) { 67 coords.y = newy; 68 } 69 70 int32_t Lash_Sprite_2D_Simple::getW() { 71 return w; 72 } 73 74 int32_t Lash_Sprite_2D_Simple::getH() { 75 return h; 76 } 77 78 void Lash_Sprite_2D_Simple::setResistance(float newf) { 79 f = newf; 80 } 81 82 float Lash_Sprite_2D_Simple::getResistance() { 83 return f; 84 } 85 86 void Lash_Sprite_2D_Simple::setAccelerationX(float newa) { 87 if (newa < 0) { 88 a = -newa; 89 ra = M_PI; 90 } else { 91 a = newa; 92 ra = 0.f; 93 } 94 } 95 96 void Lash_Sprite_2D_Simple::setAccelerationY(float newa) { 97 if (newa < 0) { 98 a = -newa; 99 ra = M_PI_2; 100 } else { 101 a = newa; 102 ra = 3 * M_PI_2; 103 } 104 } 105 106 void Lash_Sprite_2D_Simple::setAcceleration(float newa, float newr) { 107 a = newa; 108 ra = newr; 109 } 110 111 void Lash_Sprite_2D_Simple::addAcceleration(float inca, float r) { 112 float newx = (cos(ra) * a) + (cos(r) * inca); 113 float newy = (-sin(ra) * a) + (sin(r) * inca); 114 ra = atan2(newy, newx); 115 a = sqrt(pow(newx,2) + pow(newy,2)); 116 } 117 118 void Lash_Sprite_2D_Simple::addAccelerationX(float inca) { 119 float newx = (cos(ra) * a) + inca; 120 float newy = (sin(ra) * a); 121 ra = atan2(-newy, newx); 122 a = sqrt(pow(newx,2) + pow(newy,2)); 123 } 124 125 void Lash_Sprite_2D_Simple::addAccelerationY(float inca) { 126 float newx = (cos(ra) * a); 127 float newy = (sin(ra) * a) + inca; 128 ra = atan2(-newy, newx); 129 a = sqrt(pow(newx,2) + pow(newy,2)); 130 } 131 132 void Lash_Sprite_2D_Simple::getAcceleration(float *vslot, float *rslot, int noresistance) { 133 if (noresistance) 134 *vslot = a; 135 else 136 *vslot = a - f; 137 *rslot = lashNormalizeRadians(ra); 138 } 139 140 float Lash_Sprite_2D_Simple::getAccelerationX(int noresistance) { 141 if (noresistance) 142 return cos(ra) * a; 143 return cos(ra) * (a - f); 144 } 145 146 float Lash_Sprite_2D_Simple::getAccelerationY(int noresistance) { 147 if (noresistance) 148 return sin(ra) * a; 149 return sin(ra) * (a - f); 150 } 151 152 float Lash_Sprite_2D_Simple::getAccelerationRadians() { 153 return ra; 154 } 155 156 void Lash_Sprite_2D_Simple::setVel(float newv, float newr) { 157 v = newv; 158 rv = newr; 159 } 160 161 void Lash_Sprite_2D_Simple::setVelX(float newvx, int keepy = 0) { 162 if (keepy) { 163 float oldvy = getVelY(); 164 v = sqrt(pow(newvx, 2) + pow(oldvy, 2)); 165 rv = atan(oldvy / newvx); 166 } else { 167 if (newvx < 0) { 168 v = -newvx; 169 rv = M_PI; 170 } else { 171 v = newvx; 172 rv = 0.f; 173 } 174 } 175 } 176 177 void Lash_Sprite_2D_Simple::addVel(float incv, float r) { 178 float newx = (cos(rv) * v) + (cos(r) * incv); 179 //float newy = (-sin(rv) * v) + (sin(r) * incv); 180 float newy = (sin(rv) * v) + (sin(r) * incv); 181 rv = atan2(newy, newx); 182 v = sqrt(pow(newx,2) + pow(newy,2)); 183 } 184 185 float Lash_Sprite_2D_Simple::getVel() { 186 return v; 187 } 188 189 void Lash_Sprite_2D_Simple::getVel(float *retv, float *retr) { 190 *retv = v; 191 *retr = lashNormalizeRadians(rv); 192 } 193 194 float Lash_Sprite_2D_Simple::getVelRadians() { 195 return rv; 196 } 197 198 float Lash_Sprite_2D_Simple::getVelX() { 199 return cos(rv) * v; 200 } 201 202 void Lash_Sprite_2D_Simple::setVelY(float newvy, int keepx = 0) { 203 if (keepx) { 204 float oldvx = getVelX(); 205 v = sqrt(pow(oldvx, 2) + pow(newvy, 2)); 206 rv = atan(-newvy / oldvx); 207 } else { 208 if (newvy < 0) { 209 v = -newvy; 210 rv = M_PI_2; 211 } else { 212 v = newvy; 213 rv = 3 * M_PI_2; 214 } 215 } 216 } 217 218 float Lash_Sprite_2D_Simple::getVelY() { 219 return sin(rv) * v; 220 } 221 222 void Lash_Sprite_2D_Simple::setMass(float newm) { 223 m = newm; 224 } 225 226 float Lash_Sprite_2D_Simple::getMass() { 227 return m; 228 } 229 230 int32_t Lash_Sprite_2D_Simple::getNextXPixels() { 231 return (int32_t)(coords.x + (cos(rv) * v)); 232 } 233 234 float Lash_Sprite_2D_Simple::getNextX() { 235 return coords.x + (cos(rv) * v); 236 } 237 238 int32_t Lash_Sprite_2D_Simple::getNextYPixels() { 239 return (int32_t)(coords.y + (sin(rv) * v)); 240 } 241 242 float Lash_Sprite_2D_Simple::getNextY() { 243 return coords.y + (sin(rv) * v); 244 } 245 246 void Lash_Sprite_2D_Simple::move() { 247 coords.x += cos(rv) * v; 248 coords.y += -sin(rv) * v; 249 } 250 251 void Lash_Sprite_2D_Simple::moveX() { 252 coords.x += cos(rv) * v; 253 } 254 255 void Lash_Sprite_2D_Simple::moveY() { 256 coords.y += -sin(rv) * v; 257 } 258 259 void Lash_Sprite_2D_Simple::moveBy(const lash_game_coords_float_t addcoords) { 260 coords.x += addcoords.x; 261 coords.y += addcoords.y; 262 } 263 264 void Lash_Sprite_2D_Simple::moveBy(float m, float r) { 265 coords.x += cos(r) * m; 266 coords.y += -sin(r) * m; 267 } 268 269 void Lash_Sprite_2D_Simple::accelerate() { 270 /*if (state & LASH_GAME_SPRITE_SIMPLE_STATE_LEFT || state & LASH_GAME_SPRITE_SIMPLE_STATE_RIGHT) { 271 if (vx < 0.f) 272 vx -= ax; 273 else 274 vx += ax; 275 } 276 if (state & LASH_GAME_SPRITE_SIMPLE_STATE_UP || state & LASH_GAME_SPRITE_SIMPLE_STATE_DOWN) { 277 if (vy < 0.f) 278 vy -= ay; 279 else 280 vy += ay; 281 }*/ 282 283 284 //double newvx = (cos(ra) * (a - (cos(ra) * f))) + (cos(rv) * v); 285 //double newvy = (sin(ra) * (a - (sin(ra) * f))) + (sin(rv) * v); 286 double newvx = (cos(ra) * a) + (cos(rv) * v); 287 double newvy = (sin(ra) * a) + (sin(rv) * v); 288 rv = atan2(newvy, newvx); 289 v = sqrt(pow(newvx, 2) + pow(newvy, 2)); 290 v -= f; 291 292 // if the only force acting is friction 293 if ((a == 0.f || a - f < 0.f) && v <= 0.f) { 294 v = 0.f; 295 return; 296 } 297 } 298 299 void Lash_Sprite_2D_Simple::still() { 300 state &= 0; 301 state |= LASH_GAME_SPRITE_SIMPLE_STATE_STILL; 302 } 303 304 int Lash_Sprite_2D_Simple::walkLeft(int resetvelocity) { 305 // check if one can walk, return 1 if not 306 state &= ~255; 307 state |= LASH_GAME_SPRITE_SIMPLE_STATE_LEFT; 308 state |= LASH_GAME_SPRITE_SIMPLE_STATE_WALKING; 309 if (resetvelocity) { 310 v = a_init; 311 rv = M_PI; 312 } 313 return 0; 314 } 315 316 int Lash_Sprite_2D_Simple::walkRight(int resetvelocity) { 317 // check if one can walk, return 1 if not 318 state &= ~255; 319 state |= LASH_GAME_SPRITE_SIMPLE_STATE_RIGHT; 320 state |= LASH_GAME_SPRITE_SIMPLE_STATE_WALKING; 321 if (resetvelocity) { 322 v = a_init; 323 rv = 0.f; 324 } 325 return 0; 326 } 327 328 void Lash_Sprite_2D_Simple::stop() { 329 state &= ~254; 330 state &= ~(255 << 8); 331 } 332 333 334 int Lash_Sprite_2D_Simple::jump() { 335 if (!isJumping()) { 336 state |= (LASH_GAME_SPRITE_SIMPLE_STATE_ENTERING | LASH_GAME_SPRITE_SIMPLE_STATE_JUMPING); 337 return 0; 338 } 339 return 1; 340 } 341 342 int Lash_Sprite_2D_Simple::bounce() { 343 if (!isBouncing()) { 344 state &= ~(255 << 24); 345 state |= LASH_GAME_SPRITE_SIMPLE_STATE_REBOUNDING; 346 return 0; 347 } 348 return 1; 349 } 350 351 void Lash_Sprite_2D_Simple::land() { 352 state &= ~(255 << 24); 353 state |= LASH_GAME_SPRITE_SIMPLE_STATE_EXITING; 354 } 355 356 void Lash_Sprite_2D_Simple::finish() { 357 state &= ~(255 << 24); 358 } 359 360 int Lash_Sprite_2D_Simple::isJumping() { 361 return state & LASH_GAME_SPRITE_SIMPLE_STATE_JUMPING; 362 } 363 364 int Lash_Sprite_2D_Simple::isBouncing() { 365 return state & LASH_GAME_SPRITE_SIMPLE_STATE_BOUNCING; 366 } 367 368 int Lash_Sprite_2D_Simple::isWalking(uint8_t direction = 0) { 369 uint32_t cmp = 0; 370 cmp |= LASH_GAME_SPRITE_SIMPLE_STATE_WALKING; 371 switch (direction) { 372 case LASH_GAME_SPRITE_SIMPLE_STATE_LEFT: 373 cmp |= direction; 374 break; 375 case LASH_GAME_SPRITE_SIMPLE_STATE_RIGHT: 376 cmp |= direction; 377 break; 378 case LASH_GAME_SPRITE_SIMPLE_STATE_UP: 379 cmp |= direction; 380 break; 381 case LASH_GAME_SPRITE_SIMPLE_STATE_DOWN: 382 cmp |= direction; 383 break; 384 default: 385 if (state & cmp) 386 return 1; 387 } 388 389 return state == cmp; 390 } 391 392 void Lash_Sprite_2D_Simple::_old_land() { 393 // remove all movement types (bytes 2 and 3) 394 /*state &= ~(LASH_GAME_SPRITE_SIMPLE_STATE_RUNNING | 395 LASH_GAME_SPRITE_SIMPLE_STATE_CROUCHING | 396 LASH_GAME_SPRITE_SIMPLE_STATE_CRAWLING | 397 LASH_GAME_SPRITE_SIMPLE_STATE_JUMPING | 398 LASH_GAME_SPRITE_SIMPLE_STATE_FLYING | 399 LASH_GAME_SPRITE_SIMPLE_STATE_SWIMMING | 400 LASH_GAME_SPRITE_SIMPLE_STATE_CLIMBING | 401 LASH_GAME_SPRITE_SIMPLE_STATE_IMMERSED | 402 LASH_GAME_SPRITE_SIMPLE_STATE_ENTERING | 403 LASH_GAME_SPRITE_SIMPLE_STATE_NOCONTROL | 404 LASH_GAME_SPRITE_SIMPLE_STATE_REBOUNDING);*/ 405 state &= ~((255 + (255 << 8)) << 8); 406 state |= LASH_GAME_SPRITE_SIMPLE_STATE_EXITING; 407 408 } 409 410 // temporary function for debug 411 void Lash_Sprite_2D_Simple::dumpState(char bitstring[]) { 412 unsigned int i; 413 unsigned int skew = 0; 414 for (i = 0; i < sizeof(uint32_t) * 8; i++) { 415 if (!(i % 8) && i > 0) { 416 sprintf(bitstring+skew+i, " "); 417 skew++; 418 } 419 sprintf(bitstring+skew+i, "%d", state >> i & 1); 420 } 421 strcat(bitstring, "\0"); 422 }