liblashgame

Pathfinder and path decision making library for 2D tile game
git clone git://holbrook.no/liblashgame.git
Info | Log | Files | Refs

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 }