void sea_event(SDL_Event event) { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); camera_control_orbit(cam, event); switch(event.type){ case SDL_KEYUP: if (event.key.keysym.sym == SDLK_SPACE) { //char ball_name[20]; //sprintf(ball_name, "ball_%i", ball_count); //ball_count++; //physics_object* ball = entity_new(ball_name, physics_object); //ball->renderable = asset_get(P("./resources/ball.obj")); //ball->collision_body = collision_body_new_sphere(sphere_new(v3_zero(), 1)); //ball->position = cam->position; //ball->scale = v3(0.5, 0.5, 0.5); //ball->velocity = v3_mul(v3_normalize(v3_sub(cam->target, cam->position)), 75); } case SDL_MOUSEMOTION: mouse_x = event.motion.xrel; mouse_y = event.motion.yrel; break; } }
void scotland_event(SDL_Event event) { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); switch(event.type){ case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_w) { w_held = true; } if (event.key.keysym.sym == SDLK_a) { a_held = true; } if (event.key.keysym.sym == SDLK_s) { s_held = true; } if (event.key.keysym.sym == SDLK_d) { d_held = true; } break; case SDL_KEYUP: if (event.key.keysym.sym == SDLK_w) { w_held = false; } if (event.key.keysym.sym == SDLK_a) { a_held = false; } if (event.key.keysym.sym == SDLK_s) { s_held = false; } if (event.key.keysym.sym == SDLK_d) { d_held = false; } break; case SDL_MOUSEBUTTONDOWN: break; case SDL_MOUSEBUTTONUP: break; case SDL_MOUSEMOTION: mouse_x = event.motion.xrel; mouse_y = event.motion.yrel; break; } }
void sea_render() { static_object* s_seaplane = entity_get("seaplane"); static_object* s_skydome = entity_get("skydome"); static_object* s_corvette = entity_get("corvette"); light* sun = entity_get("sun"); light* backlight = entity_get("backlight"); shadow_mapper_begin(); shadow_mapper_render_static(s_corvette); shadow_mapper_end(); forward_renderer_begin(); forward_renderer_render_static(s_skydome); forward_renderer_render_static(s_seaplane); forward_renderer_render_static(s_corvette); physics_object* balls[100]; int num_balls; entities_get(balls, &num_balls, physics_object); for(int i = 0; i < num_balls; i++) { //forward_renderer_render_physics(balls[i]); } //static_object* center_sphere = entity_get("center_sphere"); //forward_renderer_render_static(center_sphere); forward_renderer_render_light(sun); forward_renderer_render_light(backlight); forward_renderer_end(); }
static void toggle_freecam(ui_button* b, SDL_Event event) { if (event.type == SDL_MOUSEBUTTONDOWN) { if (ui_button_contains_position(b, vec2_new(event.motion.x, event.motion.y))) { b->pressed = true; } } else if (event.type == SDL_MOUSEBUTTONUP) { if (b->pressed) { b->pressed = false; freecam = !freecam; camera* cam = entity_get("camera"); landscape* world = entity_get("world"); vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position)); float height = terrain_height(asset_hndl_ptr(world->terrain), vec2_new(cam->position.x, cam->position.z)); cam->position.y = height + 1; cam->target = vec3_add(cam->position, cam_dir); } } }
void scotland_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); static_object* skydome = entity_get("skydome"); landscape* world = entity_get("world"); sun_orbit += frame_time() * 0.01; sun->position.x = 512 + sin(sun_orbit) * 512; sun->position.y = cos(sun_orbit) * 512; sun->position.z = 512; sun->target = vec3_new(512, 0, 512); if (w_held || s_held) { vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position)); float speed = 0.5; if (!freecam) speed = 0.05; if (w_held) { cam->position = vec3_add(cam->position, vec3_mul(cam_dir, speed)); } if (s_held) { cam->position = vec3_sub(cam->position, vec3_mul(cam_dir, speed)); } if (!freecam) { float height = terrain_height(asset_hndl_ptr(world->terrain), vec2_new(cam->position.x, cam->position.z)); cam->position.y = height + 1; } cam->target = vec3_add(cam->position, cam_dir); } Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)){ float a1 = -(float)mouse_x * 0.005; float a2 = (float)mouse_y * 0.005; vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position)); cam_dir.y += -a2; vec3 side_dir = vec3_normalize(vec3_cross(cam_dir, vec3_new(0,1,0))); cam_dir = vec3_add(cam_dir, vec3_mul(side_dir, -a1)); cam_dir = vec3_normalize(cam_dir); cam->target = vec3_add(cam->position, cam_dir); } mouse_x = 0; mouse_y = 0; ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); }
void sea_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); wave_time += frame_time(); static_object* corvette = entity_get("corvette"); corvette->position.y = (sin(wave_time) + 1) / 2; corvette->rotation = v4_quaternion_pitch(sin(wave_time * 1.123) / 50); corvette->rotation = v4_quaternion_mul(corvette->rotation, v4_quaternion_yaw(sin(wave_time * 1.254) / 25)); corvette->rotation = v4_quaternion_mul(corvette->rotation, v4_quaternion_roll(sin(wave_time * 1.355) / 100)); static_object* center_sphere = entity_get("center_sphere"); physics_object* balls[100]; int num_balls; entities_get(balls, &num_balls, physics_object); for(int i = 0; i < num_balls; i++) { physics_object_collide_static(balls[i], center_sphere, frame_time()); physics_object_collide_static(balls[i], corvette, frame_time()); physics_object_update(balls[i], frame_time()); } Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)) { float a1 = -(float)mouse_x * 0.01; float a2 = (float)mouse_y * 0.01; cam->position = v3_sub(cam->position, cam->target); cam->position = m33_mul_v3(m33_rotation_y( a1 ), cam->position ); cam->position = v3_add(cam->position, cam->target); cam->position = v3_sub(cam->position, cam->target); vector3 rotation_axis = v3_normalize(v3_cross( v3_sub(cam->position, v3_zero()) , v3(0,1,0) )); cam->position = m33_mul_v3(m33_rotation_axis_angle(rotation_axis, a2 ), cam->position ); cam->position = v3_add(cam->position, cam->target); } if(keystate & SDL_BUTTON(3)) { sun->position.x += (float)mouse_y / 2; sun->position.z -= (float)mouse_x / 2; } mouse_x = 0; mouse_y = 0; ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); }
static void reset_game() { /* Set the starting level to demo.level */ current_level = asset_get(P("./levels/demo.level")); level_score = 0; level_time = 0.0; /* New main character entity */ character* main_char = entity_get("main_char"); main_char->position = vec2_mul( vec2_new(20, 20), TILE_SIZE); main_char->velocity = vec2_zero(); /* We can create multiple entities using a name format string like printf */ entities_new("coin_id_%i", COIN_COUNT, coin); /* Get an array of pointers to all coin entities */ coin* coins[COIN_COUNT]; entities_get(coins, NULL, coin); /* Set all the coin initial positions */ for(int i = 0; i < COIN_COUNT; i++) { coins[i]->position = vec2_mul(coin_positions[i], TILE_SIZE); } /* Deactivate victory and new game UI elements */ ui_button* victory = ui_elem_get("victory"); ui_button* new_game = ui_elem_get("new_game"); victory->active = false; new_game->active = false; }
void metaballs_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)){ float a1 = -(float)mouse_x * frame_time() * 0.25; float a2 = (float)mouse_y * frame_time() * 0.25; cam->position = v3_sub(cam->position, cam->target); cam->position = m33_mul_v3(m33_rotation_y( a1 ), cam->position ); cam->position = v3_add(cam->position, cam->target); cam->position = v3_sub(cam->position, cam->target); vector3 rotation_axis = v3_normalize(v3_cross( v3_sub(cam->position, v3_zero()) , v3(0,1,0) )); cam->position = m33_mul_v3(m33_rotation_axis_angle(rotation_axis, a2 ), cam->position ); cam->position = v3_add(cam->position, cam->target); } if(keystate & SDL_BUTTON(3)){ sun->position.x += (float)mouse_y / 2; sun->position.z -= (float)mouse_x / 2; } mouse_x = 0; mouse_y = 0; particles_update(frame_time()); ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); #ifdef MARCHING_CUBES marching_cubes_metaball_data( particle_positions_memory(), particles_count() ); marching_cubes_clear(); marching_cubes_update(); #endif #ifdef VOLUME_RENDERER volume_renderer_metaball_data( particle_positions_memory(), particles_count() ); volume_renderer_update(); #endif }
void metaballs_event(SDL_Event event) { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); switch(event.type){ case SDL_KEYDOWN: break; case SDL_KEYUP: if (event.key.keysym.sym == SDLK_SPACE) { particles_reset(); } if (event.key.keysym.sym == SDLK_w) { wireframe = !wireframe; } break; case SDL_MOUSEBUTTONUP: break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_WHEELUP) { cam->position = v3_sub(cam->position, v3_normalize(v3_sub(cam->position, cam->target))); } if (event.button.button == SDL_BUTTON_WHEELDOWN) { cam->position = v3_add(cam->position, v3_normalize(v3_sub(cam->position, cam->target))); } break; case SDL_MOUSEMOTION: mouse_x = event.motion.xrel; mouse_y = event.motion.yrel; break; } }
void vegetation_render() { camera* cam = entity_get("camera"); vec2 pos = vec2_div(vec2_new(cam->position.x, cam->position.z), BLOCK_SIZE); pos = vec2_clamp(pos, 1, 1022); char blockname0[512]; char blockname1[512]; char blockname2[512]; char blockname3[512]; char blockname4[512]; char blockname5[512]; char blockname6[512]; char blockname7[512]; char blockname8[512]; sprintf(blockname0, "vegblock_%i_%i", (int)pos.x-1, (int)pos.y-1); sprintf(blockname1, "vegblock_%i_%i", (int)pos.x , (int)pos.y-1); sprintf(blockname2, "vegblock_%i_%i", (int)pos.x+1, (int)pos.y-1); sprintf(blockname3, "vegblock_%i_%i", (int)pos.x-1, (int)pos.y ); sprintf(blockname4, "vegblock_%i_%i", (int)pos.x , (int)pos.y ); sprintf(blockname5, "vegblock_%i_%i", (int)pos.x+1, (int)pos.y ); sprintf(blockname6, "vegblock_%i_%i", (int)pos.x-1, (int)pos.y+1); sprintf(blockname7, "vegblock_%i_%i", (int)pos.x , (int)pos.y+1); sprintf(blockname8, "vegblock_%i_%i", (int)pos.x+1, (int)pos.y+1); static_object* block0 = entity_get(blockname0); static_object* block1 = entity_get(blockname1); static_object* block2 = entity_get(blockname2); static_object* block3 = entity_get(blockname3); static_object* block4 = entity_get(blockname4); static_object* block5 = entity_get(blockname5); static_object* block6 = entity_get(blockname6); static_object* block7 = entity_get(blockname7); static_object* block8 = entity_get(blockname8); /* forward_renderer_render_static(block0); forward_renderer_render_static(block1); forward_renderer_render_static(block2); forward_renderer_render_static(block3); forward_renderer_render_static(block4); forward_renderer_render_static(block5); forward_renderer_render_static(block6); forward_renderer_render_static(block7); forward_renderer_render_static(block8); */ }
static void collision_detection_coins() { /* We simply check if the player intersects with the coins */ character* main_char = entity_get("main_char"); vec2 top_left = vec2_add(main_char->position, vec2_new(-TILE_SIZE, -TILE_SIZE)); vec2 bottom_right = vec2_add(main_char->position, vec2_new(TILE_SIZE, TILE_SIZE)); /* Again we collect pointers to all the coin type entities */ int num_coins = 0; coin* coins[COIN_COUNT]; entities_get(coins, &num_coins, coin); for(int i = 0; i < num_coins; i++) { /* Check if they are within the main char bounding box */ if ((coins[i]->position.x > top_left.x) && (coins[i]->position.x < bottom_right.x) && (coins[i]->position.y > top_left.y) && (coins[i]->position.y < bottom_right.y)) { /* Remove them from the entity manager and delete */ char* coin_name = entity_name(coins[i]); entity_delete(coin_name); /* Play a nice twinkle sound */ audio_sound_play(asset_get_as(P("./sounds/coin.wav"), sound), 0); /* Add some score! */ level_score += 10; /* Update the ui text */ ui_button* score = ui_elem_get("score"); sprintf(score->label->string, "Score %06i", level_score); ui_text_draw(score->label); } } ui_button* victory = ui_elem_get("victory"); /* if all the coins are gone and the victory rectangle isn't disaplayed then show it */ if ((entity_type_count(coin) == 0) && (!victory->active)) { ui_button* victory = ui_elem_get("victory"); ui_button* new_game = ui_elem_get("new_game"); victory->active = true; new_game->active = true; } }
void sea_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); wave_time += frame_time(); static_object* corvette = entity_get("corvette"); corvette->position.y = (sin(wave_time) + 1) / 2; corvette->rotation = quaternion_pitch(sin(wave_time * 1.123) / 50); corvette->rotation = quaternion_mul(corvette->rotation, quaternion_yaw(sin(wave_time * 1.254) / 25)); corvette->rotation = quaternion_mul(corvette->rotation, quaternion_roll(sin(wave_time * 1.355) / 100)); static_object* center_sphere = entity_get("center_sphere"); physics_object* balls[100]; int num_balls; entities_get(balls, &num_balls, physics_object); for(int i = 0; i < num_balls; i++) { physics_object_collide_static(balls[i], center_sphere, frame_time()); physics_object_collide_static(balls[i], corvette, frame_time()); physics_object_update(balls[i], frame_time()); } Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(3)){ sun->position.x += (float)mouse_y / 2; sun->position.z -= (float)mouse_x / 2; } mouse_x = 0; mouse_y = 0; ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); }
void metaballs_render() { static_object* s_podium = entity_get("podium"); camera* cam = entity_get("camera"); light* sun = entity_get("sun"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #ifdef MARCHING_CUBES shadow_mapper_begin(); shadow_mapper_render_static(s_podium); marching_cubes_render_shadows(sun); shadow_mapper_end(); forward_renderer_begin(); forward_renderer_render_static(s_podium); forward_renderer_render_light(sun); marching_cubes_render(wireframe, cam, sun); forward_renderer_end(); #endif #ifdef VOLUME_RENDERER volume_renderer_render(); #endif #ifndef VOLUME_RENDERER #ifndef MARCHING_CUBES particles_render(); #endif #endif ui_render(); SDL_GL_SwapBuffers(); }
void scotland_render() { light* sun = entity_get("sun"); camera* cam = entity_get("camera"); landscape* world = entity_get("world"); static_object* skydome = entity_get("skydome"); shadow_mapper_begin(); shadow_mapper_render_landscape(world); shadow_mapper_end(); //texture_write_to_file(shadow_mapper_depth_texture(), "shadow_depth.tga"); forward_renderer_begin(); if (!wireframe) { forward_renderer_render_static(skydome); } if (wireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } forward_renderer_render_landscape(world); if (wireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } if (!wireframe) { vegetation_render(); } forward_renderer_render_light(sun); forward_renderer_end(); }
void vegetation_finish() { for(int x = 0; x < X_NUM; x++) for(int y = 0; y < Y_NUM; y++) { char blockname[512]; sprintf(blockname, "vegblock_%i_%i", x, y); static_object* block = entity_get(blockname); //renderable_delete(block->renderable); entity_delete(blockname); } free(blocks); }
void particles_render() { #ifdef OPEN_GL_CPU #ifndef CPU_ONLY kernel_memory_read(k_particle_positions, sizeof(vector4) * particle_count, particle_positions); #endif glBindBuffer(GL_ARRAY_BUFFER, positions_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vector4) * particle_count, particle_positions, GL_DYNAMIC_COPY); #ifndef CPU_ONLY kernel_memory_read(k_particle_randoms, sizeof(vector4) * particle_count, particle_randoms); #endif glBindBuffer(GL_ARRAY_BUFFER, randoms_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vector4) * particle_count, particle_randoms, GL_DYNAMIC_COPY); #endif camera* cam = entity_get("camera"); matrix_4x4 viewm = camera_view_matrix(cam); matrix_4x4 projm = camera_proj_matrix(cam, graphics_viewport_ratio() ); m44_to_array(viewm, view_matrix); m44_to_array(projm, proj_matrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(view_matrix); glMatrixMode(GL_PROJECTION); glLoadMatrixf(proj_matrix); glBindBuffer(GL_ARRAY_BUFFER, positions_buffer); glVertexPointer(4, GL_FLOAT, 0, (void*)0); glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, randoms_buffer); glColorPointer(4, GL_FLOAT, 0, (void*)0); glEnableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_POINTS, 0, particle_count); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); }
void platformer_update() { character* main_char = entity_get("main_char"); if (left_held) { main_char->velocity.x -= 0.1; main_char->facing_left = true; } else if (right_held) { main_char->velocity.x += 0.1; main_char->facing_left = false; } else { main_char->velocity.x *= 0.95; } /* Give the player some gravity speed */ const float gravity = 0.2; main_char->velocity.y += gravity; /* Update moves position based on velocity */ character_update(main_char); /* Two phases of collision detection */ collision_detection(); collision_detection_coins(); /* Camera follows main character */ camera_position = vec2_new(main_char->position.x, -main_char->position.y); /* Update the framerate text */ ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); /* Update the time text */ ui_button* victory = ui_elem_get("victory"); if (!victory->active) { level_time += frame_time(); ui_button* time = ui_elem_get("time"); sprintf(time->label->string, "Time %06i", (int)level_time); ui_text_draw(time->label); } }
void platformer_event(SDL_Event event) { switch(event.type){ case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_LEFT) { left_held = true; } if (event.key.keysym.sym == SDLK_RIGHT) { right_held = true; } /* Up key used to "jump". Just adds to up velocity and flaps wings of icon */ if (event.key.keysym.sym == SDLK_UP) { character* main_char = entity_get("main_char"); main_char->velocity.y -= 5.0; main_char->flap_timer = 0.15; } break; case SDL_KEYUP: if (event.key.keysym.sym == SDLK_LEFT) { left_held = false; } if (event.key.keysym.sym == SDLK_RIGHT) { right_held = false; } break; } }
int main(int argc, char **argv) { #ifdef _WIN32 FILE* ctt = fopen("CON", "w" ); FILE* fout = freopen( "CON", "w", stdout ); FILE* ferr = freopen( "CON", "w", stderr ); #endif corange_init("../../assets_core"); graphics_viewport_set_title("Teapot"); graphics_viewport_set_size(1280, 720); camera* cam = entity_new("camera", camera); cam->position = vec3_new(5, 5, 5); cam->target = vec3_new(0, 0, 0); teapot_shader = asset_hndl_new_load(P("./assets/teapot.mat")); teapot_object = asset_hndl_new_load(P("./assets/teapot.obj")); int running = 1; SDL_Event e = {0}; while(running) { frame_begin(); camera* cam = entity_get("camera"); while(SDL_PollEvent(&e)) { switch(e.type){ case SDL_KEYDOWN: case SDL_KEYUP: if (e.key.keysym.sym == SDLK_ESCAPE) { running = 0; } if (e.key.keysym.sym == SDLK_PRINTSCREEN) { graphics_viewport_screenshot(); } if (e.key.keysym.sym == SDLK_r && e.key.keysym.mod == KMOD_LCTRL) { asset_reload_all(); } break; case SDL_QUIT: running = 0; break; } camera_control_orbit(cam, e); ui_event(e); } ui_update(); glClearColor(0.25, 0.25, 0.25, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); shader_program* shader = material_first_program(asset_hndl_ptr(&teapot_shader)); shader_program_enable(shader); shader_program_set_mat4(shader, "world", mat4_id()); shader_program_set_mat4(shader, "view", camera_view_matrix(cam)); shader_program_set_mat4(shader, "proj", camera_proj_matrix(cam)); shader_program_set_texture(shader, "cube_beach", 0, asset_hndl_new_load(P("$CORANGE/water/cube_sea.dds"))); shader_program_set_vec3(shader, "camera_direction", camera_direction(cam)); renderable* r = asset_hndl_ptr(&teapot_object); for(int i=0; i < r->num_surfaces; i++) { renderable_surface* s = r->surfaces[i]; int mentry_id = min(i, ((material*)asset_hndl_ptr(&r->material))->num_entries-1); material_entry* me = material_get_entry(asset_hndl_ptr(&r->material), mentry_id); glBindBuffer(GL_ARRAY_BUFFER, s->vertex_vbo); shader_program_enable_attribute(shader, "vPosition", 3, 18, (void*)0); shader_program_enable_attribute(shader, "vNormal", 3, 18, (void*)(sizeof(float) * 3)); //shader_program_enable_attribute(shader, "vTangent", 3, 18, (void*)(sizeof(float) * 6)); //shader_program_enable_attribute(shader, "vBinormal", 3, 18, (void*)(sizeof(float) * 9)); //shader_program_enable_attribute(shader, "vTexcoord", 2, 18, (void*)(sizeof(float) * 12)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->triangle_vbo); glDrawElements(GL_TRIANGLES, s->num_triangles * 3, GL_UNSIGNED_INT, (void*)0); shader_program_disable_attribute(shader, "vPosition"); shader_program_disable_attribute(shader, "vNormal"); //shader_program_disable_attribute(shader, "vTangent"); //shader_program_disable_attribute(shader, "vBinormal"); //shader_program_disable_attribute(shader, "vTexcoord"); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); } shader_program_disable(shader); glDisable(GL_DEPTH_TEST); ui_render(); graphics_swap(); frame_end(); } corange_finish(); return 0; }
static void collision_detection() { /* Collision is fairly simplistic and looks something like this. @-----@ We check for collision in those points here which @ @ are @ signs. If any are colliding with a solid tile | | then we shift the player so that they are no longer @ @ colliding with it. Also invert the velocity. @-----@ */ character* main_char = entity_get("main_char"); const float buffer = 4; const float bounce = 0.5; vec2 diff; /* Bottom Collision */ diff = vec2_fmod(main_char->position, TILE_SIZE); vec2 bottom1 = vec2_add(main_char->position, vec2_new(buffer, TILE_SIZE)); vec2 bottom2 = vec2_add(main_char->position, vec2_new(TILE_SIZE - buffer, TILE_SIZE)); bool bottom1_col = tile_has_collision(level_tile_at(current_level, bottom1)); bool bottom2_col = tile_has_collision(level_tile_at(current_level, bottom2)); if (bottom1_col || bottom2_col) { main_char->position = vec2_add(main_char->position, vec2_new(0,-diff.y)); main_char->velocity.y *= -bounce; } /* Top Collision */ diff = vec2_fmod(main_char->position, TILE_SIZE); vec2 top1 = vec2_add(main_char->position, vec2_new(buffer, 0)); vec2 top2 = vec2_add(main_char->position, vec2_new(TILE_SIZE - buffer, 0)); bool top1_col = tile_has_collision(level_tile_at(current_level, top1)); bool top2_col = tile_has_collision(level_tile_at(current_level, top2)); if (top1_col || top2_col) { main_char->position = vec2_add(main_char->position, vec2_new(0, TILE_SIZE - diff.y)); main_char->velocity.y *= -bounce; } /* Left Collision */ diff = vec2_fmod(main_char->position, TILE_SIZE); vec2 left1 = vec2_add(main_char->position, vec2_new(0, buffer)); vec2 left2 = vec2_add(main_char->position, vec2_new(0, TILE_SIZE - buffer)); bool left1_col = tile_has_collision(level_tile_at(current_level, left1)); bool left2_col = tile_has_collision(level_tile_at(current_level, left2)); if (left1_col || left2_col) { main_char->position = vec2_add(main_char->position, vec2_new(TILE_SIZE - diff.x,0)); main_char->velocity.x *= -bounce; } /* Right Collision */ diff = vec2_fmod(main_char->position, TILE_SIZE); vec2 right1 = vec2_add(main_char->position, vec2_new(TILE_SIZE, buffer)); vec2 right2 = vec2_add(main_char->position, vec2_new(TILE_SIZE, TILE_SIZE - buffer)); bool right1_col = tile_has_collision(level_tile_at(current_level, right1)); bool right2_col = tile_has_collision(level_tile_at(current_level, right2)); if (right1_col || right2_col) { main_char->position = vec2_add(main_char->position, vec2_new(-diff.x,0)); main_char->velocity.x *= -bounce; } }