#include <SDL2/SDL.h>
#include <assert.h>
+#include "game/camera.h"
#include "game/level.h"
#include "game/level/background.h"
-#include "game/level/camera.h"
+#include "game/level/boxes.h"
#include "game/level/goals.h"
#include "game/level/lava.h"
+#include "game/level/physical_world.h"
#include "game/level/platforms.h"
#include "game/level/player.h"
#include "system/error.h"
#include "system/lt.h"
-
-/* TODO(#118): Level doesn't play the Nothing and Something sounds when the goal get into view */
+#include "system/lt/lt_adapters.h"
struct level_t
{
lt_t *lt;
+
+ physical_world_t *physical_world;
player_t *player;
platforms_t *platforms;
goals_t *goals;
color_t background_color;
platforms_t *back_platforms;
background_t *background;
+ boxes_t *boxes;
};
level_t *create_level_from_file(const char *file_name)
RETURN_LT(lt, NULL);
}
- FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose);
+ FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt);
if (level_file == NULL) {
throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
RETURN_LT(lt, NULL);
}
+ level->boxes = PUSH_LT(lt, create_boxes_from_stream(level_file), destroy_boxes);
+ if (level->boxes == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+
level->background = PUSH_LT(lt, create_background(level->background_color), destroy_background);
if (level->background == NULL) {
RETURN_LT(lt, NULL);
}
+ level->physical_world = PUSH_LT(lt, create_physical_world(), destroy_physical_world);
+ if (level->physical_world == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+ if (physical_world_add_solid(
+ level->physical_world,
+ player_as_solid(level->player)) < 0) { RETURN_LT(lt, NULL); }
+ if (boxes_add_to_physical_world(
+ level->boxes,
+ level->physical_world) < 0) { RETURN_LT(lt, NULL); }
+
level->lt = lt;
fclose(RELEASE_LT(lt, level_file));
{
assert(level);
+ player_focus_camera(level->player, camera);
+
if (camera_clear_background(camera, level->background_color) < 0) {
return -1;
}
- const rect_t view_port = camera_view_port(camera);
-
- background_move_to(level->background, vec(view_port.x + view_port.w * 0.5f,
- view_port.y + view_port.h * 0.5f));
-
if (background_render(level->background, camera) < 0) {
return -1;
}
return -1;
}
+ if (boxes_render(level->boxes, camera) < 0) {
+ return -1;
+ }
+
if (lava_render(level->lava, camera) < 0) {
return -1;
}
return -1;
}
- /* TODO: player_focus_camera is not supposed to be invoked in level_render */
- player_focus_camera(level->player, camera);
-
- /* TODO(#157): goals_cue is not supposed to be invoked in level_render
- *
- * But I simply couldn't find a better place for it.
- */
- goals_cue(level->goals, camera);
return 0;
}
assert(level);
assert(delta_time > 0);
- player_update(level->player, level->platforms, delta_time);
+ physical_world_apply_gravity(level->physical_world);
+
+ boxes_update(level->boxes, delta_time);
+ player_update(level->player, delta_time);
+
+ physical_world_collide_solids(level->physical_world, level->platforms);
player_hide_goals(level->player, level->goals);
player_die_from_lava(level->player, level->lava);
goals_update(level->goals, delta_time);
- goals_checkpoint(level->goals, level->player);
lava_update(level->lava, delta_time);
return 0;
/* TODO(#104): duplicate code in create_level_from_file and level_reload_preserve_player */
- FILE * const level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose);
+
+
+ FILE * const level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt);
if (level_file == NULL) {
throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, -1);
}
level->back_platforms = RESET_LT(level->lt, level->back_platforms, back_platforms);
+ boxes_t * const boxes = create_boxes_from_stream(level_file);
+ if (level->boxes == NULL) {
+ RETURN_LT(lt, -1);
+ }
+ level->boxes = RESET_LT(level->lt, level->boxes, boxes);
+
+ physical_world_clean(level->physical_world);
+ if (physical_world_add_solid(
+ level->physical_world,
+ player_as_solid(level->player)) < 0) { RETURN_LT(lt, -1); }
+ if (boxes_add_to_physical_world(
+ level->boxes,
+ level->physical_world) < 0) { RETURN_LT(lt, -1); }
+
RETURN_LT(lt, 0);
}
-int level_sound(level_t *level, sound_medium_t *sound_medium)
+int level_sound(level_t *level, sound_samples_t *sound_samples)
{
- if (goals_sound(level->goals, sound_medium) < 0) {
+ if (goals_sound(level->goals, sound_samples) < 0) {
return -1;
}
- if (player_sound(level->player, sound_medium) < 0) {
+ if (player_sound(level->player, sound_samples) < 0) {
return -1;
}
return 0;
}
+
+void level_toggle_debug_mode(level_t *level)
+{
+ background_toggle_debug_mode(level->background);
+}
+
+int level_enter_camera_event(level_t *level,
+ const camera_t *camera)
+{
+ goals_cue(level->goals, camera);
+ goals_checkpoint(level->goals, level->player);
+ return 0;
+}