| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- //
- // level.cxx
- // danmaku
- //
- // Created by Sam Jaffe on 5/26/19.
- // Copyright © 2019 Sam Jaffe. All rights reserved.
- //
- #include "danmaku/level.hpp"
- #include <json/json.h>
- #include "danmaku/actor.hpp"
- #include "danmaku/bullet.hpp"
- #include "danmaku/player.hpp"
- #include "danmaku/serial.hpp"
- #include "game/graphics/renderer.hpp"
- #include "game/math/common.hpp"
- #include "game/util/env.hpp"
- #include "resource_factory/prototype_factory.hpp"
- using namespace danmaku;
- struct wave_helper {
- using wave_t = std::vector<std::unique_ptr<actor>>;
- wave_t get_wave(Json::Value const & json) {
- wave_t out;
- for (int i = 0; i < json.size(); ++i) {
- std::string file = mappings[json[i]["id"].asString()].asString();
- std::string path = env::resource_file("scripts/entity/" + file);
- Json::Value actor = engine::read_file(path);
- actor["position"] = json[i]["position"];
- out.emplace_back(to_actor(actor, manager));
- }
- return out;
- }
- std::deque<wave_t> operator()() {
- std::deque<wave_t> out;
- for (int i = 0; i < waves.size(); ++i) {
- out.emplace_back(get_wave(waves[i]));
- }
- return out;
- }
- wave_helper(Json::Value const & json, graphics::manager const & mgr)
- : waves(json["waves"]), mappings(json["mappings"]), manager(mgr) {}
- Json::Value const & waves;
- Json::Value const & mappings;
- graphics::manager const & manager;
- };
- level::level(Json::Value const & json,
- std::shared_ptr<engine::game_dispatch> dispatch)
- : engine::scene(json["id"].asString(), dispatch),
- player_(), wave_timer_{json["timeBetweenWaves"].asFloat()},
- waves_(wave_helper{json, graphics_manager()}()) {}
- level::level(std::string const & id, Json::Value const & json,
- std::shared_ptr<engine::game_dispatch> dispatch)
- : engine::scene(id, dispatch),
- player_(), wave_timer_{json["timeBetweenWaves"].asFloat()},
- waves_(wave_helper{json, graphics_manager()}()) {}
- level::~level() {}
- void level::add_bullet(bullet b) {
- bullets_.emplace_back(std::make_unique<bullet>(std::move(b)));
- // TODO: Add to correct collision boxes...
- collidables[0].emplace_back(bullets_.back().get());
- }
- template <typename T>
- void level::perform_oob_culling_impl(std::vector<std::unique_ptr<T>> & data) {
- // TODO: Aquire screen size correctly...?
- math::dim2::rectangle bound{{{0.f, 0.f}}, {{3840.f, 2160.f}}};
- auto is_oob = [&bound](std::unique_ptr<T> & ptr) {
- return !math::intersects(ptr->render_info().points, bound);
- };
- auto it = std::remove_if(data.begin(), data.end(), is_oob);
- auto remove_collider = [this](std::unique_ptr<T> & ptr) {
- // TODO: colliders, use the collision enums.
- collidables[0].erase(
- std::remove(collidables[0].begin(), collidables[0].end(), ptr.get()),
- collidables[0].end());
- };
- std::for_each(it, data.end(), remove_collider);
- data.erase(it, data.end());
- }
- void level::perform_oob_culling() {
- // perform_oob_culling_impl(actors_);
- perform_oob_culling_impl(bullets_);
- }
- void level::update(float delta) {
- perform_oob_culling();
- update_waves(delta);
- update_object(delta);
- check_collisions();
- }
- void level::update_object(float delta) {
- player_->update(delta);
- for (auto & a : actors_) {
- a->update(delta);
- }
- for (auto & b : bullets_) {
- b->update(delta);
- }
- }
- void level::check_collisions() {
- engine::scene::check_collisions();
- // TODO: This is a bad hack until I can properly disassociate collision info
- for (auto & b : bullets_) {
- if (math::intersects(player_->render_info().points,
- b->render_info().points)) {
- player_->hit(*b);
- }
- }
- }
- void level::update_waves(float delta) {
- if (waves_.empty()) { return; }
- if ((wave_timer_.remainder -= delta) <= 0.f) {
- wave_timer_.remainder = wave_timer_.interval;
- for (auto & actor : waves_.front()) {
- actor->level(this);
- actors_.emplace_back(std::move(actor));
- }
- waves_.pop_front();
- }
- }
- void level::render(graphics::renderer & renderer) {
- renderer.draw(player_->render_info());
- for (auto & a : actors_) {
- renderer.draw(a->render_info());
- }
- for (auto & b : bullets_) {
- renderer.draw(b->render_info());
- }
- }
|