此步骤将随机放置游戏图块。
将 src/main.cpp 中的 main 函数和头文件更改如下:
#include <random> // Added
int main(){ auto main_window = MainWindow::create(); auto old_tiles = main_window->get_memory_tiles(); std::vector<TileData> new_tiles; new_tiles.reserve(old_tiles->row_count() * 2); for (int i = 0; i < old_tiles->row_count(); ++i) { new_tiles.push_back(*old_tiles->row_data(i)); new_tiles.push_back(*old_tiles->row_data(i)); } std::default_random_engine rng {}; std::shuffle(new_tiles.begin(), new_tiles.end(), rng); auto tiles_model = std::make_shared<slint::VectorModel<TileData>>(new_tiles); main_window->set_memory_tiles(tiles_model);
main_window->run();}这段代码取出图块列表,对其进行复制并打乱顺序,通过 C++ 代码访问 memory_tiles 属性。
对于每个顶级属性,Slint 会生成一个 getter 和一个 setter 函数。在本例中为 get_memory_tiles 和 set_memory_tiles。 由于 memory_tiles 是一个 Slint 数组,它被表示为 std::shared_ptr<slint::Model>。
你无法更改 Slint 生成的模型,但你可以从中提取图块,并将它们 放入一个继承自 Model 的 slint::VectorModel 中。 VectorModel 允许你进行修改,你可以使用它来替换静态生成的模型。
将 main.js 更改为如下内容:
import * as slint from "slint-ui";const ui = slint.loadFile(new URL("./ui/app-window.slint", import.meta.url));const mainWindow = new ui.MainWindow();
const initial_tiles = mainWindow.memory_tiles;const tiles = initial_tiles.concat( initial_tiles.map((tile) => Object.assign({}, tile)),
);
for (let i = tiles.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * i); [tiles[i], tiles[j]] = [tiles[j], tiles[i]];}
const model = new slint.ArrayModel(tiles);mainWindow.memory_tiles = model;
await mainWindow.run();这段代码取出图块列表,对其进行复制并打乱顺序,通过 JavaScript 代码访问 memory_tiles 属性。
由于 memory_tiles 是一个数组,它被表示为 JavaScript Array。 你无法更改 Slint 生成的模型,但你可以从中提取图块,并将它们 放入一个实现了 Model 接口的 slint.ArrayModel.html 中。 ArrayModel 允许你进行修改,你可以使用它来替换静态生成的模型。
该代码使用 rand 依赖项来进行随机化。使用 cargo 命令将其添加到 Cargo.toml 文件中。
Terminal window
cargo add [email protected]将 main 函数更改为如下内容:
fn main() { use slint::Model;
let main_window = MainWindow::new().unwrap();
// Fetch the tiles from the model
let mut tiles: Vec<TileData> = main_window.get_memory_tiles().iter().collect(); // Duplicate them to ensure that we have pairs
tiles.extend(tiles.clone());
// Randomly mix the tiles
use rand::seq::SliceRandom; let mut rng = rand::rng(); tiles.shuffle(&mut rng);
// Assign the shuffled Vec to the model property
let tiles_model = std::rc::Rc::new(slint::VecModel::from(tiles)); main_window.set_memory_tiles(tiles_model.clone().into());
main_window.run().unwrap();}这段代码取出图块列表,对其进行复制并打乱顺序,通过 Rust 代码访问 memory_tiles 属性。
对于每个顶级属性, Slint 会生成一个 getter 和一个 setter 函数。在本例中为 get_memory_tiles 和 set_memory_tiles。 由于 memory_tiles 是一个表示为 Rc<dyn slint::Model> 的 Slint 数组。
你无法更改 Slint 生成的模型,但你可以从中提取图块,并将它们 放入一个实现了 Model trait 的 VecModel 中。 VecModel 允许你进行修改,你可以使用它来替换静态生成的模型。
将 main.py 更改为如下内容:
import slintimport sysimport osimport randomimport itertoolsimport copyimport datetime
class MainWindow(slint.loader.ui.app_window.MainWindow): def __init__(self): super().__init__() initial_tiles = self.memory_tiles tiles = slint.ListModel( itertools.chain( map(copy.copy, initial_tiles), map(copy.copy, initial_tiles) ) ) random.shuffle(tiles) self.memory_tiles = tiles
main_window = MainWindow()main_window.show()main_window.run()这段代码取出图块列表,对其进行复制并打乱顺序,通过 Python 代码访问 memory_tiles 属性。
由于 memory_tiles 是一个数组,它被表示为 Slint ListModel。 你无法更改 Slint 生成的模型,但你可以从中提取图块,并将它们 放入一个继承自 Model 接口的 slint.ListModel 中。 ListModel 允许你进行修改,你可以使用它来替换静态生成的模型。
运行此代码会打开一个窗口,现在窗口中显示一个 4×4 的矩形网格,当玩家点击图块时, 这些图标会显示或隐藏。
现在还差最后一个方面——游戏的规则。