space_pirate space_pirate_update(space_pirate p, whitgl_fvec target) { if(!p.e.active) return p; whitgl_fvec diff = whitgl_fvec_sub(target, p.e.pos); whitgl_float target_angle = whitgl_fvec_to_angle(diff)+whitgl_pi/2; whitgl_float ang_diff = whitgl_fwrap(target_angle-p.e.angle, -whitgl_pi, whitgl_pi); whitgl_bool r, l; if(ang_diff > 0.2) { r = true; l = false; } else if(ang_diff < -0.2) { r = false; l = true; } else { l = true; r = true; } if(l&&r) { whitgl_fvec impulse = {0,-0.002}; impulse = whitgl_rotate_point_around_point(impulse, whitgl_fvec_zero, p.e.angle); p.speed = whitgl_fvec_add(p.speed, impulse); } if(l) p.angle_speed = whitgl_fclamp(p.angle_speed-0.01, -0.2, 0.2); if(r) p.angle_speed = whitgl_fclamp(p.angle_speed+0.01, -0.2, 0.2); p.angle_speed = p.angle_speed*0.9; p.e.angle = whitgl_fwrap(p.e.angle+p.angle_speed, 0, whitgl_pi*2); p.e.pos = whitgl_fvec_add(p.e.pos, p.speed); p.speed = whitgl_fvec_interpolate(p.speed, whitgl_fvec_zero, 0.01); whitgl_int i; for(i=0; i<2; i++) { whitgl_bool on = i == 0 ? r : l; // if(on && !p.was_on[i]) // whitgl_sound_play(i == 0 ? SOUND_THRUST_L : SOUND_THRUST_R, 1.0); // p.was_on[i] = on; whitgl_float target = on ? 1 : 0; p.engine_thrust[i] = p.engine_thrust[i]*0.6 + 0.4*target; } return p; }
game_snake game_snake_update(game_snake snake, const game_map* map) { whitgl_fvec joy = whitgl_input_joystick(); if(whitgl_input_pressed(WHITGL_INPUT_A)) snake.do_reverse = true; if(snake.do_reverse) joy = whitgl_fvec_zero; whitgl_int dir = whitgl_fvec_to_facing(joy); bool moving = joy.x != 0 || joy.y != 0; snake.falling = true; whitgl_int i; for(i=0 ;i<snake.size; i++) { whitgl_int j; for(j=0; j<4; j++) { whitgl_ivec test_pos = whitgl_ivec_add(snake.pos[i], whitgl_facing_to_ivec(j)); if(j!=2 && (i==snake.size-1 || i==0)) continue; if(j==2 && game_map_get_tile(map, test_pos) == TILE_WALL) snake.falling = false; if(j==2 && game_map_get_tile(map, test_pos) == TILE_PLATFORM) snake.falling = false; if(j==2 && game_map_get_tile(map, test_pos) == TILE_BEAM) snake.falling = false; } if(game_map_get_tile(map, snake.pos[i]) == TILE_VINE) snake.falling = false; } if(game_map_get_tile(map, snake.new_pos) == TILE_WALL && _game_snake_move_valid(snake, snake.new_pos, map)) snake.falling = false; if(snake.falling) { snake.fall_speed = whitgl_fclamp(snake.fall_speed+0.02, 0, 0.5); snake.fall_timer += snake.fall_speed; if(snake.fall_timer > 0.5) { for(i=0 ;i<MAX_SEGMENTS; i++) { snake.pos[i].y++; } snake.new_pos.y++; snake.fall_timer -= 1; } } else { snake.fall_timer = 0; snake.fall_speed = 0; } if(!moving && !snake.do_reverse ) { return snake; } bool forward = true; if(dir != snake.dir && snake.t < 0.5) forward = false; if(!_game_snake_move_valid(snake, snake.new_pos, map)) forward = false; whitgl_float inc = forward ? 1.0/8.0 : -1.0/4.0; whitgl_float old_snake_t = snake.t; snake.t = whitgl_fclamp(snake.t+inc, 0, 1); if(old_snake_t <= 0.5 && snake.t > 0.5) { snake.old_pos = snake.pos[snake.size-1]; for(i=MAX_SEGMENTS-1; i>0; i--) snake.pos[i] = snake.pos[i-1]; snake.pos[0] = snake.new_pos; if(whitgl_randfloat() > 0.5) whitgl_sound_play(SOUND_SLICK00+whitgl_randint(6), whitgl_randfloat()*0.2+0.9); } if(snake.t == 0 || snake.t == 1) { if(snake.do_reverse) { game_snake new_snake = snake; for(i=0; i<snake.size; i++) new_snake.pos[i] = snake.pos[snake.size-1-i]; new_snake.dir = whitgl_ivec_to_facing(whitgl_ivec_sub(snake.pos[snake.size-1], snake.pos[snake.size-2])); new_snake.do_reverse = false; new_snake.old_pos = snake.new_pos; new_snake.new_pos = snake.old_pos; snake = new_snake; whitgl_sound_play(SOUND_SWAP, whitgl_randfloat()*0.5+0.75); snake.t = 1; } whitgl_ivec new_pos = whitgl_ivec_add(snake.pos[0], whitgl_facing_to_ivec(dir)); if(_game_snake_move_valid(snake, new_pos, map)) { snake.new_pos = new_pos; snake.dir = dir; snake.t = 0.1; } } return snake; }