liblashgame

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

slopejump.cpp (7173B)


      1 // Physics slope experiment with lash_game_sprite
      2 
      3 #include "SDL.h"
      4 #include "SDL_gfxPrimitives.h"
      5 #include "../lash_game_sprite.h"
      6 #include <math.h>
      7 #include <stdio.h>
      8 
      9 #define SCREEN_WIDTH 800
     10 #define SCREEN_HEIGHT 600
     11 #define BALL_RADIUS 30
     12 #define BPP 32
     13 #define FPS 60
     14 #define GRAVITY 9.8
     15 #define PIXELS_METER 100
     16 
     17 int main(int argc, char *argv[]) {	
     18 
     19 	int i;
     20 	
     21 	unsigned long frametime;
     22 	unsigned long lastframetime;
     23 	float minframetime = 1000 / (float)FPS;	
     24 	int run = 1;
     25 	int state = 0;
     26 
     27 	Lash_Sprite_2D_Simple *sprite;
     28 	
     29 	SDL_Event event;
     30 	SDL_Surface *screen;
     31 
     32 	SDL_Rect screen_r;
     33 	//SDL_Rect ball_r;
     34 
     35 	uint32_t screen_c;
     36 	//uint32_t ball_c;
     37 	//uint32_t slope_c;
     38 	
     39 	//uint32_t ball_slope_offset_y;
     40 	float p_ball_force_net;
     41 	float p_ball_force_norm;
     42 	float slope_friction;
     43 	
     44 	float slope_angle;
     45 	
     46 	uint8_t slope_v_size = 7;
     47 	Sint16 *slope_v_x;
     48 	Sint16 *slope_v_y;
     49 	
     50 	float ballxinit;
     51 	float ballyinit;
     52 	
     53 	float groundy;
     54 	float jumpwidth;
     55 	
     56 	char debugstring[255];
     57 	unsigned int framesrun;
     58 	unsigned long timestart;
     59 	float *debugframevels;
     60 	
     61 	if (argc < 3) {
     62 		printf("Usage: %s slope_angle_in_degrees ball_mass_in_grammes slope_friction_coeffcient\n", argv[0]);
     63 		return 1;
     64 	}
     65 	
     66 	
     67 	sprite = new Lash_Sprite_2D_Simple(BALL_RADIUS * 2, BALL_RADIUS * 2, 0.f, 0.f);
     68 	sprite->setMass(atof(argv[2]));
     69 
     70 	//radians
     71 	slope_angle = (atof(argv[1]) * M_PI) / 180;
     72 	slope_friction = atof(argv[3]);
     73 	if (!slope_friction)
     74 		slope_friction = 0.f;
     75 	
     76 	SDL_Init(SDL_INIT_VIDEO);
     77 	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, BPP, SDL_HWSURFACE|SDL_DOUBLEBUF);
     78 	
     79 	if (screen == NULL)	
     80 		return 1;
     81 		
     82 	slope_v_x = (Sint16*)malloc(sizeof(Sint16)*slope_v_size);
     83 	slope_v_y = (Sint16*)malloc(sizeof(Sint16)*slope_v_size);
     84 
     85 	if (slope_v_x == NULL || slope_v_y == NULL)
     86 		return 1;
     87 	
     88 	debugframevels = (float*)malloc(sizeof(float) * 10000); // should be ample
     89 
     90 	screen_r.x = 0;
     91 	screen_r.y = 0;
     92 	screen_r.w = SCREEN_WIDTH;
     93 	screen_r.h = SCREEN_HEIGHT;
     94 	
     95 	//ball_r.x = 0;
     96 	//ball_r.y = 0;
     97 	//ball_r.w = BALL_RADIUS * 2;
     98 	//ball_r.h = BALL_RADIUS * 2;
     99 	
    100 	screen_c = SDL_MapRGBA(screen->format, 255, 255, 255, 255);
    101 	//slope_c = SDL_MapRGBA(screen->format, 0, 0, 255, 255);
    102 	//ball_c = SDL_MapRGBA(screen->format, 255, 0, 0, 255);
    103 
    104 	groundy = SCREEN_HEIGHT * 0.75;
    105 	jumpwidth = SCREEN_WIDTH / 12.f;
    106 	
    107 	*slope_v_y = SCREEN_HEIGHT;
    108 	*(slope_v_y + 1) = (SCREEN_HEIGHT / 2) - ((SCREEN_WIDTH / 4) * tan(slope_angle));
    109 	*(slope_v_y + 2) = SCREEN_HEIGHT / 2;
    110 	*(slope_v_y + 3) = (SCREEN_HEIGHT / 2) - (jumpwidth * tan(slope_angle));
    111 	*(slope_v_y + 4) = groundy;
    112 	*(slope_v_y + 5) = groundy;
    113 	*(slope_v_y + 6) = SCREEN_HEIGHT;
    114 	
    115 	*slope_v_x = 0;
    116 	*(slope_v_x + 1) = 0;
    117 	*(slope_v_x + 2) = SCREEN_WIDTH / 4;
    118 	*(slope_v_x + 3) = (SCREEN_WIDTH / 4) + jumpwidth;
    119 	*(slope_v_x + 4) = (SCREEN_WIDTH / 4) + jumpwidth;
    120 	*(slope_v_x + 5) = SCREEN_WIDTH;
    121 	*(slope_v_x + 6) = SCREEN_WIDTH;
    122 	
    123 	ballxinit = BALL_RADIUS;
    124 	ballyinit = (BALL_RADIUS / cos(slope_angle));
    125 	sprite->setY((int)((tan(slope_angle) * BALL_RADIUS) + *(slope_v_y + 1) - ballyinit));
    126 	sprite->setX((int)ballxinit);
    127 	
    128 	p_ball_force_net = sin(slope_angle) * (GRAVITY * sprite->getMass());
    129 	p_ball_force_norm = cos(slope_angle) * (GRAVITY * sprite->getMass());
    130 	if (p_ball_force_net < 0.f)
    131 		p_ball_force_net = 0.f;
    132 	
    133 	// divide by FPS twice, as it's m/s²
    134 	sprite->setAcceleration((((p_ball_force_net / sprite->getMass()) * PIXELS_METER) / FPS) / FPS, -slope_angle);
    135 	// resistance is friction translated to m/s
    136 	sprite->setResistance(((p_ball_force_norm / sprite->getMass()) * slope_friction) / FPS);
    137 
    138 	float tmpav, tmpar;
    139 	sprite->getAcceleration(&tmpav, &tmpar, 0);
    140 	printf("FPS: %d\nPixels per meter: %d\nSprite: x %.1fpx, y %.1fpx, mass %.2fkg\nSlope: angle %f, resistance %fm/s, distance %f\nObject force %.2fN, accel: %f m/s/s | %f px/frame, radians %f\n", FPS, PIXELS_METER, sprite->getX(), sprite->getY(), sprite->getMass(), slope_angle, sprite->getResistance(), SCREEN_WIDTH / cos(slope_angle), p_ball_force_net, ((float)p_ball_force_net / sprite->getMass()), tmpav * FPS, tmpar);
    141 		
    142 	SDL_WM_SetCaption("Slope Physics Test", 0);
    143 	
    144 	while (run) {
    145 
    146 		frametime = SDL_GetTicks();
    147 
    148 		while (SDL_PollEvent(&event)) {
    149 			switch(event.type) {
    150 				case SDL_KEYDOWN:
    151 					if (event.key.keysym.sym == SDLK_ESCAPE) {
    152 						run = 0;
    153 					} else if (event.key.keysym.sym == SDLK_SPACE) {
    154 						sprite->walkRight();
    155 						framesrun = 0;
    156 						timestart = frametime;
    157 					} else if (event.key.keysym.sym == SDLK_r) {
    158 						sprite->stop();
    159 						sprite->setVel(0.f, 0.f);
    160 						sprite->setY((int)((tan(slope_angle) * BALL_RADIUS) + *(slope_v_y + 1) - ballyinit));
    161 						sprite->setX((int)ballxinit);
    162 						sprite->setAcceleration((((p_ball_force_net / sprite->getMass()) * PIXELS_METER) / FPS) / FPS, -slope_angle);
    163 						state = 0;
    164 					}
    165 
    166 					break;
    167 			}
    168 
    169 		}
    170 			
    171 		if (sprite->isWalking(0)) {
    172 			
    173 			sprite->move();			
    174 			
    175 			// enter jump
    176 			if (sprite->getX() > SCREEN_WIDTH / 4 && state < 1) {
    177 				sprite->setVel(sprite->getVel(), slope_angle);
    178 				sprite->setAcceleration((((p_ball_force_net / sprite->getMass()) * PIXELS_METER) / FPS) / FPS, slope_angle - M_PI);
    179 				state = 1;
    180 			}
    181 			else if (sprite->getX() > (SCREEN_WIDTH / 4) + jumpwidth && state < 2) {
    182 				sprite->setAcceleration(((GRAVITY * PIXELS_METER) / FPS )/ FPS, 3 * (M_PI_2));
    183 				sprite->setResistance(0.f);
    184 				state = 2;
    185 			// land
    186 			} else if (sprite->getX() > SCREEN_WIDTH * (5 / 12.f) && sprite->getY() >= groundy && state < 3) {
    187 				sprite->addVel(sprite->getVelY(), M_PI_2);
    188 				sprite->setAcceleration(0.f, 0.f);
    189 				sprite->setResistance(((p_ball_force_norm / sprite->getMass()) * slope_friction) / FPS);
    190 				sprite->setY(groundy - BALL_RADIUS);
    191 				state = 3;
    192 			}
    193 			
    194 			sprite->accelerate();
    195 			
    196 			if (sprite->getY() >= SCREEN_HEIGHT - BALL_RADIUS || sprite->getX() >= SCREEN_WIDTH - BALL_RADIUS || sprite->getVel() == 0.f) {
    197 				if (sprite->getY() >= SCREEN_HEIGHT - BALL_RADIUS || sprite->getX() >= SCREEN_WIDTH - BALL_RADIUS) {
    198 					sprite->setX(SCREEN_WIDTH - BALL_RADIUS);
    199 				}
    200 				sprite->stop();
    201 				printf("End velocity: %f px/frame (%f m/s) after %.2f secs, %d frames. \n---\nVels:\n", *(debugframevels + framesrun - 1), ((*(debugframevels + framesrun - 1) / PIXELS_METER) * FPS), (frametime - timestart) / (float)1000, framesrun);
    202 				
    203 				if (debugframevels != NULL) {
    204 					for (i = 0; i < (int)framesrun; i++) {
    205 						printf("Frame %d: %f\n", i, *(debugframevels+i));
    206 					}
    207 				}
    208 			}
    209 			
    210 			if (debugframevels != NULL)
    211 				*(debugframevels + framesrun) = sprite->getVel();
    212 			framesrun++;
    213 			
    214 		}
    215 		
    216 		sprintf(debugstring, "Frametime %lu", frametime - lastframetime);
    217 		SDL_FillRect(screen, &screen_r, screen_c);
    218 		filledPolygonColor(screen, slope_v_x, slope_v_y, slope_v_size, 0x0000ffff);
    219 		filledCircleColor(screen, sprite->getXPixels(), sprite->getYPixels(), BALL_RADIUS, 0xff0000ff);
    220 		stringColor(screen, 10, SCREEN_HEIGHT - 15, debugstring, 0xffffff99);
    221 		SDL_Flip(screen);
    222 		
    223 		lastframetime = frametime;
    224 		
    225 		//if (lastframetime - frametime < minframetime)
    226 			//SDL_Delay (minframetime - (SDL_GetTicks () - frametime));
    227 		SDL_Delay(minframetime);
    228 		
    229 		
    230 	}
    231 	
    232 	delete(sprite);
    233 	SDL_FreeSurface(screen);
    234 	SDL_Quit();
    235 	
    236 	return 0;
    237 }