Skip to content

Commit

Permalink
game modal start
Browse files Browse the repository at this point in the history
  • Loading branch information
randallard committed Nov 30, 2024
1 parent f48fb61 commit 4809d22
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 6 deletions.
117 changes: 113 additions & 4 deletions src/components/game.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
use leptos::*;
use leptos::prelude::*;
use leptos::callback::Callback;
use super::board::SavedBoard;
use super::opponent::Opponent;
use serde::{Serialize, Deserialize};
use crate::components::board::SavedBoard;
use crate::components::opponent::Opponent;
use std::time::Duration;
use super::utils::load_saved_boards;

#[derive(Clone, Serialize, Deserialize, PartialEq)]
pub enum GamePhase {
SelectingBoards,
ShowingResults,
}

#[derive(Clone, Serialize, Deserialize)]
pub struct GameState {
pub player1: String, // Current player's name
pub player2: Option<Opponent>, // Selected opponent
pub player1: String,
pub player2: Option<Opponent>,
pub current_round: usize,
pub player1_score: i32,
pub player2_score: i32,
pub player1_board: Option<SavedBoard>,
pub player2_board: Option<SavedBoard>,
pub phase: GamePhase, // Add this
}

impl GameState {
Expand All @@ -23,6 +35,103 @@ impl GameState {
player2_score: 0,
player1_board: None,
player2_board: None,
phase: GamePhase::SelectingBoards, // Add this
}
}
}

#[component]
pub fn Game(
#[prop(into)] player_name: String,
#[prop(into)] opponent: Opponent,
#[prop(into)] on_exit: Callback<()>,
) -> impl IntoView {
let game_state = RwSignal::new(GameState::new(player_name, opponent));
let boards = Memo::new(|_| load_saved_boards().unwrap_or_default());
let (timer, set_timer) = signal(5);

// Update timer every second
if timer.get() > 0 {
set_interval(
move || {
set_timer.update(|t| *t = (*t - 1).max(0));
},
Duration::from_secs(1),
);
}
view! {
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div class="bg-slate-800 p-6 rounded-lg shadow-xl max-w-4xl w-full mx-4 text-white">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold">
"Round " {move || game_state.get().current_round} " of 8"
</h2>
<button
class="px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded"
on:click=move |_| on_exit.run(())
>
"Exit Game"
</button>
</div>
<div class="flex justify-between text-xl mb-4">
<div>
{move || game_state.get().player1}
": "
<span class="font-bold">
{move || game_state.get().player1_score}
</span>
</div>
<div>
{move || game_state.get().player2.as_ref().map(|p| p.name.clone()).unwrap_or_default()}
": "
<span class="font-bold">
{move || game_state.get().player2_score}
</span>
</div>
</div>
{move || match game_state.get().phase {
GamePhase::SelectingBoards => view! {
<div class="mt-8">
<div class="flex flex-col items-center mb-4">
<h3 class="text-xl font-bold mb-2">
"Select your board"
</h3>
<div class="font-mono text-lg text-orange-400 bg-slate-700 px-4 py-1 rounded-md">
{move || format!("{} seconds left!", timer.get())}
</div>
</div>
<div class="grid grid-cols-4 gap-4 max-w-xl mx-auto">
<For
each=move || boards.get()
key=|board| board.thumbnail.clone()
children=move |board: SavedBoard| {
view! {
<button
class="w-24 h-24 rounded border border-slate-700 hover:border-blue-500 transition-colors"
on:click=move |_| {
let mut current_state = game_state.get();
current_state.player1_board = Some(board.clone());
current_state.phase = GamePhase::ShowingResults;
game_state.set(current_state);
}
>
<img
src=board.thumbnail.clone()
alt="Board option"
class="w-full h-full rounded"
/>
</button>
}
}
/>
</div>
</div>
}.into_any(),
GamePhase::ShowingResults => view! {
<div>"Results will go here"</div>
}.into_any(),
}}
</div>
</div>
}
}
13 changes: 11 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use leptos::*;
use leptos::prelude::*;
use leptos::logging::log;
use web_sys::{MouseEvent, Storage, window};
use serde::{Serialize, Deserialize};

mod components;
use components::board::BoardCreator;
use components::game::Game;
use components::saved_boards::SavedBoards;
use components::opponent::{
delete_opponent, Opponent, OpponentType, load_opponents, save_opponent
Expand Down Expand Up @@ -44,6 +44,7 @@ fn App() -> impl IntoView {
let (name, set_name) = signal(String::new());
let (greeting, set_greeting) = signal(String::new());
let (show_form, set_show_form) = signal(true);
let (show_game, set_show_game) = signal(None::<Opponent>);
let (show_board_creator, set_show_board_creator) = signal(false);
let opponent_to_delete = RwSignal::new(None::<Opponent>);
let opponents_trigger = RwSignal::new(false);
Expand Down Expand Up @@ -139,7 +140,8 @@ fn App() -> impl IntoView {
<button
class="px-3 py-1 bg-green-600 hover:bg-green-700 rounded text-sm"
on:click=move |_| {
log!("Starting game with {}", play_opponent.name);
let opponent = play_opponent.clone();
set_show_game.set(Some(opponent));
}
>
"Play"
Expand Down Expand Up @@ -212,6 +214,13 @@ fn App() -> impl IntoView {
</div>
})}
</div>
{move || show_game.get().map(|opponent| view! {
<Game
player_name=name.get()
opponent=opponent
on_exit=move || set_show_game.set(None)
/>
})}
}
}

Expand Down

0 comments on commit 4809d22

Please sign in to comment.