美化牌面
在这一步中,你将添加一个点击时会打开的帘幕式覆盖层。Slint 文件在绘制项目时有一个隐式的 z 顺序。
每个后续项目都绘制在前一个项目之上。因此,第 10 行的 Rectangle 会位于文件中第 50 行
之后声明的另一个 Rectangle 之下。为了营造覆盖图像的帘幕效果,
请在 Image 之后声明两个矩形,这样 Slint 会把它们绘制在 Image 之上。
TouchArea 元素声明了一个透明的矩形区域,用于 响应用户输入,例如鼠标点击或触摸。该元素会向 MainWindow 转发一个回调,表明用户点击了这张牌。
MainWindow 通过翻转自定义的 open_curtain 属性来做出反应。 动画 width 和 x 属性的属性绑定也使用自定义的 open_curtain 属性。
下表更详细地展示这两种状态:
| open_curtain 值: | false | true |
|---|---|---|
| 左侧帘幕矩形 | 通过将宽度 width 设为父级宽度的一半来填充左半部分 | 宽度为零会使矩形不可见 |
| 右侧帘幕矩形 | 通过将 x 和 width 设为父级宽度的一半来填充右半部分 | width 为零会使矩形不可见。x 向右移动,在播放动画时滑开帘幕 |
为了让牌具有可扩展性,请将硬编码的图标名称替换为一个可在实例化元素时设置的 icon 属性。
作为最后的润色,添加一个 solved 属性,用于在玩家找到一对匹配的牌时将颜色动画过渡到一种绿色调。
将 ui/app-window.slint 文件中的代码替换为以下内容:
component MemoryTile inherits Rectangle { callback clicked; in property <bool> open_curtain; in property <bool> solved; in property <image> icon;
height: 64px; width: 64px; background: solved ? #34CE57 : #3960D5; animate background { duration: 800ms; }
Image { source: icon; width: parent.width; height: parent.height; }
// Left curtain Rectangle { background: #193076; x: 0px; width: open_curtain ? 0px : (parent.width / 2); height: parent.height; animate width { duration: 250ms; easing: ease-in; } }
// Right curtain Rectangle { background: #193076; x: open_curtain ? parent.width : (parent.width / 2); width: open_curtain ? 0px : (parent.width / 2); height: parent.height; animate width { duration: 250ms; easing: ease-in; } animate x { duration: 250ms; easing: ease-in; } }
TouchArea { clicked => { // Delegate to the user of this element root.clicked(); } }}
export component MainWindow inherits Window { MemoryTile { icon: @image-url("icons/bus.png"); clicked => { self.open_curtain = !self.open_curtain; } }}代码使用了 root 和 self。root 指组件中最外层的
元素,在本例中是 MemoryTile。self 指
当前元素。
代码导出了 MainWindow 组件。这是必要的,以便你稍后可以从应用业务逻辑中 访问它。
运行代码会打开一个窗口,其中的矩形在点击时会打开以显示公交车图标。后续点击会再次合上和打开帘幕。
© 2026 SixtyFPS GmbH