use crate::core::resources::Resources;
use crate::ui::grid::Grid;
use crate::plants::Plant;
use crate::entities::pea::Pea;
use crate::zombies::Zombie;
use crate::entities::sun::Sun;
use crate::ui::shop::Shop;
use crate::ui::shovel::Shovel;
use ggez::{Context, GameResult};
use ggez::graphics::{self, Color, DrawParam, Text, TextFragment};
pub struct Renderer;
impl Renderer {
pub fn draw_game(
ctx: &mut Context,
resources: &Resources,
grid: &Grid,
plants: &[Plant],
peas: &[Pea],
zombies: &[Zombie],
suns: &[Sun],
shop: &Shop,
sun_count: i32,
game_over: bool,
victory: bool,
show_final_wave: bool,
game_state: crate::core::states::GameState,
pause_button_rect: (f32, f32, f32, f32),
shovel: &Shovel,
is_initial_pause: bool
) -> GameResult {
graphics::clear(ctx, Color::WHITE);
Renderer::draw_background(ctx, resources)?;
grid.draw(ctx)?;
for plant in plants {
plant.draw(ctx, resources)?;
}
for pea in peas {
pea.draw(ctx, resources)?;
}
for zombie in zombies {
zombie.draw(ctx, resources)?;
}
for sun in suns {
sun.draw(ctx, resources)?;
}
Renderer::draw_ui(ctx, resources, shop, sun_count)?;
shovel.draw(ctx, resources)?;
let (x, y, w, h) = pause_button_rect;
let button_text = match game_state {
crate::core::states::GameState::Paused => if is_initial_pause { "Start" } else { "Continue" },
_ => "pause"
};
graphics::draw(
ctx,
&resources.button_image,
DrawParam::default()
.dest([x, y])
.scale([w / resources.button_image.width() as f32, h / resources.button_image.height() as f32])
)?;
let button_text = Text::new(
TextFragment::new(button_text)
.color(Color::BLACK)
.scale(20.0)
);
let text_width = button_text.width(ctx);
let text_height = button_text.height(ctx);
graphics::draw(
ctx,
&button_text,
DrawParam::default().dest([
x + w / 2.0 - text_width / 2.0,
y + h / 2.0 - text_height / 2.0,
])
)?;
if game_state == crate::core::states::GameState::Paused {
Renderer::draw_pause_message(ctx, is_initial_pause)?;
}
if show_final_wave {
Renderer::draw_final_wave_message(ctx)?;
}
if game_over {
Renderer::draw_game_over(ctx)?;
}
if victory {
Renderer::draw_victory_message(ctx)?;
}
graphics::present(ctx)?;
Ok(())
}
fn draw_background(ctx: &mut Context, resources: &Resources) -> GameResult {
graphics::draw(ctx, &resources.background, DrawParam::default())?;
graphics::draw(
ctx,
&resources.shop_image,
DrawParam::default().dest([250.0, 0.0])
)?;
Ok(())
}
fn draw_ui(ctx: &mut Context, resources: &Resources, shop: &Shop, sun_count: i32) -> GameResult {
shop.draw(ctx, resources)?;
let sun_text = Text::new(
TextFragment::new(format!("{}", sun_count))
.color(Color::BLACK)
.scale(25.0)
);
graphics::draw(
ctx,
&sun_text,
DrawParam::default().dest([280.0, 65.0])
)?;
Ok(())
}
fn draw_game_over(ctx: &mut Context) -> GameResult {
let game_over_text = Text::new(
TextFragment::new("GAME OVER")
.color(Color::RED)
.scale(100.0)
);
let text_width = game_over_text.width(ctx);
let text_height = game_over_text.height(ctx);
let screen_size = graphics::drawable_size(ctx);
graphics::draw(
ctx,
&game_over_text,
DrawParam::default().dest([
screen_size.0 / 2.0 - text_width / 2.0,
screen_size.1 / 2.0 - text_height / 2.0,
])
)?;
Ok(())
}
fn draw_final_wave_message(ctx: &mut Context) -> GameResult {
let final_wave_text = Text::new(
TextFragment::new("The final wave is coming!")
.color(Color::RED)
.scale(70.0)
);
let text_width = final_wave_text.width(ctx);
let text_height = final_wave_text.height(ctx);
let screen_size = graphics::drawable_size(ctx);
graphics::draw(
ctx,
&final_wave_text,
DrawParam::default().dest([
screen_size.0 / 2.0 - text_width / 2.0,
screen_size.1 / 2.0 - text_height / 2.0,
])
)?;
Ok(())
}
fn draw_victory_message(ctx: &mut Context) -> GameResult {
let victory_text = Text::new(
TextFragment::new("you win!")
.color(Color::GREEN)
.scale(100.0)
);
let text_width = victory_text.width(ctx);
let text_height = victory_text.height(ctx);
let screen_size = graphics::drawable_size(ctx);
graphics::draw(
ctx,
&victory_text,
DrawParam::default().dest([
screen_size.0 / 2.0 - text_width / 2.0,
screen_size.1 / 2.0 - text_height / 2.0,
])
)?;
Ok(())
}
fn draw_pause_message(ctx: &mut Context, is_initial_pause: bool) -> GameResult {
let pause_text = if is_initial_pause {
Text::new(
TextFragment::new("Make sure the screen zoom ratio is 100%.\nClick Start in the upper right corner.")
.color(Color::RED)
.scale(60.0)
)
} else {
Text::new(
TextFragment::new("Game Paused")
.color(Color::BLUE)
.scale(80.0)
)
};
let text_width = pause_text.width(ctx);
let text_height = pause_text.height(ctx);
let screen_size = graphics::drawable_size(ctx);
graphics::draw(
ctx,
&pause_text,
DrawParam::default().dest([
screen_size.0 / 2.0 - text_width / 2.0,
screen_size.1 / 2.0 - text_height / 2.0,
])
)?;
Ok(())
}
}