示例#1
0
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;
}
示例#2
0
static int _llfunc_vec2_mul(lua_State *L) {
	vec2 *v = (vec2*)userdata_get_or_die(L, 1);
	float k = (float)luaL_checknumber(L, 2);
	vec2 *r = (vec2*)userdata_get_or_new(L, 3, sizeof(vec2));
	vec2_mul(v, k, r);
	return 1;
}
示例#3
0
文件: game.c 项目: truongascii/cgame
Vec2 game_unit_to_pixels(Vec2 p)
{
    Vec2 hw = vec2_scalar_mul(game_get_window_size(), 0.5f);
    p = vec2_mul(p, hw);
    p = vec2(p.x + hw.x, p.y - hw.y);
    return p;
}
示例#4
0
static void vertex_shader(const vertex_t *in, vs_to_fs_t *out)
{
	// decode vertex
	const vec3_t pc = { 0.5f, 0.5f, 0.5f }, nc = { 1.0f, 1.0f, 1.0f };
	const float pi = 1.0f / 65535.0f, ni = 2.0f / 255.0f, uvi = 1.0f / 255.0f;
	vec3_t position = vec3_sub(vec3_mul(vec3(in->x, in->y, in->z), pi), pc);
	vec3_t normal = vec3_sub(vec3_mul(vec3(in->nx, in->ny, in->nz), ni), nc);
	vec2_t uv = vec2_mul(vec2(in->u, in->v), uvi);
	// transform vertex
	out->position = mat4_transform_position(mvp, position);
	out->normal = mat4_transform_vector(mv, normal);
	out->uv = uv;
}
示例#5
0
void	raycast_init(t_env *e)
{
	float	cam;
	t_vec2	dir_pow;

	cam = (2 * e->ray.x / (float)e->win_w) - 1;
	e->ray.hit = 0;
	e->ray.pos = e->map.pos;
	e->ray.dir.x = e->cam.dir.x + e->cam.pln.x * cam;
	e->ray.dir.y = e->cam.dir.y + e->cam.pln.y * cam;
	e->ray.map = vec2i(e->ray.pos);
	dir_pow = vec2_mul(e->ray.dir, e->ray.dir);
	e->ray.a.x = sqrt(1 + dir_pow.y / dir_pow.x);
	e->ray.a.y = sqrt(1 + dir_pow.x / dir_pow.y);
}
示例#6
0
文件: gx.c 项目: LWSS/gx
static bool line_line_intersection(vec2 a0, vec2 a1, vec2 b0, vec2 b1)
{
#if 1
    // Implemented based on http://stackoverflow.com/a/17198094/4354008
    vec2 v = vec2_sub(a0, a1);
    vec2 normal = vec2_new(v.y, -v.x);

    vec2 v0 = vec2_sub(b0, a0);
    vec2 v1 = vec2_sub(b1, a0);

    float proj0 = vec2_dot(v0, normal);
    float proj1 = vec2_dot(v1, normal);

    if ((proj0 == 0) || (proj1 == 0))
        return true;

    // TODO: float_sign()
    if ((proj0 > 0) && (proj1 < 0))
        return true;
    if ((proj0 < 0) && (proj1 > 0))
        return true;

    return false;
#else
    vec2 intersection = vec2_zero();

    vec2 b = vec2_sub(a1, a0);
    vec2 d = vec2_sub(b1, b0);
    float b_dot_p_perp = (b.x * d.y) - (b.y * d.x);

    if (b_dot_p_perp == 0)
        return false;

    vec2 c = vec2_sub(b0, a0);
    float t = ((c.x * d.y) - (c.y * d.x)) / b_dot_p_perp;
    if ((t < 0) || (t > 1))
        return false;

    float u = ((c.x * b.y) - (c.y * b.x)) / b_dot_p_perp;
    if ((u < 0) || (u > 1))
        return false;

    // TODO: make this an output parameter
    intersection = vec2_add(a0, vec2_mul(b, t));

    return true;
#endif
}
示例#7
0
文件: gx.c 项目: LWSS/gx
static void fire_projectile(struct GameState *game_state, struct Ship *source, struct Ship *target, int32 damage)
{
    ASSERT(source != target);

    source->fire_cooldown_timer = source->fire_cooldown;

    struct Projectile *projectile = create_projectile(game_state);

    projectile->owner = source->id;
    projectile->team = source->team;
    projectile->damage = damage;

    projectile->position = source->position;
    projectile->size = vec2_new(0.1f, 0.1f);

    vec2 direction = vec2_normalize(vec2_sub(target->position, projectile->position));
    projectile->velocity = vec2_mul(direction, 5.0f);
}
示例#8
0
文件: gx.c 项目: LWSS/gx
void tick_game(struct GameMemory *memory, struct Input *input, uint32 screen_width, uint32 screen_height, float dt)
{
    struct GameState *game_state = (struct GameState *)memory->game_memory;
    struct RenderBuffer *render_buffer = (struct RenderBuffer *)memory->render_memory;

    clear_render_buffer(render_buffer);

    for (uint32 i = 0; i < game_state->visibility_graph.vertex_count; ++i)
    {
        vec2 vertex = game_state->visibility_graph.vertices[i];
        draw_world_quad_buffered(render_buffer, vertex, vec2_scalar(0.1f), vec4_zero(), vec3_new(0, 1, 1));
    }

    for (uint32 i = 0; i < game_state->visibility_graph.edge_count; ++i)
    {
        uint32 *edge = &game_state->visibility_graph.edges[i][0];

        vec2 p0 = game_state->visibility_graph.vertices[edge[0]];
        vec2 p1 = game_state->visibility_graph.vertices[edge[1]];

        draw_world_line_buffered(render_buffer, p0, p1, vec3_new(1, 1, 0));
    }

    if (mouse_down(MOUSE_LEFT, input))
    {
        struct AABB box = calc_mouse_selection_box(input, MOUSE_LEFT);

        vec2 size = vec2_sub(box.max, box.min);
        vec2 bottom_left  = vec2_new(box.min.x, box.max.y);
        vec2 bottom_right = vec2_new(box.max.x, box.max.y);
        vec2 top_left     = vec2_new(box.min.x, box.min.y);
        vec2 top_right    = vec2_new(box.max.x, box.min.y);

        const uint32 outline_thickness = 1;

        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, bottom_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_right, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
    }

    if (mouse_released(MOUSE_LEFT, input))
    {
        // Clear previous selection.
        game_state->selected_ship_count = 0;

        struct AABB screen_selection_box = calc_mouse_selection_box(input, MOUSE_LEFT);

        // Because screen space y-values are inverted, these two results have conflicting
        // y-values, i.e. screen_to_world_min.y is actually the maximum y. These values
        // are then properly min/maxed and stored correctly in world_selection_box.
        vec2 screen_to_world_min = screen_to_world_coords(screen_selection_box.min, &game_state->camera, screen_width, screen_height);
        vec2 screen_to_world_max = screen_to_world_coords(screen_selection_box.max, &game_state->camera, screen_width, screen_height);

        struct AABB world_selection_box;
        world_selection_box.min = min_vec2(screen_to_world_min, screen_to_world_max);
        world_selection_box.max = max_vec2(screen_to_world_min, screen_to_world_max);

        // Add colliding ships to the selection list.
        // TODO: optimize, spatial grid hash?
        for (uint32 i = 0; i < game_state->ship_count; ++i)
        {
            struct Ship *ship = &game_state->ships[i];
            struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size);

            vec2 center = vec2_div(vec2_add(ship_aabb.min, ship_aabb.max), 2.0f);

            if (aabb_aabb_intersection(world_selection_box, ship_aabb))
                game_state->selected_ships[game_state->selected_ship_count++] = ship->id;
        }

        if (game_state->selected_ship_count > 0)
            fprintf(stderr, "selected %u ships\n", game_state->selected_ship_count);
    }

    if (mouse_down(MOUSE_RIGHT, input))
    {
        vec2 target_position = screen_to_world_coords(input->mouse_position, &game_state->camera, screen_width, screen_height);

        for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
        {
            uint32 id = game_state->selected_ships[i];
            struct Ship *ship = get_ship_by_id(game_state, id);

            ship->target_position = target_position;
            ship->move_order = true;
        }
    }

    // Outline selected ships.
    for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
    {
        uint32 id = game_state->selected_ships[i];
        struct Ship *ship = get_ship_by_id(game_state, id);

        draw_world_quad_buffered(render_buffer, ship->position, vec2_mul(ship->size, 1.1f), vec4_zero(), vec3_new(0, 1, 0));

        if (ship->move_order)
            draw_world_quad_buffered(render_buffer, ship->target_position, vec2_new(0.5f, 0.5f), vec4_zero(), vec3_new(0, 1, 0));
    }

    // Handle move orders.
    for (uint32 i = 0; i < game_state->ship_count; ++i)
    {
        struct Ship *ship = &game_state->ships[i];
        if (ship->move_order)
        {
            vec2 direction = vec2_zero();
            /*
            if (vec2_length2(direction) < FLOAT_EPSILON)
                direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
                */
            ship->move_velocity = vec2_mul(direction, 2.0f);

            /*
            vec2 direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
            ship->move_velocity = vec2_mul(direction, 2.0f);
            */

            if (vec2_distance2(ship->position, ship->target_position) < 0.1f)
            {
                ship->move_velocity = vec2_zero();
                ship->move_order = false;
            }
        }
    }

    tick_camera(input, &game_state->camera, dt);

    tick_combat(game_state, dt);
    tick_physics(game_state, dt);
}
示例#9
0
文件: gx.c 项目: LWSS/gx
static void tick_physics(struct GameState *game_state, float dt)
{
    // Projectile kinematics.
    for (uint32 i = 0; i < game_state->projectile_count; ++i)
    {
        struct Projectile *projectile = &game_state->projectiles[i];

        // r = r0 + (v*t) + (a*t^2)/2
        projectile->position = vec2_add(projectile->position, vec2_mul(projectile->velocity, dt));
    }

    // Ship kinematics.
    for (uint32 i = 0; i < game_state->ship_count; ++i)
    {
        struct Ship *ship = &game_state->ships[i];

        vec2 move_acceleration = vec2_zero();

        // v = v0 + (a*t)
        ship->move_velocity = vec2_add(ship->move_velocity, vec2_mul(move_acceleration, dt));

        // r = r0 + (v*t) + (a*t^2)/2
        ship->position = vec2_add(vec2_add(ship->position, vec2_mul(ship->move_velocity, dt)), vec2_div(vec2_mul(move_acceleration, dt * dt), 2.0f));
    }

    //
    // TODO: spatial hashing
    //

    // Projectile collision.
    for (uint32 i = 0; i < game_state->projectile_count; ++i)
    {
        struct Projectile *projectile = &game_state->projectiles[i];
        struct AABB projectile_aabb = aabb_from_transform(projectile->position, projectile->size);

        // Projectile-building collision.
        for (uint32 j = 0; j < game_state->building_count; ++j)
        {
            struct Building *building = &game_state->buildings[j];
            struct AABB building_aabb = aabb_from_transform(building->position, building->size);

            if (aabb_aabb_intersection(projectile_aabb, building_aabb))
            {
                // TODO: damage building if not friendly
                destroy_projectile(game_state, projectile);
                break;
            }
        }

        // NOTE: owner may be dead and destroyed at this point, so checking for NULL might be required.
        struct Ship *owner = get_ship_by_id(game_state, projectile->owner);

        // Projectile-ship collision.
        for (uint32 j = 0; j < game_state->ship_count; ++j)
        {
            struct Ship *ship = &game_state->ships[j];
            if (ship->id == projectile->owner)
                continue;

#if 0
            // Allow projectiles to pass through teammates.
            if (ship->team == projectile->team)
                continue;
#endif

            struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size);

            if (aabb_aabb_intersection(projectile_aabb, ship_aabb))
            {
                // Disable friendly fire.
                if (ship->team != projectile->team)
                    damage_ship(game_state, ship, projectile->damage);

                destroy_projectile(game_state, projectile);
                break;
            }
        }
    }

    // TODO: optimize
    // Ship collision.
    if (game_state->ship_count >= 2)
    {
        for (uint32 i = 0; i < game_state->ship_count - 1; ++i)
        {
            struct Ship *a = &game_state->ships[i];
            struct AABB a_aabb = aabb_from_transform(a->position, a->size);
            vec2 a_center = vec2_div(vec2_add(a_aabb.min, a_aabb.max), 2.0f);
            vec2 a_half_extents = vec2_div(vec2_sub(a_aabb.max, a_aabb.min), 2.0f);

            // Ship-building collision.
            for (uint32 j = 0; j < game_state->building_count; ++j)
            {
                struct Building *building = &game_state->buildings[j];
                struct AABB b_aabb = aabb_from_transform(building->position, building->size);

                if (aabb_aabb_intersection(a_aabb, b_aabb))
                {
                    vec2 b_center = vec2_div(vec2_add(b_aabb.min, b_aabb.max), 2.0f);
                    vec2 b_half_extents = vec2_div(vec2_sub(b_aabb.max, b_aabb.min), 2.0f);

                    vec2 intersection = vec2_sub(vec2_abs(vec2_sub(b_center, a_center)), vec2_add(a_half_extents, b_half_extents));
                    if (intersection.x > intersection.y)
                    {
                        a->move_velocity.x = 0.0f;

                        if (a->position.x < building->position.x)
                            a->position.x += intersection.x/2.0f;
                        else
                            a->position.x -= intersection.x/2.0f;
                    }
                    else
                    {
                        a->move_velocity.y = 0.0f;

                        if (a->position.y < building->position.y)
                            a->position.y += intersection.y/2.0f;
                        else
                            a->position.y -= intersection.y/2.0f;
                    }
                }
            }

            // Ship-ship collision.
            for (uint32 j = i + 1; j < game_state->ship_count; ++j)
            {
                struct Ship *b = &game_state->ships[j];
                struct AABB b_aabb = aabb_from_transform(b->position, b->size);

                if (aabb_aabb_intersection(a_aabb, b_aabb))
                {
                    vec2 b_center = vec2_div(vec2_add(b_aabb.min, b_aabb.max), 2.0f);
                    vec2 b_half_extents = vec2_div(vec2_sub(b_aabb.max, b_aabb.min), 2.0f);

                    vec2 intersection = vec2_sub(vec2_abs(vec2_sub(b_center, a_center)), vec2_add(a_half_extents, b_half_extents));
                    if (intersection.x > intersection.y)
                    {
                        if (abs_float(a->move_velocity.x) > abs_float(b->move_velocity.x))
                            a->move_velocity.x = 0.0f;
                        else
                            b->move_velocity.x = 0.0f;

                        if (a->position.x < b->position.x)
                        {
                            a->position.x += intersection.x/2.0f;
                            b->position.x -= intersection.x/2.0f;
                        }
                        else
                        {
                            a->position.x -= intersection.x/2.0f;
                            b->position.x += intersection.x/2.0f;
                        }
                    }
                    else
                    {
                        if (abs_float(a->move_velocity.y) > abs_float(b->move_velocity.y))
                            a->move_velocity.y = 0.0f;
                        else
                            b->move_velocity.y = 0.0f;

                        if (a->position.y < b->position.y)
                        {
                            a->position.y += intersection.y/2.0f;
                            b->position.y -= intersection.y/2.0f;
                        }
                        else
                        {
                            a->position.y -= intersection.y/2.0f;
                            b->position.y += intersection.y/2.0f;
                        }
                    }
                }
            }
        }
    }
}
示例#10
0
文件: gx.c 项目: LWSS/gx
static void tick_camera(struct Input *input, struct Camera *camera, float dt)
{
    //
    // move
    //

    vec2 camera_up = vec2_direction(camera->rotation);
    vec2 camera_right = vec2_direction(camera->rotation - PI_OVER_TWO);

    vec2 move_acceleration = vec2_zero();
    if (key_down(GLFW_KEY_W, input))
        move_acceleration = vec2_add(move_acceleration, camera_up);
    if (key_down(GLFW_KEY_A, input))
        move_acceleration = vec2_add(move_acceleration, vec2_negate(camera_right));
    if (key_down(GLFW_KEY_S, input))
        move_acceleration = vec2_add(move_acceleration, vec2_negate(camera_up));
    if (key_down(GLFW_KEY_D, input))
        move_acceleration = vec2_add(move_acceleration, camera_right);

    if (vec2_length2(move_acceleration) > FLOAT_EPSILON)
    {
        const float acceleration_magnitude = camera->zoom * 10.0f;
        move_acceleration = vec2_normalize(move_acceleration);
        move_acceleration = vec2_mul(move_acceleration, acceleration_magnitude);

        // v = v0 + (a*t)
        camera->move_velocity = vec2_add(camera->move_velocity, vec2_mul(move_acceleration, dt));

        // Clamp move velocity.
        const float max_move_speed = 5.0f * sqrtf(camera->zoom);
        if (vec2_length2(camera->move_velocity) > (max_move_speed * max_move_speed))
            camera->move_velocity = vec2_mul(vec2_normalize(camera->move_velocity), max_move_speed);
    }

    // Number of seconds required for friction to stop movement completely.
    // (because velocity is sampled each frame, actual stop time longer than this)
    float stop_time = 0.1f;
    float inv_stop_time = 1.0f / stop_time;

    if (move_acceleration.x == 0.0f)
        camera->move_velocity.x -= camera->move_velocity.x * inv_stop_time * dt;
    if (move_acceleration.y == 0.0f)
        camera->move_velocity.y -= camera->move_velocity.y * inv_stop_time * dt;

    // r = r0 + (v0*t) + (a*t^2)/2
    camera->position = vec2_add(vec2_add(camera->position, vec2_mul(camera->move_velocity, dt)), vec2_div(vec2_mul(move_acceleration, dt * dt), 2.0f));


    //
    // zoom
    //

    float zoom_acceleration = 0.0f;
    if (key_down(GLFW_KEY_SPACE, input))
        zoom_acceleration += 1.0f;
    if (key_down(GLFW_KEY_LEFT_CONTROL, input))
        zoom_acceleration -= 1.0f;
    zoom_acceleration *= camera->zoom * 50.0f;

    if (zoom_acceleration == 0.0f)
        camera->zoom_velocity -= camera->zoom_velocity * (1.0f / 0.1f) * dt;

    // v = v0 + (a*t)
    camera->zoom_velocity += zoom_acceleration * dt;

    // r = r0 + (v0*t) + (a*t^2)/2
    camera->zoom += (camera->zoom_velocity * dt) + (zoom_acceleration * dt * dt) / 2.0f;

    // Clamp zoom velocity.
    const float max_zoom_speed = 3.0f * camera->zoom;
    camera->zoom_velocity = clamp_float(camera->zoom_velocity, -max_zoom_speed, max_zoom_speed);

    float unclamped_zoom = camera->zoom;
    camera->zoom = clamp_float(camera->zoom, 1.0f, 1000.0f);
    if (camera->zoom != unclamped_zoom)
        camera->zoom_velocity = 0.0f;
}