湛江网站建设方案策划,高要区住房和城乡建设局网站,wordpress 最强插件,做一个小公司网站多少钱【1】引言#xff08;完整代码在最后面#xff09;
本文介绍的拖动七巧板游戏是一个简单的益智游戏#xff0c;用户可以通过拖动和旋转不同形状的七巧板块来完成拼图任务。整个游戏使用鸿蒙Next框架开发#xff0c;利用其强大的UI构建能力和数据响应机制#xff0c;实现了…
【1】引言完整代码在最后面
本文介绍的拖动七巧板游戏是一个简单的益智游戏用户可以通过拖动和旋转不同形状的七巧板块来完成拼图任务。整个游戏使用鸿蒙Next框架开发利用其强大的UI构建能力和数据响应机制实现了流畅的用户体验。
【2】环境准备
电脑系统windows 10
开发工具DevEco Studio NEXT Beta1 Build Version: 5.0.3.806
工程版本API 12
真机Mate 60 Pro
语言ArkTS、ArkUI
【3】关键技术点
1. TangramBlock 类定义 游戏的核心在于TangramBlock类的定义它封装了每个七巧板块的属性和行为。类中包含了宽度、高度、颜色、初始和当前偏移量、旋转角度等属性并提供了重置数据的方法。这为后续的数据绑定和UI渲染奠定了基础。
2. 数据绑定与响应式更新 在鸿蒙Next中使用ObservedV2和Trace装饰器可以轻松实现数据的观察和响应式更新。每当TangramBlock实例中的属性发生变化时UI会自动更新以反映最新的状态。这种机制极大地简化了数据同步的工作使得开发者可以专注于逻辑实现而无需担心UI更新的问题。
3. UI构建与布局管理 鸿蒙Next提供了丰富的UI组件和布局工具使得构建复杂的用户界面变得简单。在这个项目中我们使用了Column、Stack、Polygon等组件来构建七巧板块的布局。通过嵌套这些组件我们可以灵活地控制每个板块的位置和大小。
4. 手势处理与交互 为了实现拖动和旋转功能我们使用了PanGesture和rotate方法来处理用户的触摸和手势操作。当用户拖动板块时通过更新initialOffsetX和initialOffsetY属性可以实时反映板块的位置变化。同样通过增加或减少rotationAngle属性可以实现板块的旋转效果。
5. 动画与过渡 鸿蒙Next内置了丰富的动画和过渡效果使得用户交互更加自然。在本项目中我们使用了animateTo方法来平滑地更新板块的状态从而提升了用户体验。
5.1 旋转动画属性
.rotate({angle: block.rotationAngle,
})5.2 翻转动画属性
.rotate({x: 0,y: 1,z: 0,angle: block.flipAngle,centerX: block.width / 2, // 中心点X坐标centerY: block.height / 2, // 中心点Y坐标
})5.3 平移动画属性
.translate({ x: block.initialOffsetX, y: block.initialOffsetY, z: 0 })【完整代码】
ObservedV2 // 监听数据变化的装饰器
class TangramBlock { // 定义七巧板类width: number; // 宽度height: number; // 高度points: Array[number, number]; // 点坐标数组color: string; // 颜色Trace initialOffsetX: number; // 初始X偏移量Trace initialOffsetY: number; // 初始Y偏移量Trace currentOffsetX: number; // 当前X偏移量Trace currentOffsetY: number; // 当前Y偏移量Trace rotationAngle: number; // 旋转角度Trace flipAngle: number 0; // 翻转角度默认为0Trace rotateValue: number; // 旋转值defaultInitialOffsetX: number; // 默认初始X偏移量defaultInitialOffsetY: number; // 默认初始Y偏移量defaultRotationAngle: number; // 默认旋转角度constructor(color: string, width: number, height: number, initialOffsetX: number, initialOffsetY: number,rotationAngle: number, points: Array[number, number]) {this.initialOffsetX this.currentOffsetX this.defaultInitialOffsetX initialOffsetX; // 初始化X偏移量this.initialOffsetY this.currentOffsetY this.defaultInitialOffsetY initialOffsetY; // 初始化Y偏移量this.rotationAngle this.rotateValue this.defaultRotationAngle rotationAngle; // 初始化旋转角度this.color color; // 设置颜色this.width width; // 设置宽度this.height height; // 设置高度this.points points; // 设置点坐标数组}resetData() { // 重置数据方法this.flipAngle 0; // 重置翻转角度this.initialOffsetX this.currentOffsetX this.defaultInitialOffsetX; // 重置初始X偏移量this.initialOffsetY this.currentOffsetY this.defaultInitialOffsetY; // 重置初始Y偏移量this.rotationAngle this.rotateValue this.defaultRotationAngle; // 重置旋转角度}
}const baseUnitLength: number 80; // 基本单位长度Entry // 入口组件
Component // 定义组件
export struct Index { // 主组件State selectedBlockIndex: number -1; // 当前选中位置State blocks: TangramBlock[] [// 七巧板数组// 小直角等腰三角形new TangramBlock(#fed8e5, baseUnitLength, baseUnitLength, -33.58, -58.02, 135,[[0, 0], [baseUnitLength, 0], [0, baseUnitLength]]),new TangramBlock(#0a0bef, baseUnitLength, baseUnitLength, 78.76, 54.15, 45,[[0, 0], [baseUnitLength, 0], [0, baseUnitLength]]),// 中直角等腰三角形new TangramBlock(#ff0d0c, baseUnitLength * Math.sqrt(2), baseUnitLength * Math.sqrt(2), -33.16, -1.43, -90,[[0, 0], [baseUnitLength * Math.sqrt(2), 0], [0, baseUnitLength * Math.sqrt(2)]]),// 大直角等腰三角形new TangramBlock(#ffa60a, baseUnitLength * 2, baseUnitLength * 2, 22.46, -172, -135,[[0, 0], [baseUnitLength * 2, 0], [0, baseUnitLength * 2]]),new TangramBlock(#3da56a, baseUnitLength * 2, baseUnitLength * 2, 135.65, -59.34, -45,[[0, 0], [baseUnitLength * 2, 0], [0, baseUnitLength * 2]]),// 正方形new TangramBlock(#ffff0b, baseUnitLength, baseUnitLength, 23.07, -1.84, -45,[[0, 0], [baseUnitLength, 0], [baseUnitLength, baseUnitLength], [0, baseUnitLength]]),// 平行四边形new TangramBlock(#5e0b9b, baseUnitLength * 2, baseUnitLength, -61.53, -85.97, 45,[[0, 0], [baseUnitLength, 0], [baseUnitLength * 2, baseUnitLength], [baseUnitLength, baseUnitLength]])];build() { // 构建方法Column({ space: 30 }) { // 创建垂直布局Stack() { // 创建堆叠布局ForEach(this.blocks, (block: TangramBlock, index: number) { // 遍历七巧板数组Stack() { // 创建堆叠布局Polygon({ width: block.width, height: block.height })// 绘制多边形.points(block.points)// 设置多边形顶点坐标.fill(block.color)// 填充颜色.draggable(false)// 长按不可拖动.rotate({ angle: block.rotationAngle }) // 旋转角度}.rotate({// 旋转x: 0,y: 1,z: 0,angle: block.flipAngle,centerX: block.width / 2, // 中心点X坐标centerY: block.height / 2, // 中心点Y坐标}).width(block.width) // 设置宽度.height(block.height) // 设置高度.onTouch(() { // 触摸事件this.selectedBlockIndex index; // 设置选中索引}).draggable(false) // 长按不可拖动.translate({ x: block.initialOffsetX, y: block.initialOffsetY, z: 0 }) // 平移.gesture( // 手势操作PanGesture()// 拖动手势.onActionUpdate((event: GestureEvent | undefined) { // 更新事件if (event) {block.initialOffsetX block.currentOffsetX event.offsetX; // 更新X偏移量block.initialOffsetY block.currentOffsetY event.offsetY; // 更新Y偏移量}}).onActionEnd((event: GestureEvent | undefined) { // 结束事件if (event) {block.currentOffsetX block.initialOffsetX; // 更新当前X偏移量block.currentOffsetY block.initialOffsetY; // 更新当前Y偏移量}})).zIndex(this.selectedBlockIndex index ? 1 : 0) // 设置层级.borderWidth(2) // 边框宽度.borderStyle(BorderStyle.Dashed) // 边框样式.borderColor(this.selectedBlockIndex index ? #80a8a8a8 : Color.Transparent) // 边框颜色})}.width(100%).height(750lpx) // 设置宽高.backgroundColor(#e4f2f5) // 背景颜色// 旋转角度计数器Column({ space: 5 }) { // 创建垂直布局设置间距Text(旋转角度(间隔5)).fontColor(Color.Black) // 显示旋转角度文本设置字体颜色Counter() { // 创建计数器组件Text(${this.selectedBlockIndex ! -1 ? this.blocks[this.selectedBlockIndex].rotationAngle :-})// 显示当前选中七巧板的旋转角度或占位符.fontColor(Color.Black) // 设置字体颜色}.width(300) // 设置计数器宽度.onInc(() { // 增加按钮的点击事件if (this.selectedBlockIndex ! -1) {animateTo({}, () {this.blocks[this.selectedBlockIndex].rotationAngle 5; // 增加旋转角度})}}).onDec(() { // 减少按钮的点击事件if (this.selectedBlockIndex ! -1) {animateTo({}, () {this.blocks[this.selectedBlockIndex].rotationAngle - 5; // 减少旋转角度})}});}// 旋转角度计数器Column({ space: 5 }) { // 创建垂直布局设置间距Text(旋转角度(间隔45)).fontColor(Color.Black) // 显示旋转角度文本设置字体颜色Counter() { // 创建计数器组件Text(${this.selectedBlockIndex ! -1 ? this.blocks[this.selectedBlockIndex].rotationAngle :-})// 显示当前选中七巧板的旋转角度或占位符.fontColor(Color.Black) // 设置字体颜色}.width(300) // 设置计数器宽度.onInc(() { // 增加按钮的点击事件if (this.selectedBlockIndex ! -1) {animateTo({}, () {this.blocks[this.selectedBlockIndex].rotationAngle 45; // 增加旋转角度})}}).onDec(() { // 减少按钮的点击事件if (this.selectedBlockIndex ! -1) {animateTo({}, () {this.blocks[this.selectedBlockIndex].rotationAngle - 45; // 减少旋转角度})}});}// 翻转按钮Row() { // 创建水平布局Button(向左翻转).onClick(() { // 左翻转按钮点击事件animateTo({}, () {if (this.selectedBlockIndex ! -1) {this.blocks[this.selectedBlockIndex].flipAngle - 180; // 减少翻转角度}});});Button(向右翻转).onClick(() { // 右翻转按钮点击事件animateTo({}, () {if (this.selectedBlockIndex ! -1) {this.blocks[this.selectedBlockIndex].flipAngle 180; // 增加翻转角度}});});}.width(100%).justifyContent(FlexAlign.SpaceEvenly) // 设置宽度和内容对齐方式// 重置和隐藏边框按钮Row() { // 创建水平布局Button(重置).onClick(() { // 重置按钮点击事件animateTo({}, () {for (let i 0; i this.blocks.length; i) {this.blocks[i].resetData(); // 重置七巧板数据}this.selectedBlockIndex -1; // 重置选中索引});});Button(隐藏边框).onClick(() { // 隐藏边框按钮点击事件this.selectedBlockIndex -1; // 重置选中索引});}.width(100%).justifyContent(FlexAlign.SpaceEvenly) // 设置宽度和内容对齐}.width(100%).height(100%)}
}