Esempio n. 1
0
struct SVGPath* svgParseFromFile(const char* filename)
{
	FILE* fp;
	int size;
	char* data;
	struct SVGPath* plist;

	fp = fopen(filename, "rb");
	if (!fp) return 0;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	data = (char*)malloc(size+1);
	fread(data, size, 1, fp);
	data[size] = '\0';	// Must be null terminated.
	fclose(fp);
	plist = svgParse(data);
	free(data);
	return plist;
}
Esempio n. 2
0
Game::Game(const std::string &level, float near, float far, float fov) :
    camera(fov, resolution.x/(float)resolution.y, near, far)
    , music(nullptr)
    , current_mode(MODE_READY)
{
    composition = new RenderTarget(resolution, GL_RGB8, RenderTarget::DEPTH_BUFFER | RenderTarget::DOUBLE_BUFFER);
    geometry = new RenderTarget(resolution, GL_RGB8, RenderTarget::DEPTH_BUFFER);

    printf("Loading level %s\n", level.c_str());

    std::string base_dir = PATH_BASE "data/levels/" + level;

    Config config = Config::parse(base_dir + "/level.cfg");

    //Read config:
    start_position = config["/player/start_position"]->as_float();
    sky_color = config["/environment/sky_color"]->as_color();
    static const glm::vec2 terrain_scale = config["/environment/terrain/scale"]->as_vec2();
    static const float fog_intensity = config["/environment/fog_intensity"]->as_float();
    camera_offset = config["/player/camera/offset"]->as_vec3();
    look_at_offset = config["/player/camera/look_at_offset"]->as_float();
    movement_speed = config["/player/speed/normal"]->as_float();
    brake_movement_speed = config["/player/speed/brake"]->as_float();

    spawn_area_start = config["/game/spawn_area/start"]->as_float();
    spawn_area_end = config["/game/spawn_area/end"]->as_float();
    spawn_area_size = spawn_area_end - spawn_area_start;
    spawn_distance = config["/game/spawn_area/distance"]->as_float();
    despawn_distance = config["/game/spawn_area/despawn_distance"]->as_float();
    difficulty_increase = config["/game/difficulty_increase"]->as_float();

    static const Shader::fog_t fog = { glm::vec4(sky_color.to_vec3(), 1.f), fog_intensity };
    Shader::upload_fog(fog);

    TextureArray * colors = TextureArray::from_filename( (base_dir +"/color0.png").c_str(),
                            (base_dir + "/color1.png").c_str(), nullptr);
    TextureArray *  normals = TextureArray::from_filename( (base_dir +"/normal0.png").c_str(),
                              (base_dir + "/normal1.png").c_str(), nullptr);

    terrain = new Terrain(base_dir + "/map.png", terrain_scale.x, terrain_scale.y, colors, normals);

    Data * path_file = Data::open(base_dir + "/path.svg");

    SVGPath * svg_path = svgParse((char*) path_file->data());

    delete path_file;

    std::vector<glm::vec3> path_nodes;

    for(int i=0; i< svg_path->npts; ++i) {
        path_nodes.push_back(glm::vec3(
                                 svg_path->pts[i*2],
                                 0,
                                 svg_path->pts[i*2 + 1]
                             ) * terrain_scale.x);
    }

    svgDelete(svg_path);

    Path::optimize_vector(path_nodes);

    // Gets max elevation for a radius around a point to avoid the rails cliping into the ground.
    for(glm::vec3 &v : path_nodes) {
        v.y = glm::max(glm::max(glm::max(terrain->height_at(v.x+1.5f, v.z),terrain->height_at(v.x-1.5f, v.z)),terrain->height_at(v.x, v.z+1.5f)),terrain->height_at(v.x, v.z-1.5f)) + 0.2f;
    }

    path = new Path(path_nodes, false);

    rails = new Rails(path, 1.f);
    rail_texture = Texture2D::from_filename(PATH_BASE "data/textures/rails.png");
    rail_material.texture = rail_texture;

    //Setup player:
    player.canon_offset = config["/player/canon_offset"]->as_vec3();
    player.canon_length = config["/player/canon_length"]->as_float();
    //Configure lights:

    lights.ambient_intensity() = config["/environment/light/ambient"]->as_vec3();
    lights.num_lights() = 1;

    lights.lights[0]->intensity = config["/environment/light/sunlight"]->as_vec3();
    lights.lights[0]->type = MovableLight::DIRECTIONAL_LIGHT;

    //Load enemies:
    EnemyTemplate::init(Config::parse(base_dir + "/enemies.cfg"), this);

//Set up camera:

    update_camera();

//Create particle systems:

    wind_velocity = config["/environment/wind_velocity"]->as_vec3();
    gravity = glm::vec4(config["/environment/gravity"]->as_vec3(), 1.f);

    particle_shader = Shader::create_shader("particles");
    passthru = Shader::create_shader("passthru");

    static const Config particle_config = Config::parse(base_dir + "/particles.cfg");

    static const float canon_inner_radius = particle_config["/particles/spawn_radius"]->as_float();

    particle_textures = TextureArray::from_filename( PATH_BASE "data/textures/smoke.png",
                        PATH_BASE "data/textures/fog.png",
                        PATH_BASE "data/textures/particle.png",
                        PATH_BASE "data/textures/fire1.png",
                        PATH_BASE "data/textures/fire2.png",
                        PATH_BASE "data/textures/fire3.png",
                        nullptr);

    static const int max_attack_particles = particle_config["/particles/max_attack_particles"]->as_int();
    static const int max_smoke_particles = particle_config["/particles/max_smoke_particles"]->as_int();
    static const int max_dust_particles = particle_config["/particles/max_dust_particles"]->as_int();
    static const int max_explosion_particles = particle_config["/particles/max_explosion_particles"]->as_int();

    attack_particles = new HittingParticles(max_attack_particles, particle_textures, EnemyTemplate::max_num_enemies, false);
    attack_particles->config.gravity = gravity;
    system_configs.push_back(&(attack_particles->config));
    attack_particles->config.spawn_area = glm::vec4(0.f, 0.f, 0.f, canon_inner_radius);

    for(auto &p : particle_types) {
        p.config = attack_particles->config; //Get reasonable defaults
        system_configs.push_back(&(p.config));
    }

    read_particle_config(particle_config["/particles/light"], particle_types[LIGHT_PARTICLES].config);
    particle_types[LIGHT_PARTICLES].count = particle_config["/particles/light/count"]->as_int();
    particle_types[LIGHT_PARTICLES].spawn_speed = particle_config["/particles/light/spawn_speed"]->as_float();
    particle_types[LIGHT_PARTICLES].damage = particle_config["/particles/light/damage"]->as_float();

    read_particle_config(particle_config["/particles/medium"], particle_types[MEDIUM_PARTICLES].config);
    particle_types[MEDIUM_PARTICLES].count = particle_config["/particles/medium/count"]->as_int();
    particle_types[MEDIUM_PARTICLES].spawn_speed = particle_config["/particles/medium/spawn_speed"]->as_float();
    particle_types[MEDIUM_PARTICLES].damage = particle_config["/particles/medium/damage"]->as_float();

    read_particle_config(particle_config["/particles/heavy"], particle_types[HEAVY_PARTICLES].config);
    particle_types[HEAVY_PARTICLES].count = particle_config["/particles/heavy/count"]->as_int();
    particle_types[HEAVY_PARTICLES].spawn_speed = particle_config["/particles/heavy/spawn_speed"]->as_float();
    particle_types[HEAVY_PARTICLES].damage = particle_config["/particles/heavy/damage"]->as_float();

    //Smoke:
    smoke = new ParticleSystem(max_smoke_particles, particle_textures, false);
    smoke->config.gravity = gravity;
    system_configs.push_back(&(smoke->config));
    smoke->config.spawn_area = glm::vec4(0.f, 0.f, 0.f, canon_inner_radius * 2.0);

    read_particle_config(particle_config["/particles/smoke"], smoke->config);
    smoke_count = particle_config["/particles/smoke/count"]->as_int();
    smoke_spawn_speed = particle_config["/particles/smoke/spawn_speed"]->as_float();

    //Dust:
    dust = new ParticleSystem(max_dust_particles, particle_textures, true);

    read_particle_config(particle_config["/particles/dust"], dust->config);

    dust->config.gravity = gravity;
    system_configs.push_back(&(dust->config));
    dust->config.spawn_area = particle_config["/particles/dust/spawn_area"]->as_vec4();
    dust->config.avg_spawn_velocity = glm::vec4(particle_config["/particles/dust/avg_spawn_velocity"]->as_vec3(), 0);
    dust->avg_spawn_rate = particle_config["/particles/dust/avg_spawn_rate"]->as_float();
    dust->spawn_rate_var = particle_config["/particles/dust/spawn_rate_var"]->as_float();
    dust_spawn_ahead = particle_config["/particles/dust/spawn_ahead"]->as_float();
    half_dust_spawn_area = glm::vec3(dust->config.spawn_area.x, dust->config.spawn_area.y, dust->config.spawn_area.z) / 2.f;

    dust->config.spawn_position = glm::vec4(player.position() - half_dust_spawn_area, 1.f);
    dust->update_config();
    dust->spawn(dust->avg_spawn_rate * 5.0);
    dust->config.spawn_position += glm::vec4(path->at(player.path_position() + dust_spawn_ahead / 2.f), 0.f);
    dust->spawn(dust->avg_spawn_rate * 5.0);

    //Explosions
    explosions = new ParticleSystem(max_explosion_particles, particle_textures, false);

    hit_explosion = explosions->config;
    system_configs.push_back(&(hit_explosion));
    kill_explosion = explosions->config;
    system_configs.push_back(&(kill_explosion));
    read_particle_config(particle_config["/particles/hit_explosion"], hit_explosion);
    read_particle_config(particle_config["/particles/kill_explosion"], kill_explosion);

    explosions->config.gravity = gravity;
    system_configs.push_back(&(explosions->config));
    hit_explosion_count = particle_config["/particles/hit_explosion/count"]->as_int();
    kill_explosion_count = particle_config["/particles/kill_explosion/count"]->as_int();
    kill_explosion.spawn_area = particle_config["/particles/kill_explosion/spawn_area"]->as_vec4();
    kill_explosion.avg_spawn_velocity = glm::vec4(particle_config["/particles/kill_explosion/avg_spawn_velocity"]->as_vec3(), 0);
    hit_explosion.spawn_area = particle_config["/particles/hit_explosion/spawn_area"]->as_vec4();
    hit_explosion.avg_spawn_velocity = glm::vec4(particle_config["/particles/hit_explosion/avg_spawn_velocity"]->as_vec3(), 0);

    update_wind_velocity();
    //Setup HUD




    hud_scale = glm::vec2(resolution.x / 800.f, resolution.y / 600.f);
    hud_static_elements_tex = Texture2D::from_filename(PATH_BASE "/data/textures/hudStatic.png");
    fullscreen_quad = new Quad();
    fullscreen_quad->set_scale(glm::vec3(resolution.x,resolution.y,0));

    hud_lightpos =  glm::vec2(594,490) * hud_scale;
    hud_mediumpos = glm::vec2(644,490) * hud_scale;
    hud_heavypos =  glm::vec2(700,490) * hud_scale;

    hud_choice_tex = Texture2D::from_filename(PATH_BASE "/data/textures/weap_select.png");
    hud_choice_quad = new Quad();
    hud_choice_quad->set_scale(glm::vec3(97,92,0) * glm::vec3(hud_scale , 0));

    hud_break_tex = Texture2D::from_filename(PATH_BASE "/data/textures/breaks_ready.png");
    hud_break_quad = new Quad();
    hud_break_quad->set_scale(glm::vec3(190, 25, 0) * glm::vec3(hud_scale, 0));
    hud_break_quad->set_position(glm::vec3(glm::vec2(30, 530) * hud_scale, 0.f));

    life_text.set_color(hud_font_color);
    life_text.set_scale(20.0 * hud_scale.x);
    life_text.set_position(glm::vec3(glm::vec2(26.f, 44.5f) * hud_scale, 0.f));

    //Highscore stuff:
    highscore = new Highscore(base_dir + "/highscore", NUM_HIGHSCORE_ENTRIES);
    float hs_scale = 40.f;
    glm::vec2 higscore_base = glm::vec2(735.f, 85.f);
    int i=0;
    for(Text &t : highscore_entries) {
        t.set_position(glm::vec3( (higscore_base + glm::vec2(0.f, (i++)*hs_scale)) * hud_scale, 0.f));
        t.set_scale(hs_scale);
        t.set_text("");
        t.set_alignment(Text::RIGHT_ALIGNED);
    }

    //Textures
    game_over_texture = Texture2D::from_filename(PATH_BASE "/data/textures/gameover.png");
    startscreen_texture = Texture2D::from_filename(PATH_BASE "/data/textures/start_screen.png");
}