// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
//#define VG_STEAM
+//#define VG_STEAM_APPID 1218140U
#include "vg/vg.h"
#include "fishladder_resources.h"
k_fish_state_soon_dead = -1,
k_fish_state_dead = 0,
k_fish_state_alive,
- k_fish_state_bg
+ k_fish_state_bg,
+ k_fish_state_soon_alive
};
struct world
int simulating;
int sim_run, max_runs;
+ float sim_speed;
float frame_lerp;
struct cell_terminal
world.sim_frame = 0;
world.sim_start = vg_time;
world.sim_run = 0;
+ world.sim_speed = 2.5f;
for( int i = 0; i < world.w*world.h; i ++ )
world.data[ i ].state &= ~FLAG_FLIP_FLOP;
// Fish ticks
if( world.simulating )
{
- while( world.sim_frame < (int)((vg_time-world.sim_start)*2.0f) )
+ while( world.sim_frame < (int)((vg_time-world.sim_start)*world.sim_speed) )
{
//vg_info( "frame: %u\n", world.sim_frame );
sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 9 );
if( fish->state == k_fish_state_soon_dead )
fish->state = k_fish_state_dead;
+ if( fish->state == k_fish_state_soon_alive )
+ fish->state = k_fish_state_alive;
+
if( fish->state < k_fish_state_alive )
continue;
fish->state = world_check_pos_ok( fish->pos )? k_fish_state_bg: k_fish_state_dead;
}
- v2i_add( fish->pos, fish->dir, fish->pos );
+ //v2i_add( fish->pos, fish->dir, fish->pos );
}
else if( fish->state == k_fish_state_bg )
{
if( cell_entry->config == k_cell_type_con_r || cell_entry->config == k_cell_type_con_u
|| cell_entry->config == k_cell_type_con_l || cell_entry->config == k_cell_type_con_d )
{
- fish->state = k_fish_state_alive;
+ fish->state = k_fish_state_soon_alive;
fish->dir[0] = 0;
fish->dir[1] = 0;
if( fish->state == k_fish_state_alive )
{
+ v2i_add( fish->pos, fish->dir, fish->pos );
struct cell *cell_current = pcell( fish->pos );
if( cell_current->state & FLAG_IS_TRIGGER )
}
// Third pass (collisions)
+ struct fish *fi, *fj;
+
for( int i = 0; i < world.num_fishes; i ++ )
{
- if( world.fishes[i].state == k_fish_state_alive )
+ fi = &world.fishes[i];
+
+ if( fi->state == k_fish_state_alive )
{
+ int continue_again = 0;
+
for( int j = i+1; j < world.num_fishes; j ++ )
{
- if( (world.fishes[j].state == k_fish_state_alive) &&
- (world.fishes[i].pos[0] == world.fishes[j].pos[0]) &&
- (world.fishes[i].pos[1] == world.fishes[j].pos[1]) )
+ fj = &world.fishes[j];
+
+ if( (fj->state == k_fish_state_alive) )
{
- // Shatter death (+0.5s)
- world.fishes[i].state = k_fish_state_soon_dead;
- world.fishes[j].state = k_fish_state_soon_dead;
- world.fishes[i].death_time = 0.5f;
- world.fishes[j].death_time = 0.5f;
+ v2i fi_prev;
+ v2i fj_prev;
+
+ v2i_sub( fi->pos, fi->dir, fi_prev );
+ v2i_sub( fj->pos, fj->dir, fj_prev );
+
+ int
+ collide_next_frame = (
+ (fi->pos[0] == fj->pos[0]) &&
+ (fi->pos[1] == fj->pos[1]))? 1: 0,
+ collide_this_frame = (
+ (fi_prev[0] == fj->pos[0]) &&
+ (fi_prev[1] == fj->pos[1]) &&
+ (fj_prev[0] == fi->pos[0]) &&
+ (fj_prev[1] == fi->pos[1])
+ )? 1: 0;
+
+ if( collide_next_frame || collide_this_frame )
+ {
+ // Shatter death (+0.5s)
+ float death_time = collide_this_frame? 0.0f: 0.5f;
+
+ fi->state = k_fish_state_soon_dead;
+ fj->state = k_fish_state_soon_dead;
+ fi->death_time = death_time;
+ fj->death_time = death_time;
+
+ continue_again = 1;
+ break;
+ }
}
}
+ if( continue_again )
+ continue;
}
}
world.sim_frame = 0;
world.sim_start = vg_time;
world.num_fishes = 0;
+
+ for( int i = 0; i < world.w*world.h; i ++ )
+ world.data[ i ].state &= ~FLAG_FLIP_FLOP;
+
continue;
}
else
}
float scaled_time = 0.0f;
- scaled_time = (vg_time-world.sim_start)*2.0f;
+ scaled_time = (vg_time-world.sim_start)*world.sim_speed;
world.frame_lerp = scaled_time - (float)world.sim_frame;
// Update positions
vg_tex2d tex_tile_data = { .path = "textures/tileset.qoi" };
vg_tex2d tex_tile_detail = { .path = "textures/tile_overlays.qoi" };
vg_tex2d tex_wood = { .path = "textures/wood.qoi" };
-vg_tex2d tex_ball = { .path = "textures/ball.qoi", .flags = VG_TEXTURE_CLAMP };
vg_tex2d tex_background = { .path = "textures/background.qoi" };
vg_tex2d tex_ball_noise = { .path = "textures/bnoise.qoi" };
-vg_tex2d *texture_list[] = { &tex_tile_detail, &tex_tile_data, &tex_wood, &tex_ball, &tex_background, &tex_ball_noise };
+vg_tex2d *texture_list[] = { &tex_tile_detail, &tex_tile_data, &tex_wood, &tex_background, &tex_ball_noise };
// AUDIO
// ===========================================================================================================
UNIFORMS({ "uPv", "uOffset", "uColour" })
)
-/*
-SHADER_DEFINE( shader_ball,
- // VERTEX
- "layout (location=0) in vec2 a_co;"
- "uniform vec2 uOffset;"
- "uniform mat3 uPv;"
- ""
- "out vec2 aTexCoords;"
- ""
- "void main()"
- "{"
- // Create texture coords
- "aTexCoords = a_co;"
-
- // Vertex transform
- "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );"
- "gl_Position = vec4( uPv * worldpos, 1.0 );"
- "}",
-
- // FRAGMENT
- "out vec4 FragColor;"
- ""
- "uniform sampler2D uTexMain;"
- "uniform vec3 uColour;"
- ""
- "in vec2 aTexCoords;"
- ""
- "void main()"
- "{"
- "vec4 glyph = texture( uTexMain, aTexCoords );"
- "FragColor = vec4( uColour + glyph.rgb * 0.2, glyph.a );"
- "}"
- ,
- UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv" })
-)
-*/
-
SHADER_DEFINE( shader_ball,
// VERTEX
"layout (location=0) in vec2 a_co;"
"vec2 shadow_coords = center_coords + vec2(0.02,0.07);"
"vec2 shadow_coords_sqr = shadow_coords*shadow_coords;"
- //"float shadow = exp(-abs(shadow_coords_sqr.x+shadow_coords_sqr.y)*20.0);"
"float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);"
"vec3 marble_comp = uColour*0.9 + (noise_sample.x*0.7+pow(rim_light,3.0)*2.0) * 0.1;"