当前位置: 首页 > news >正文

Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序--DeepSeek辅助编程(俄罗斯方块)

 在之前工作基础上(Tauri(2.5.1)+Leptos(0.8.2)开发自用桌面小程序-CSDN博客),继续进行自用桌面小程序的开发,这次完全使用DeepSeek辅助编程做一个俄罗斯方块游戏,大部分代码由DeepSeek自主完成,Bug扔给DeepSeek自行处理,期间人为简单干预即可。具体游戏界面如下:

 1. DeepSeek辅助编程界面

Win10的操作系统,使用VS Code及Rust analyzer插件搭建的Rust开发环境,使用Roo Code绑定DeepSeek API ,配置比较简单,网上教程很多。

 2. 页面设置

还是使用leptos-router新建一个页面(类似浏览器的标签页),用于俄罗斯方块游戏界面。主要在src/app/app.rs文件中设置,具体代码如下:

#[warn(unused_imports)]
use leptos::prelude::*;
use leptos_router::components::{Route, Router, Routes};
use leptos_router::path;
mod acidinput;
mod schedule;
mod game2048;
mod game5;
mod match_game;use acidinput::*;
use schedule::*;
use game2048::*;
use game5::*;
use match_game::*;#[component]
pub fn App() -> impl IntoView {view! {<Router><nav><a class="nav" href="/">"工作进度表"</a><a class="nav" href="/acidinput">"产品录入"</a><a class="nav" href="/game2048">"2048数字游戏"</a><a class="nav" href="/game5">"五子棋游戏"</a><a class="nav" href="/matchgame">"俄罗斯方块"</a></nav><main><Routes fallback=|| "Not found.">// / just has an un-nested "Home"<Route path=path!("/") view= || view! {<WorkSchedule />} /><Route path=path!("/acidinput") view=|| view! {<AcidInput />} /><Route path=path!("/game2048") view=|| view! {<GameBoard />} /><Route path=path!("/game5") view=|| view! {<GomokuGame />} /><Route path=path!("/matchgame") view=|| view! {<TetrisGameBoard />} /></Routes>                </main></Router>}
}

3. 游戏主程序

 俄罗斯方块游戏的代码被放在了文件src/app/match_game.rs中,绝大部分代码和注释都是DeepSeek完成的,具体代码如下:

use leptos::*;
use leptos::prelude::*;
use leptos::component;
use leptos::view;
use wasm_bindgen::prelude::*;
use web_sys;
use leptos::task::spawn_local;
use std::rc::Rc;
use std::cell::RefCell;
use wasm_bindgen::prelude::Closure;
use leptos::logging::log;/// 方块形状枚举
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Tetromino {I, // I形J, // J形L, // L形O, // O形S, // S形T, // T形Z, // Z形
}/// 游戏方向枚举
#[derive(Clone, Copy, PartialEq)]
pub enum Direction {Left,Right,Down,
}/// 游戏状态结构体
#[derive(Clone)]
pub struct Game {pub grid: [[Option<Tetromino>; 10]; 20], // 10x20游戏网格pub current_piece: (Tetromino, [[i32; 2]; 4]), // 当前方块及其位置pub next_piece: (Tetromino, u8), // 下一个方块及其旋转状态pub score: u32, // 当前得分pub level: u32, // 当前等级pub game_over: bool, // 游戏是否结束pub paused: bool, // 游戏是否暂停pub is_locked: bool, // 方块是否已锁定pub current_rotation: u8, // 当前旋转状态(0-3)
}impl Game {/// 创建新游戏实例pub fn new() -> Self {let mut game = Game {grid: [[None; 10]; 20],current_piece: (Tetromino::I, [[0; 2]; 4]),next_piece: (Self::random_tetromino(), (rand::random::<f32>() * 4.0).floor() as u8),score: 0,level: 1,game_over: false,paused: false,is_locked: false,current_rotation: 0,};game.spawn_piece();game}/// 随机生成方块fn random_tetromino() -> Tetromino {use rand::random;let piece = match (random::<f64>() * 7.0).floor() as u8 {0 => Tetromino::I,1 => Tetromino::J,2 => Tetromino::L,3 => Tetromino::O,4 => Tetromino::S,5 => Tetromino::T,_ => Tetromino::Z,};log!("Generated new piece: {:?}", piece);piece}/// 生成新方块fn spawn_piece(&mut self) {//log!("[SPAWN] Current state - next_piece: {:?}, current_piece: {:?}",//    self.next_piece, self.current_piece.0);// 保存当前预览方块及其旋转状态let (current_falling, preview_rotation) = self.next_piece;let actual_rotation = preview_rotation % 4;//log!("[SPAWN] Will spawn: {:?} with preview_rotation {:?} (actual: {:?})",//    current_falling, preview_rotation, actual_rotation);// 验证旋转状态一致性//log!("[ROTATION VERIFY] Preview rotation: {}, Actual rotation: {}",//    preview_rotation, actual_rotation);// 确保预览和实际方块类型一致//log!("[SPAWN] Verifying piece types - preview: {:?}, actual: {:?}",//    current_falling, self.next_piece.0);// 设置当前方块状态self.current_piece.0 = current_falling;self.is_locked = false;self.current_rotation = actual_rotation; // 确保旋转状态同步// 使用与预览完全相同的旋转状态计算方式let positions = match (current_falling, actual_rotation) {// 调整初始位置,确保最下端在第0行,其他部分可以在第0行以上(Tetromino::I, 0) => [[-2, 3], [-2, 4], [-2, 5], [-2, 6]],  // I型水平(Tetromino::I, 1) => [[-3, 4], [-2, 4], [-1, 4], [0, 4]],    // I型垂直(Tetromino::I, 2) => [[-2, 3], [-2, 4], [-2, 5], [-2, 6]],   // I型水平(反向)(Tetromino::I, 3) => [[-3, 4], [-2, 4], [-1, 4], [0, 4]],    // I型垂直(反向)(Tetromino::O, _) => [[-1, 4], [-1, 5], [0, 4], [0, 5]],     // O型(Tetromino::J, 0) => [[-1, 4], [0, 4], [0, 5], [0, 6]],      // J型初始(Tetromino::J, 1) => [[-2, 5], [-2, 6], [-1, 5], [0, 5]],    // J型90度(Tetromino::J, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 6]],    // J型180度(Tetromino::J, 3) => [[-2, 5], [-1, 5], [0, 5], [0, 4]],     // J型270度(Tetromino::L, 0) => [[-1, 6], [0, 4], [0, 5], [0, 6]],      // L型初始(Tetromino::L, 1) => [[-2, 4], [-1, 4], [0, 4], [0, 5]],     // L型90度(Tetromino::L, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 4]],    // L型180度(Tetromino::L, 3) => [[-2, 4], [-2, 5], [-1, 5], [0, 5]],     // L型270度(Tetromino::S, 0) => [[-1, 5], [-1, 6], [0, 4], [0, 5]],     // S型初始(右凸)(Tetromino::S, 1) => [[-2, 5], [-1, 5], [-1, 6], [0, 6]],    // S型90度(左凸)(Tetromino::S, 2) => [[-1, 5], [-1, 6], [0, 4], [0, 5]],    // S型180度(右凸)(Tetromino::S, 3) => [[-2, 4], [-1, 4], [-1, 5], [0, 5]],    // S型270度(左凸)(Tetromino::T, 0) => [[-1, 5], [0, 4], [0, 5], [0, 6]],      // T型初始(Tetromino::T, 1) => [[-2, 5], [-1, 5], [-1, 6], [0, 5]],    // T型90度(Tetromino::T, 2) => [[-1, 4], [-1, 5], [-1, 6], [0, 5]],    // T型180度(Tetromino::T, 3) => [[-2, 5], [-1, 4], [-1, 5], [0, 5]],    // T型270度(Tetromino::Z, 0) => [[-1, 4], [-1, 5], [0, 5], [0, 6]],     // Z型初始(Tetromino::Z, 1) => [[-2, 6], [-1, 5], [-1, 6], [0, 5]],    // Z型90度(Tetromino::Z, 2) => [[-1, 4], [-1, 5], [0, 5], [0, 6]],     // Z型180度(Tetromino::Z, 3) => [[-2, 5], [-1, 4], [-1, 5], [0, 4]],    // Z型270度_ => unreachable!("Invalid rotation state"),};//log!("[POSITION] Final positions for {:?} with rotation {}: {:?}",//    current_falling, actual_rotation, positions);//log!("[POSITION] Calculated positions for {:?} with rotation {}: {:?}",//    current_falling, actual_rotation, positions);self.current_piece.1 = positions;// 生成新预览方块及随机旋转状态(0-3)let new_piece = Self::random_tetromino();let new_rotation = (rand::random::<f32>() * 4.0).floor() as u8;let new_preview = (new_piece, new_rotation);//log!("[SPAWN] Generated new preview: {:?} with rotation {} (will be next piece)",//    new_preview.0, new_preview.1);// 双重验证预览方块类型if new_preview.0 != current_falling {log!("[SPAWN] Preview and current piece match verified");}// 更新预览方块self.next_piece = new_preview;//log!("[SPAWN] Updated next_piece to: {:?}", self.next_piece);//log!("[SPAWN] After update - next_piece: {:?}, current_piece: {:?}",//    self.next_piece, self.current_piece.0);// 检查新方块位置是否有效(允许部分超出顶部)let dropped_pos = self.get_dropped_position();if !self.is_valid_position(&dropped_pos) || dropped_pos == self.current_piece.1 {self.lock_piece();} else {// 检查新方块位置是否有效(允许部分超出顶部)let mut valid_spawn = true;for &[i, j] in &self.current_piece.1 {if j < 0 || j >= 10 || i >= 20 || (i >= 0 && self.grid[i as usize][j as usize].is_some()) {valid_spawn = false;break;}}self.game_over = !valid_spawn;}}/// 检查方块是否完全无法移动fn is_piece_stuck(&self) -> bool {// 检查方块是否无法继续下落for &[i, j] in &self.current_piece.1 {// 如果方块在网格内(i >= 0)if i >= 0 {// 检查是否到达底部或下方有方块if i >= 19 || self.grid[(i + 1) as usize][j as usize].is_some() {return true;}}}false}/// 移动方块pub fn move_piece(&mut self, direction: Direction) {if self.game_over || self.paused || self.is_locked {return;}let mut new_positions = self.current_piece.1;// 计算新位置for pos in &mut new_positions {match direction {Direction::Left => pos[1] -= 1,Direction::Right => pos[1] += 1,Direction::Down => pos[0] += 1,}}// 检查新位置是否有效if self.is_valid_position(&new_positions) {self.current_piece.1 = new_positions;// 如果是向下移动if direction == Direction::Down {// 检查是否已经到底部if self.is_piece_stuck() {self.lock_piece();return; // 锁定后立即返回,防止后续移动}} else if self.is_piece_stuck() {// 其他方向移动时检查是否卡住self.lock_piece();return; // 锁定后立即返回,防止后续移动}} else if direction == Direction::Down && self.is_piece_stuck() {// 如果向下移动无效且方块卡住,也锁定self.lock_piece();}}/// 旋转方块pub fn rotate_piece(&mut self) {if self.game_over || self.paused || self.current_piece.0 == Tetromino::O {return; // O方块不需要旋转}// 获取当前旋转状态(0-3)let current_rot = self.current_rotation;//log!("[ROTATE] Rotating {:?} from state {}", self.current_piece.0, current_rot);// 根据方块类型定义精确旋转中心(取第二和第三个方块中间)let (center_x, center_y) = match self.current_piece.0 {Tetromino::I => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::O => (self.current_piece.1[0][0] + 1, self.current_piece.1[0][1] + 1), // O型中心在四个方块中间Tetromino::J => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::L => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::S => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::Z => ((self.current_piece.1[1][0] + self.current_piece.1[2][0]) / 2,(self.current_piece.1[1][1] + self.current_piece.1[2][1]) / 2),Tetromino::T => (self.current_piece.1[1][0], self.current_piece.1[1][1]), // T型中心取第二个方块};//log!("[ROTATE] Fixed center for {:?}: ({}, {})", self.current_piece.0, center_x, center_y);let mut new_positions = self.current_piece.1.clone();// 应用旋转for pos in &mut new_positions {// 计算相对于中心的坐标let x = pos[1] - center_y;let y = pos[0] - center_x;// 应用标准90度顺时针旋转矩阵let new_x = -y;let new_y = x;// 计算新位置pos[1] = center_y + new_x;pos[0] = center_x + new_y;}// 尝试原始位置if self.is_valid_position(&new_positions) {self.apply_rotation(new_positions, current_rot);return;}// 墙踢: 尝试左右移动1-2格for offset in [1, -1, 2, -2].iter() {let mut kicked_positions = new_positions.clone();for pos in &mut kicked_positions {pos[1] += offset;}if self.is_valid_position(&kicked_positions) {self.apply_rotation(kicked_positions, current_rot);//log!("[ROTATE] Applied wall kick with offset {}", offset);return;}}//log!("[ROTATE] Rotation failed - all positions invalid");}/// 检查位置是否有效fn is_valid_position(&self, positions: &[[i32; 2]; 4]) -> bool {for &[i, j] in positions {// 允许i<0(顶部以上),只要j在有效范围内// 仅检查网格内(i>=0)的方块重叠if j < 0 || j >= 10 || i >= 20 || (i >= 0 && self.grid[i as usize][j as usize].is_some()) {return false;}}true}/// 获取下落到底部的位置fn get_dropped_position(&self) -> [[i32; 2]; 4] {let mut dropped = self.current_piece.1;loop {for pos in &mut dropped {pos[0] += 1;}if !self.is_valid_position(&dropped) {for pos in &mut dropped {pos[0] -= 1;}break;}}dropped}/// 硬降(直接下落到底部)pub fn hard_drop(&mut self) {if self.game_over || self.paused {return;}self.current_piece.1 = self.get_dropped_position();self.lock_piece();}/// 固定当前方块到网格fn lock_piece(&mut self) {if self.is_locked || self.game_over {return;}let piece_type = self.current_piece.0;for &[i, j] in &self.current_piece.1 {if i >= 0 {self.grid[i as usize][j as usize] = Some(piece_type);// 如果方块被锁定在第0行,游戏结束if i == 0 {self.game_over = true;}}}self.is_locked = true;self.clear_lines();if !self.game_over {self.spawn_piece();}}/// 应用旋转并更新状态(内部方法)pub(crate) fn apply_rotation(&mut self, positions: [[i32; 2]; 4], current_rot: u8) {self.current_piece.1 = positions;self.current_rotation = (current_rot + 1) % 4;//log!("[ROTATE] Success! New state: {}", self.current_rotation);//log!("[ROTATE] New positions: {:?}", self.current_piece.1);// 旋转后检查是否卡住if self.is_piece_stuck() {self.lock_piece();}}/// 清除完整的行fn clear_lines(&mut self) {let mut lines_cleared = 0;// 从下往上扫描let mut row = 19;while row > 0 {if self.grid[row].iter().all(|cell| cell.is_some()) {lines_cleared += 1;// 将上方行下移for move_row in (1..=row).rev() {self.grid[move_row] = self.grid[move_row - 1];}// 清空最顶行self.grid[0] = [None; 10];// 继续检查当前行(因为上方行已经下移)continue;}row -= 1;}// 更新分数match lines_cleared {1 => self.score += 100 * self.level,2 => self.score += 300 * self.level,3 => self.score += 500 * self.level,4 => self.score += 800 * self.level,_ => (),}// 更新等级if lines_cleared > 0 {self.level = (self.score / 2000) + 1;}}/// 暂停/继续游戏pub fn toggle_pause(&mut self) {if !self.game_over {self.paused = !self.paused;}}
}/// 游戏界面组件
#[component]
pub fn TetrisGameBoard() -> impl IntoView {// 创建游戏状态信号let (game, set_game) = signal(Game::new());// 设置游戏循环(自动下落)let tick = move || {set_game.update(|g| {if !g.game_over && !g.paused {g.move_piece(Direction::Down);}});};// 每500ms触发一次下落(速度随等级提高)let tick_interval = move || {500.0 / (game.get_untracked().level as f64).max(1.0)};// 使用Leptos的spawn_local和web_sys的set_timeout实现游戏循环spawn_local(async move {let window = web_sys::window().expect("no global window exists");let closure: Rc<RefCell<Option<Closure<dyn FnMut()>>>> = Rc::new(RefCell::new(None));let closure_clone = Rc::clone(&closure);*closure_clone.borrow_mut() = Some(Closure::<dyn FnMut()>::new({let closure_clone = Rc::clone(&closure_clone);let window = window.clone();move || {if !game.get_untracked().game_over && !game.get_untracked().paused {tick();}let interval = tick_interval();window.set_timeout_with_callback_and_timeout_and_arguments_0(closure_clone.borrow().as_ref().unwrap().as_ref().unchecked_ref(),interval as i32).expect("failed to set timeout");}}));// 初始调用window.set_timeout_with_callback_and_timeout_and_arguments_0(closure.borrow().as_ref().unwrap().as_ref().unchecked_ref(),tick_interval() as i32).expect("failed to set timeout");});// 监听键盘事件let key_listener = window_event_listener(ev::keydown, move |ev| {if game.get().game_over {return;}ev.prevent_default();match &ev.key()[..] {"ArrowLeft" => set_game.update(|g| g.move_piece(Direction::Left)),"ArrowRight" => set_game.update(|g| g.move_piece(Direction::Right)),"ArrowDown" => set_game.update(|g| g.move_piece(Direction::Down)),"ArrowUp" => set_game.update(|g| g.rotate_piece())," " => {if !game.get().paused {set_game.update(|g| g.hard_drop());}},"p" | "P" => set_game.update(|g| g.toggle_pause()),_ => (),}});// 组件卸载时清理事件监听器和闭包on_cleanup(move || {key_listener.remove();// 闭包会在离开作用域时自动释放});// 根据方块类型返回对应的CSS颜色类fn tile_color(tile: Option<Tetromino>) -> &'static str {if let Some(t) = tile {match t {Tetromino::I => "tetromino-i",Tetromino::J => "tetromino-j",Tetromino::L => "tetromino-l",Tetromino::O => "tetromino-o",Tetromino::S => "tetromino-s",Tetromino::T => "tetromino-t",Tetromino::Z => "tetromino-z",}} else {"tetromino-empty"}}// 渲染预览方块fn render_preview((tetromino, rotation): (Tetromino, u8)) -> impl IntoView {// 使用与实际方块相同的旋转状态let rotation_mod = rotation % 4;//log!("[PREVIEW] Rendering {:?} with rotation {}", tetromino, rotation_mod);// 使用与实际方块相同的精确旋转中心(取第二和第三方块中间)let (center_x, center_y) = match tetromino {Tetromino::I => (1, 2),  // I型中心(第二和第三方块中间)Tetromino::O => (1, 1),  // O型中心(四个方块中间)Tetromino::J => (1, 1),  // J型中心(第二和第三方块中间)Tetromino::L => (1, 1),  // L型中心(第二和第三方块中间)Tetromino::S => (1, 1),  // S型中心(第二和第三方块中间)Tetromino::Z => (1, 1),  // Z型中心(第二和第三方块中间)Tetromino::T => (1, 1),  // T型中心(第二个方块)};// 根据旋转状态计算相对位置let positions = match (tetromino, rotation_mod) {(Tetromino::I, 0) => vec![(center_x, center_y-2), (center_x, center_y-1), (center_x, center_y), (center_x, center_y+1)],(Tetromino::I, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x+1, center_y), (center_x+2, center_y)],(Tetromino::I, 2) => vec![(center_x, center_y-2), (center_x, center_y-1), (center_x, center_y), (center_x, center_y+1)],(Tetromino::I, 3) => vec![(center_x-1, center_y), (center_x, center_y), (center_x+1, center_y), (center_x+2, center_y)],(Tetromino::O, _) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1)],// J型方块定义(Tetromino::J, 0) => vec![(center_x, center_y), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::J, 1) => vec![(center_x, center_y+1), (center_x, center_y+2), (center_x+1, center_y+1), (center_x+2, center_y+1)],(Tetromino::J, 2) => vec![(center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2), (center_x+2, center_y+2)],(Tetromino::J, 3) => vec![(center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y), (center_x+2, center_y+1)],// L型方块定义(Tetromino::L, 0) => vec![(center_x, center_y+2), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::L, 1) => vec![(center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y+1), (center_x+2, center_y+2)],(Tetromino::L, 2) => vec![(center_x+1, center_y), (center_x+1, center_y+1), (center_x+1, center_y+2), (center_x+2, center_y)],(Tetromino::L, 3) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+2, center_y+1)],(Tetromino::S, 0) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y-1), (center_x+1, center_y)],(Tetromino::S, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1)],(Tetromino::S, 2) => vec![(center_x-1, center_y), (center_x-1, center_y+1), (center_x, center_y-1), (center_x, center_y)],(Tetromino::S, 3) => vec![(center_x-1, center_y-1), (center_x, center_y-1), (center_x, center_y), (center_x+1, center_y)],(Tetromino::T, 0) => vec![(center_x, center_y), (center_x+1, center_y-1), (center_x+1, center_y), (center_x+1, center_y+1)],(Tetromino::T, 1) => vec![(center_x-1, center_y), (center_x, center_y), (center_x, center_y+1), (center_x+1, center_y)],(Tetromino::T, 2) => vec![(center_x, center_y-1), (center_x, center_y), (center_x, center_y+1), (center_x-1, center_y)],(Tetromino::T, 3) => vec![(center_x-1, center_y), (center_x, center_y-1), (center_x, center_y), (center_x+1, center_y)],// Z型方块定义(Tetromino::Z, 0) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::Z, 1) => vec![(center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+2, center_y)],(Tetromino::Z, 2) => vec![(center_x, center_y), (center_x, center_y+1), (center_x+1, center_y+1), (center_x+1, center_y+2)],(Tetromino::Z, 3) => vec![(center_x, center_y+1), (center_x+1, center_y), (center_x+1, center_y+1), (center_x+2, center_y)],_ => unreachable!("Invalid rotation state"),};//log!("[PREVIEW] Calculated relative positions: {:?}", positions);view! {<div style="display: grid; grid-template-columns: repeat(4, 20px); grid-template-rows: repeat(4, 20px); width: 80px; height: 80px; gap: 1px;">{positions.into_iter().map(|(i, j)| {view! {<divstyle=format!("grid-row: {}; grid-column: {};", i + 1, j + 1)class=format!("{} tetromino-border", tile_color(Some(tetromino)))></div>}}).collect::<Vec<_>>()}</div>}}// 重置游戏函数let reset = move |_| {set_game.update(|g| *g = Game::new());};// 暂停/继续游戏函数let toggle_pause = move |_| {set_game.update(|g| g.toggle_pause());};// 游戏界面视图view! {<div class="game-container"><div class="game-header">//<h1 class="game-title" style="display: block; text-align: center; width: 100%; margin-bottom: 1rem;">"俄罗斯方块"</h1><div class="game-controls-container"><div class="game-scores-container"><div class="game-score-box"><div class="game-score-label">"得分:"{move || game.get().score}</div></div><div class="game-score-box"><div class="game-score-label">"等级:"{move || game.get().level}</div></div></div><div class="game-buttons-container"><buttonon:click=toggle_pauseclass="game-button">{move || if game.get().paused { "继续" } else { "暂停" }}</button><buttonon:click=resetclass="game-button">"新游戏"</button></div></div></div><div style="display: flex; justify-content: space-between; align-items: flex-start; width: 100%; margin-top: 1rem;"><div class="game-main-area"><div class="game-board"><div style="display: grid; grid-template-columns: repeat(10, 24px); grid-template-rows: repeat(20, 24px); gap: 1px;">{move || {// 创建网格副本用于渲染let mut render_grid = game.get().grid.clone();// 添加当前方块到渲染网格if !game.get().game_over {for &[i, j] in &game.get().current_piece.1 {if i >= 0 {render_grid[i as usize][j as usize] = Some(game.get().current_piece.0);}}}// 渲染网格render_grid.iter().flat_map(|row| {row.iter().map(|&tile| {view! {<div class=format!("{} tetromino-border", tile_color(tile))></div>}})}).collect::<Vec<_>>()}}</div></div></div><div class="game-side-panel"><div class="game-preview"><h2 class="game-preview-title">"下一个"</h2>{move || {let (tetromino, rotation) = game.get().next_piece;render_preview((tetromino, rotation))}}</div><div class="game-instructions"><h2 class="game-instructions-title">"操作说明"</h2><ul class="game-instructions-list"><li>"← → : 左右移动"</li><li>"↓ : 加速下落"</li><li>"↑ : 旋转方块"</li><li>"空格 : 硬降到底部"</li><li>"P : 暂停/继续"</li></ul></div></div></div>{/* 游戏结束提示 */}<Show when=move || game.get().game_over><div class="game-over-message">"游戏结束! 最终得分: " {move || game.get().score}</div></Show>{/* 暂停提示 */}<Show when=move || game.get().paused><div class="game-paused-message">"游戏暂停"</div></Show></div>}
}

DeepSeek刚写出来的程序bug比较多,要一步一步引导其修改完善。游戏界面的css设置文件内容如下:

/* 俄罗斯方块颜色 */
.tetromino-i {background-color: #06b6d4; /* I方块 - 青色 */
}.tetromino-l {background-color: #f97316; /* L方块 - 橙色 */
}.tetromino-z {background-color: #ef4444; /* Z方块 - 红色 */
}.tetromino-j {background-color: #2563eb; /* J方块 - 深蓝色 */
}.tetromino-s {background-color: #10b981; /* S方块 - 绿色 */
}.tetromino-o {background-color: #facc15; /* O方块 - 黄色 */
}.tetromino-t {background-color: #a855f7; /* T方块 - 紫色 */
}.tetromino-empty {background-color: #1f2937; /* 空单元格 - 深灰色 */
}/* 边框样式 */
.tetromino-border {border: 1px solid #374151;
}/* 按钮样式 */
.game-button {background-color: #3b82f6;color: #000;padding: 0.5rem 1rem;border-radius: 0.25rem;margin: 10px 5px;
}.game-button:hover {background-color: #2563eb;
}/* 容器样式 */
.game-container {width: 550px;margin-left: auto;margin-right: auto;padding: 1rem;
}.game-header {display: block;margin-bottom: 1rem;
}.game-title {font-size: 1.875rem;font-weight: bold;text-align: center;margin-bottom: 1rem;display: block;
}.game-score-container {display: flex;justify-content: center;gap: 1rem;margin-bottom: 1rem;
}.game-title {font-size: 1.875rem;font-weight: bold;
}.game-controls-container {display: flex;justify-content: center;align-items: center;gap: 2rem;width: 100%;
}.game-scores-container {display: flex;gap: 1rem;align-items: center;justify-content: center;
}.game-buttons-container {display: flex;gap: 1rem;align-items: center;justify-content: center;
}.game-score-box {display: flex;flex-direction: column;align-items: center;justify-content: center;text-align: center;
}.game-score-container {display: flex;gap: 1rem;
}.game-score-box {background-color: #e5e7eb;padding: 0.5rem;border-radius: 0.25rem;
}.game-score-label {font-size: 1rem;font-weight: bold;
}.game-score-value {font-size: 1.25rem;font-weight: bold;
}.game-content-wrapper {display: flex;gap: 1rem;
}.game-main-area {width:250px;margin:0px 0px 0px 10px;
}.game-board {width:100%;background-color: #1f2937;padding: 0.5rem;border-radius: 0.5rem;
}.game-side-panel {width:250px;
}.game-preview {width:100%;background-color: #e5e7eb;padding: 1rem;border-radius: 0.25rem;
}.game-instructions {width:100%;background-color: #e5e7eb;padding: 1rem;border-radius: 0.25rem;
}.game-over-message {margin-top: 1rem;padding: 1rem;background-color: #ef4444;color: #000;border-radius: 0.25rem;text-align: center;
}.game-paused-message {margin-top: 1rem;padding: 1rem;background-color: #facc15;color: #000;border-radius: 0.25rem;text-align: center;
}

总体而言,DeekSeek辅助编程效率还是很高的,对于编程初学者尤其方便。

相关文章:

  • 建设部网站有建筑施工分包网络营销发展方案策划书
  • 网站设计包括学历提升
  • .东莞网站建设百度网盘提取码入口
  • 郑州网络营销顾问郑州seo代理外包
  • 做网站比较好移动网站如何优化排名
  • 音乐网站设计怎么做做seo前景怎么样
  • 自用006
  • 单片机常用通信外设特点及通信方式对比表
  • Spark Streaming 与 Flink 实时数据处理方案对比与选型指南
  • QUdpScoket 组播实现及其中的踩坑点记录
  • 云原生与人工智能的融合:从弹性架构到智能运维的IT新范式
  • 华为云Flexus+DeepSeek征文 | 掌握高效开发:利用华为云ModelArts Studio在VS Code中配置Cline AI编程助手
  • [AI工具]Fish-speech部署教程(环境搭建记录)
  • spring boot项目整合百度翻译
  • 北斗导航 | 卫星载噪比(C/N₀)的定义与解析
  • 什么是PD快充诱骗取电协议,它有哪些特点及应用场景如XSP01A
  • 【HLS】pragma HLS bundle的用法 AXI接口
  • uniapp小程序在线预览
  • 前端流式接口/Socket.IO/WebSocket的区别和选用
  • 高精度RTK定位导航模块软硬件协同设计
  • Redis大规模Key遍历实战:性能与安全的最佳实践
  • 【网站内容安全检测】之3:获取所有外部域名访问后图像
  • 【邀请】点击邀请链接参加阿里云训练营活动,完成学习送礼品+户外折叠凳,一个小时就能完成
  • UI前端与大数据的深度融合:推动产品设计迭代升级
  • WordPress目录说明
  • Catchadmin 使用相关问题