-
Notifications
You must be signed in to change notification settings - Fork 1
resolution #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
resolution #1
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| pub fn format_squares_numbers(moon_squares: u32, sun_squares: u32) -> String { | ||
| let moon_formatted = format!("{:03}", moon_squares); | ||
| let sun_formatted = format!("{:03}", sun_squares); | ||
| format!("Moon {} | Sun {}", moon_formatted, sun_formatted) | ||
| } | ||
| format!("{} | {}", moon_formatted, sun_formatted) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,51 @@ | ||
| use std::fmt::Alignment; | ||
|
|
||
| use ggez::mint::Point2; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused import: |
||
| use ggez::timer; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused import: |
||
| use ggez::{graphics, Context, GameResult, event::EventHandler}; | ||
| use ggez::graphics::{Text, TextFragment, Color as GgezColor}; | ||
| use ggez::graphics::{Color, Drawable, Text, TextFragment}; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused import: |
||
| use nalgebra::Vector2; | ||
| use rand::Rng; | ||
|
|
||
| use crate::utils::count_objects; | ||
| use crate::utils::{count_objects, lerp_color}; | ||
| use crate::object::{Object, Team, ObjectKind}; | ||
| use crate::formatter::format_squares_numbers; | ||
|
|
||
| pub mod game_constants { | ||
| pub mod game_constants { | ||
| pub const ROW_SIZE: i32 = 20; | ||
| pub const COLUMN_SIZE: i32 = 10; | ||
|
|
||
| pub const CIRCLE_SIZE: f32 = 25.0; | ||
| pub const SQUARE_SIZE: f32 = 50.0; | ||
|
|
||
| pub const FIELD_START_Y: f32 = 100.0; | ||
| pub const FIELD_START_X: f32 = 128.0; | ||
|
|
||
| pub const FIELD_WIDTH: f32 = (SQUARE_SIZE * 2.0) * COLUMN_SIZE as f32; | ||
| pub const FIELD_HEIGHT: f32 = (SQUARE_SIZE) * ROW_SIZE as f32; | ||
|
|
||
| pub const MOVEMENT_SPEED: f32 = 15.0; | ||
| } | ||
|
|
||
|
|
||
| pub struct Game { | ||
| window_width: f32, | ||
| window_height: f32, | ||
| scale_factor: f32, | ||
| bounds: (f32, f32), | ||
|
|
||
| squares: Vec<Object>, | ||
| sun_circle: Object, | ||
| moon_circle: Object, | ||
|
|
||
| background_color: Color, | ||
| target_background_color: Color, | ||
| transition_duration: f32, | ||
| transition_timer: f32, | ||
| } | ||
|
|
||
| impl Game { | ||
| pub fn new(ctx: &mut Context) -> Self { | ||
| let (window_width, window_height) = ctx.gfx.drawable_size(); | ||
| let scale_factor = window_width / game_constants::FIELD_WIDTH; | ||
|
|
||
| let mut rng = rand::thread_rng(); | ||
|
|
||
| let moon_x_sign = if rng.gen::<bool>() { 1.0 } else { -1.0 }; | ||
|
|
@@ -39,46 +54,70 @@ impl Game { | |
| let sun_x_sign = if rng.gen::<bool>() { 1.0 } else { -1.0 }; | ||
| let sun_y_sign = if rng.gen::<bool>() { 1.0 } else { -1.0 }; | ||
|
|
||
| let moon_pos = (window_width * 0.7, window_height * 0.6); | ||
| let sun_pos = (window_width * 0.35, window_height * 0.6); | ||
|
|
||
| let field_start_x: f32 = (window_width - game_constants::FIELD_WIDTH) / 2.0; | ||
| let field_start_y: f32 = (window_height - game_constants::FIELD_HEIGHT) / 2.0; | ||
|
|
||
| let bounds = (field_start_x, field_start_y); | ||
|
|
||
| let background_color = Color::from_rgb(0xF7, 0xC5, 0x9F); | ||
| let target_background_color = Color::from_rgb(0x2A, 0x32, 0x4B); | ||
| let transition_duration = 2.0; | ||
| let transition_timer = 0.0; | ||
|
|
||
| let moon_circle = Object { | ||
| position: (870.0, 650.0), | ||
| position: moon_pos, | ||
| team: Team::MOON, | ||
| kind: ObjectKind::Circle, | ||
| direction: Vector2::new( | ||
| moon_x_sign * 1.5 * game_constants::MOVEMENT_SPEED, | ||
| moon_y_sign * 1.5 * game_constants::MOVEMENT_SPEED | ||
| ) | ||
| ), | ||
|
|
||
| }; | ||
|
|
||
| let sun_circle = Object { | ||
| position: (385.5, 650.0), | ||
| position: sun_pos, | ||
| team: Team::SUN, | ||
| kind: ObjectKind::Circle, | ||
| direction: Vector2::new( | ||
| sun_x_sign * 1.5 * game_constants::MOVEMENT_SPEED, | ||
| sun_y_sign * 1.5 * game_constants::MOVEMENT_SPEED | ||
| ) | ||
| ), | ||
|
|
||
| }; | ||
|
|
||
|
|
||
| let mut squares = Vec::new(); | ||
|
|
||
| for row in 0..game_constants::ROW_SIZE { | ||
| for column in 0..game_constants::COLUMN_SIZE { | ||
| squares.push(Object { | ||
| position: (game_constants::FIELD_START_X + (column as f32) * game_constants::SQUARE_SIZE, game_constants::FIELD_START_Y + (row as f32) * game_constants::SQUARE_SIZE), | ||
| position: ( | ||
| (field_start_x + (column as f32) * game_constants::SQUARE_SIZE), | ||
| (field_start_y + (row as f32) * game_constants::SQUARE_SIZE), | ||
| ), | ||
| team: Team::MOON, | ||
| kind: ObjectKind::Square, | ||
| direction: Vector2::new(0.0, 0.0), | ||
|
|
||
| }); | ||
| } | ||
| } | ||
|
|
||
| for row in 0..game_constants::ROW_SIZE { | ||
| for column in 0..game_constants::COLUMN_SIZE { | ||
| squares.push(Object { | ||
| position: (game_constants::FIELD_START_X + (column as f32) * game_constants::SQUARE_SIZE + (game_constants::COLUMN_SIZE as f32) * game_constants::SQUARE_SIZE, game_constants::FIELD_START_Y + (row as f32) * game_constants::SQUARE_SIZE), | ||
| position: ( | ||
| (field_start_x + (column as f32) * game_constants::SQUARE_SIZE + (game_constants::COLUMN_SIZE as f32) * game_constants::SQUARE_SIZE), | ||
| (field_start_y + (row as f32) * game_constants::SQUARE_SIZE), | ||
| ), | ||
| team: Team::SUN, | ||
| kind: ObjectKind::Square, | ||
| direction: Vector2::new(0.0, 0.0), | ||
|
|
||
| }); | ||
| } | ||
| } | ||
|
|
@@ -94,52 +133,102 @@ impl Game { | |
| } | ||
|
|
||
| Game { | ||
| window_height, | ||
| window_width, | ||
| scale_factor, | ||
| bounds, | ||
|
|
||
| squares, | ||
| sun_circle, | ||
| moon_circle, | ||
|
|
||
| background_color, | ||
| target_background_color, | ||
| transition_duration, | ||
| transition_timer, | ||
| } | ||
| } | ||
|
|
||
| fn update_background_color(&mut self, dt: f32) { | ||
| if self.transition_timer < self.transition_duration { | ||
| self.transition_timer += dt; | ||
| let t = self.transition_timer / self.transition_duration; | ||
| self.background_color = lerp_color(self.background_color, self.target_background_color, t); | ||
| } | ||
| } | ||
|
|
||
| fn set_target_background_color(&mut self, target_color: Color, duration: f32) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. method |
||
| self.target_background_color = target_color; | ||
| self.transition_duration = duration; | ||
| self.transition_timer = 0.0; | ||
| } | ||
| } | ||
|
|
||
| impl EventHandler for Game { | ||
| fn update(&mut self, _: &mut Context) -> GameResult { | ||
| fn update(&mut self, ctx: &mut Context) -> GameResult { | ||
| self.sun_circle.update_position(); | ||
| self.moon_circle.update_position(); | ||
| self.sun_circle.handle_boundary_collision(); | ||
| self.moon_circle.handle_boundary_collision(); | ||
|
|
||
| self.sun_circle.handle_boundary_collision(self.bounds); | ||
| self.moon_circle.handle_boundary_collision(self.bounds); | ||
|
|
||
| for square in &mut self.squares { | ||
| self.sun_circle.handle_collision(square); | ||
| self.moon_circle.handle_collision(square); | ||
| } | ||
|
|
||
| let dt = ctx.time.delta().as_secs_f32(); | ||
| self.update_background_color(dt); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| fn draw(&mut self, ctx: &mut Context) -> GameResult { | ||
| let canvas_color = GgezColor::from_rgb_u32(0x767B91); | ||
| let mut canvas = graphics::Canvas::from_frame(ctx, canvas_color); | ||
| let captured = count_objects(&self.squares, Team::MOON); | ||
|
|
||
| let dest_point = ggez::glam::Vec2::new(428.0, 1180.0); | ||
| let font_color = GgezColor::from_rgb_u32(0xE1E5EE); | ||
| let text_fragment = TextFragment::new(format_squares_numbers(count_objects(&self.squares, Team::MOON), count_objects(&self.squares, Team::SUN))) | ||
| .font("LiberationMono") | ||
| .scale(40.0) | ||
| .color(font_color); | ||
| canvas.draw( | ||
| &Text::new(text_fragment), | ||
| dest_point, | ||
| ); | ||
| let max_cells = game_constants::ROW_SIZE * game_constants::COLUMN_SIZE; | ||
|
|
||
| for square in &mut self.squares { | ||
| square.draw(ctx, &mut canvas)?; | ||
| } | ||
| let darkness_level = captured as f32 / max_cells as f32; | ||
|
|
||
| let start_color = [0xF7, 0xC5, 0x9F]; | ||
| let end_color = [0x2A, 0x32, 0x4B]; | ||
|
|
||
| let interpolated_color = [ | ||
| (start_color[0] as f32 + (end_color[0] as f32 - start_color[0] as f32) * darkness_level) as u8, | ||
| (start_color[1] as f32 + (end_color[1] as f32 - start_color[1] as f32) * darkness_level) as u8, | ||
| (start_color[2] as f32 + (end_color[2] as f32 - start_color[2] as f32) * darkness_level) as u8, | ||
| ]; | ||
|
|
||
| let canvas_color = Color::from_rgb(interpolated_color[0], interpolated_color[1], interpolated_color[2]); | ||
|
|
||
| let mut canvas = graphics::Canvas::from_frame(ctx, canvas_color); | ||
|
|
||
| for i in 0..self.squares.len() { | ||
| self.squares[i].draw(ctx, &mut canvas)?; | ||
| } | ||
|
|
||
| self.sun_circle.draw(ctx, &mut canvas)?; | ||
| self.moon_circle.draw(ctx, &mut canvas)?; | ||
|
|
||
|
|
||
| let font_color = Color::from_rgb_u32(0xE1E5EE); | ||
| let text_fragment = TextFragment::new(format_squares_numbers(count_objects(&self.squares, Team::MOON), count_objects(&self.squares, Team::SUN))) | ||
| .font("LiberationMono") | ||
| .scale(40.0 * self.scale_factor) | ||
| .color(font_color); | ||
|
|
||
| let text = Text::new(text_fragment); | ||
| let text_dimensions = text.measure(ctx)?; | ||
|
|
||
| let x = (self.window_width - text_dimensions.x) / 2.0; | ||
| let y = self.window_height - text_dimensions.y; | ||
|
|
||
| let dest_point = ggez::glam::Vec2::new(x, y); | ||
|
|
||
| canvas.draw(&text, dest_point); | ||
|
|
||
| canvas.finish(ctx)?; | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,9 +18,13 @@ fn main() { | |
| }; | ||
|
|
||
| let result = ContextBuilder::new("Moon & Sun", "wedyarit") | ||
| .window_mode(conf::WindowMode::default().dimensions(1280.0, 1280.0)) | ||
| .window_mode(conf::WindowMode::default() | ||
| .maximized(true) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume there is no need to set the default maximum window size. Window size should be comfortable. |
||
| .resizable(false)) | ||
| .add_resource_path(resource_dir) | ||
| .window_setup(conf::WindowSetup::default().title("Moon & Sun").icon("/icon.png")) | ||
| .window_setup(conf::WindowSetup::default() | ||
| .title("Moon & Sun") | ||
| .icon("/icon.png")) | ||
| .build(); | ||
| let (mut ctx, event_loop) = match result { | ||
| Ok((ctx, event_loop)) => (ctx, event_loop), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused import:
std::fmt::Alignment