Browse Source

saturation and lightness configurable from pause menu

master
Inderjit Gill 1 year ago
parent
commit
7fd75eead9
2 changed files with 213 additions and 69 deletions
  1. +203
    -63
      src/game.rs
  2. +10
    -6
      src/lib.rs

+ 203
- 63
src/game.rs View File

@@ -60,7 +60,7 @@ impl CachedHSLuv {
s,
l,
a,
cached_rgb: rgb
cached_rgb: rgb,
}
}
}
@@ -102,35 +102,26 @@ impl Block {
self.hsl = self.flashing_dull_colour;
}

pub fn updated_saturation_and_lightness(&mut self, saturation: f32, lightness: f32) {
self.hsl = CachedHSLuv::new(self.hsl.h, saturation, lightness, self.hsl.a);

// also calculate the flashing colours now
let bright_l = clampf(self.hsl.l + 20.0, 0.0, 100.0);
self.flashing_bright_colour =
CachedHSLuv::new(self.hsl.h, self.hsl.s, bright_l, self.hsl.a);

let dull_l = clampf(self.hsl.l - 20.0, 0.0, 100.0);
self.flashing_dull_colour = CachedHSLuv::new(self.hsl.h, self.hsl.s, dull_l, self.hsl.a);
}

pub fn set(&mut self, occupied: bool, hsl: &CachedHSLuv) {
self.occupied = occupied;
if occupied {
// set the colour straight away if it's occupied
// (unoccupied blocks will fade out, see update_block_colours)

self.hsl = *hsl;

// also calculate the flashing colours now
let bright_l = clampf(hsl.l + 20.0, 0.0, 100.0);
if let Ok(bright) = get_colour_from_hsl(hsl.h, hsl.s, bright_l, 1.0) { // 70
self.flashing_bright_colour = CachedHSLuv {
h: hsl.h,
s: hsl.s,
l: bright_l,
a: hsl.a,
cached_rgb: bright,
};
}
let dull_l = clampf(hsl.l - 20.0, 0.0, 100.0);
if let Ok(dull) = get_colour_from_hsl(hsl.h, hsl.s, dull_l, 1.0) { // 30
self.flashing_dull_colour = CachedHSLuv {
h: hsl.h,
s: hsl.s,
l: dull_l,
a: hsl.a,
cached_rgb: dull,
};
}
self.hsl.h = hsl.h;
self.hsl.a = hsl.a;
self.updated_saturation_and_lightness(hsl.s, hsl.l);
}
}
}
@@ -147,10 +138,12 @@ impl Board {
pub fn new(config: &Config) -> Board {
// width: usize, height: usize, inactive_colour: Col, crt_update_speed: f32

let cached_inactive_colour = CachedHSLuv::new(config.block_inactive_col_h,
config.block_inactive_col_s,
config.block_inactive_col_l,
config.block_inactive_col_a);
let cached_inactive_colour = CachedHSLuv::new(
config.block_inactive_col_h,
config.colour_saturation,
config.colour_lightness,
config.block_inactive_col_a,
);

let width = config.board_width;
let height = config.board_height;
@@ -174,12 +167,40 @@ impl Board {
}

pub fn reconfigure(&mut self, config: &Config) {
self.inactive_colour = CachedHSLuv::new(config.block_inactive_col_h,
config.block_inactive_col_s,
config.block_inactive_col_l,
config.block_inactive_col_a);
self.inactive_colour = CachedHSLuv::new(
config.block_inactive_col_h,
config.colour_saturation,
config.colour_lightness,
config.block_inactive_col_a,
);

self.update_blocks_saturation_and_lightness(
config.colour_saturation,
config.colour_lightness,
);
}

pub fn updated_saturation_and_lightness(&mut self, saturation: f32, lightness: f32) {
self.inactive_colour = CachedHSLuv::new(
self.inactive_colour.h,
saturation,
lightness,
self.inactive_colour.a,
);

self.update_blocks_saturation_and_lightness(saturation, lightness);
}

// todo: update the existing board state with the config.colour_saturation and config.colour_lightness
fn update_blocks_saturation_and_lightness(&mut self, saturation: f32, lightness: f32) {
for line in 0..self.height {
for x in 0..self.width {
if self.board[line][x].occupied {
self.board[line][x].updated_saturation_and_lightness(saturation, lightness);
} else {
self.board[line][x].deactivate(&self.inactive_colour);
}
}
}
}

pub fn set_crt_update_speed(&mut self, new_crt_update_speed: f32) {
@@ -298,6 +319,10 @@ pub struct Game {
menu_max_crt_update_speed: i32,
menu_curvature: i32,
menu_max_curvature: i32,
menu_saturation: i32,
menu_max_saturation: i32,
menu_lightness: i32,
menu_max_lightness: i32,

is_game_over: bool,

@@ -358,7 +383,7 @@ impl Game {
colour_saturation: config.colour_saturation,
colour_lightness: config.colour_lightness,

menu_num_items: 5,
menu_num_items: 7,
menu_active_item: 0,
menu_volume: config.menu_volume,
menu_max_volume: config.menu_max_volume,
@@ -366,6 +391,10 @@ impl Game {
menu_max_crt_update_speed: config.menu_max_crt_update_speed,
menu_curvature: config.menu_curvature,
menu_max_curvature: config.menu_max_curvature,
menu_saturation: config.menu_saturation,
menu_max_saturation: config.menu_max_saturation,
menu_lightness: config.menu_lightness,
menu_max_lightness: config.menu_max_lightness,

is_game_over: false,

@@ -477,10 +506,12 @@ impl Game {
render_lines(geometry, self.lines, Block2D { x, y: y + 6 }, c);
}
if let Some(shape) = self.shapes.get(&self.next_piece_shape) {
if let Ok(colour) = get_colour_from_hsl(self.next_piece_hue,
self.colour_saturation,
self.colour_lightness,
1.0) {
if let Ok(colour) = get_colour_from_hsl(
self.next_piece_hue,
self.colour_saturation,
self.colour_lightness,
1.0,
) {
render_next_shape(geometry, &shape, Block2D { x, y }, colour);
}
}
@@ -602,11 +633,7 @@ impl Game {

if piece_cant_go_lower {
if let Some(shape) = self.shapes.get(&self.piece.shape_kind) {
add_shape_to_board(
&mut self.board,
shape,
&self.piece
);
add_shape_to_board(&mut self.board, shape, &self.piece);

if any_complete_lines(&self.board) {
let num_lines = num_complete_lines(&self.board);
@@ -640,7 +667,7 @@ impl Game {
}
}
}
},
}
GameState::PieceIsDropping => {
apply_user_input(self, controller, delta);

@@ -657,12 +684,11 @@ impl Game {
}
}
}
},
}
GameState::LinesFlashing => {
self.lines_flashing_time += delta;
self.board.flash_complete_lines(self.lines_flashing_time);
if self.lines_flashing_time > 500.0 {

if self.lines_flashing_time > 600.0 {
let num_lines = remove_complete_lines(&mut self.board)?;
update_score(self, num_lines);

@@ -672,11 +698,7 @@ impl Game {
}

if let Some(shape) = self.shapes.get(&self.piece.shape_kind) {
add_shape_to_board(
&mut self.board,
shape,
&self.piece
);
add_shape_to_board(&mut self.board, shape, &self.piece);
}

// update the colour of all the blocks that aren't occupied
@@ -729,7 +751,12 @@ fn use_next_shape(game: &mut Game, random: f32) -> error::Result<()> {
game.piece.pos.x = ((game.board.width as i32) - shape.aabb_width) / 2;
game.piece.pos.y = (game.board.height as i32) - shape.real_height;
game.piece.angle = PieceAngle::R0;
game.piece.colour = CachedHSLuv::new(game.next_piece_hue, game.colour_saturation, game.colour_lightness, 1.0);
game.piece.colour = CachedHSLuv::new(
game.next_piece_hue,
game.colour_saturation,
game.colour_lightness,
1.0,
);
}

match game.piece.shape_kind {
@@ -755,7 +782,12 @@ fn get_colour_from_hsl(
lightness: f32,
alpha: f32,
) -> error::Result<Col> {
let hsluv = Colour::HSLuv(hue as f64, saturation as f64, lightness as f64, alpha as f64);
let hsluv = Colour::HSLuv(
hue as f64,
saturation as f64,
lightness as f64,
alpha as f64,
);
col_from_colour(&hsluv)
}

@@ -971,7 +1003,7 @@ fn is_colliding(board: &Board, shape: &Shape, pos: &BoardPos, angle: &PieceAngle
fn any_complete_lines(board: &Board) -> bool {
for y in 0..board.height {
if board.is_line_filled(y) {
return true
return true;
}
}
false
@@ -1002,11 +1034,7 @@ fn remove_complete_lines(board: &mut Board) -> error::Result<i32> {
Ok(offset as i32)
}

fn add_shape_to_board(
board: &mut Board,
shape: &Shape,
piece: &Piece
) {
fn add_shape_to_board(board: &mut Board, shape: &Shape, piece: &Piece) {
let pos = &piece.pos;
let angle = &piece.angle;
let colour = &piece.colour;
@@ -1097,7 +1125,7 @@ fn move_cached_col_closer(src: &CachedHSLuv, dest: &CachedHSLuv, delta: f32) ->
move_f32_closer(src.cached_rgb.g, dest.cached_rgb.g, delta),
move_f32_closer(src.cached_rgb.b, dest.cached_rgb.b, delta),
move_f32_closer(src.cached_rgb.a, dest.cached_rgb.a, delta),
)
),
}
}

@@ -1263,7 +1291,41 @@ fn update_pause_menu(game: &mut Game, controller: &Controller, random: f32) -> b
game.menu_curvature = clamp(game.menu_curvature, 0, game.menu_max_curvature);
}

// saturation
if game.menu_active_item == 4 {
if controller.just_pressed(ControllerButton::Left) {
game.menu_saturation -= 1;
update = true;
}
if controller.just_pressed(ControllerButton::Right) {
game.menu_saturation += 1;
update = true;
}
game.menu_saturation = clamp(game.menu_saturation, 0, game.menu_max_saturation);

if update {
update_saturation(game);
}
}

// lightness
if game.menu_active_item == 5 {
if controller.just_pressed(ControllerButton::Left) {
game.menu_lightness -= 1;
update = true;
}
if controller.just_pressed(ControllerButton::Right) {
game.menu_lightness += 1;
update = true;
}
game.menu_lightness = clamp(game.menu_lightness, 0, game.menu_max_lightness);

if update {
update_lightness(game);
}
}

if game.menu_active_item == 6 {
if controller.just_pressed(ControllerButton::Start) {
let _ = game.restart(random);
update = true;
@@ -1276,6 +1338,68 @@ fn update_pause_menu(game: &mut Game, controller: &Controller, random: f32) -> b
update
}

fn mc_m(xa: f32, ya: f32, xb: f32, yb: f32) -> f32 {
(ya - yb) / (xa - xb)
}

fn mc_c(xa: f32, ya: f32, m: f32) -> f32 {
ya - (m * xa)
}

fn remap(val: f32, from_a: f32, from_b: f32, to_a: f32, to_b: f32, clamping: bool) -> f32 {
let from_m = mc_m(from_a, 0.0, from_b, 1.0);
let from_c = mc_c(from_a, 0.0, from_m);

let to_m = mc_m(0.0, to_a, 1.0, to_b);
let to_c = mc_c(0.0, to_a, to_m);

let from_interp = (from_m * val) + from_c;
let to_interp = from_interp;

let mut res = (to_m * to_interp) + to_c;

if clamping {
res = if from_interp < 0.0 {
to_a
} else if from_interp > 1.0 {
to_b
} else {
res
}
}

res
}

fn update_saturation(game: &mut Game) {
game.colour_saturation = remap(
game.menu_saturation as f32,
0.0,
game.menu_max_saturation as f32,
40.0,
100.0,
true,
);
// log(&format!("saturation: {}", game.colour_saturation));

game.board
.updated_saturation_and_lightness(game.colour_saturation, game.colour_lightness);
}

fn update_lightness(game: &mut Game) {
game.colour_lightness = remap(
game.menu_lightness as f32,
0.0,
game.menu_max_lightness as f32,
30.0,
90.0,
true,
);
// log(&format!("lightness: {}", game.colour_lightness));
game.board
.updated_saturation_and_lightness(game.colour_saturation, game.colour_lightness);
}

fn update_audio_volume(game: &Game) {
let volume = game.menu_volume as f32 / game.menu_max_volume as f32;
audio_volume(volume);
@@ -1350,7 +1474,21 @@ fn render_pause_menu(
game.menu_max_curvature,
game.menu_curvature,
);
let restart = build_menu_item(game, 4, "Restart");
let saturation = build_menu_item_slider(
game,
4,
"Saturation ",
game.menu_max_saturation,
game.menu_saturation,
);
let lightness = build_menu_item_slider(
game,
5,
"Lightness ",
game.menu_max_lightness,
game.menu_lightness,
);
let restart = build_menu_item(game, 6, "Restart");

// remember to update Game::menu_num_items when adding another menu option

@@ -1359,6 +1497,8 @@ fn render_pause_menu(
&vol[..],
&crt_update_speed[..],
&curvature[..],
&saturation[..],
&lightness[..],
&restart[..],
];


+ 10
- 6
src/lib.rs View File

@@ -97,8 +97,6 @@ pub struct Config {
pub board_height: usize,

pub block_inactive_col_h: f32,
pub block_inactive_col_s: f32,
pub block_inactive_col_l: f32,
pub block_inactive_col_a: f32,

pub menu_volume: i32,
@@ -107,6 +105,10 @@ pub struct Config {
pub menu_max_crt_update_speed: i32,
pub menu_curvature: i32,
pub menu_max_curvature: i32,
pub menu_saturation: i32,
pub menu_max_saturation: i32,
pub menu_lightness: i32,
pub menu_max_lightness: i32,
}

#[wasm_bindgen]
@@ -129,8 +131,8 @@ impl Config {
sprite_width: 16,
sprite_height: 16,

colour_saturation: 85.0,
colour_lightness: 50.0,
colour_saturation: 88.0,
colour_lightness: 54.0,

board_offset_x: 1,
board_offset_y: 1,
@@ -141,8 +143,6 @@ impl Config {
board_height: 20,

block_inactive_col_h: 111.1,
block_inactive_col_s: 100.0,
block_inactive_col_l: 57.7,
block_inactive_col_a: 0.1,

menu_volume: 5,
@@ -151,6 +151,10 @@ impl Config {
menu_max_crt_update_speed: 5,
menu_curvature: 3,
menu_max_curvature: 5,
menu_saturation: 4,
menu_max_saturation: 5,
menu_lightness: 2,
menu_max_lightness: 5,
}
}
}

Loading…
Cancel
Save