在移动应用开发中,抽卡机制作为一种常见的用户互动方式,广泛应用于各类游戏中,以提升用户体验和增强游戏的趣味性。ArkTS(Ark TypeScript)作为OpenHarmony系统下的主要编程语言,继承了TypeScript的大部分语法特性,并针对移动开发场景进行了优化,旨在实现更高效的运行时性能和更低的资源消耗。本文将详细介绍如何使用ArkTS来实现一个基础的抽卡效果,通过结合界面布局、状态管理、及用户交互,来展现ArkTS在开发过程中的强大功能和灵活性。
接口定义
interface Icart {
bgcart: ResourceStr //背景图
frontcart: ResourceStr //卡牌
count: number //用于计数
}
接口定义了图片的数据结构,便于图片的处理以及卡牌计数
实现思路
- 大布局 立即抽卡 开心收下
- 点击立即抽卡 显示中卡页面
- 判断是否获取全部卡片
- 首先我们要定义一个数字类型的数据,判断 如果是初始页面数字为0 ,中奖页面数字为1 ,集齐所有卡牌数字为2 来切换页面
页面结构和布局
- 实现抽卡的页面主要是用 stack()层叠布局把控全局,Flex()弹性布局负责卡片的布局
//静态布局
Column() {
Stack() {
Column({ space: 50 }) {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.cart, (item: Icart, index,) => {
FlowItem() {
//Badge 用来计数 它可以计算获得卡牌相同的个数
Badge({ count: item.count, style: {} }) {
Image(item.count > 0 ? item.frontcart : item.bgcart)
.width(110)
.margin({ bottom: 10 })
}
}
.width('33.33%')
})
}
Button('立即抽卡')
.width(200)
.backgroundColor(Color.Pink)
.onClick(() => {
this.curren = Math.floor(Math.random() * this.cart.length)
let item = this.cart[this.curren]
item.count++ //计数
this.cart.splice(this.curren, 1, item)
this.num = 1
})
}
//点击抽卡 num赋值给1
//遮盖层
if (this.num == 1) {
Column({ space: 44 }) {
Text('获得卡牌')
.fontSize(30)
Image(this.cart[this.curren].frontcart)
.width('65%')
Button('开心收下')//统计是否获得全部
.backgroundColor(Color.Pink)
.width(200)
.onClick(() => {
let count = 0
for (let index = 0; index < this.cart.length; index++) {
const element = this.cart[index]
if (element.count > 0) {
count++
}
if (count == this.cart.length) {
this.num = 2
} else {
this.num = 0
}
}
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.4)')
}
if (this.num == 2) {
Column() {
Text('恭喜你获得全部卡牌')
.fontColor(Color.Red)
.fontSize(35)
.margin({ bottom: 100 })
Button('确认')
.backgroundColor(Color.Pink)
.width(200)
.translate({ y: 185 })
.onClick(() => {
this.num = 0
this.cart = [{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10001'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10002'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10003'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10004'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10005'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10006'), count: 0 },]
})
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.9)')
}
}
.width('100%')
.height('100%')
}
- Text 用于显示页面标题
- Button 组件添加了点击事件处理,触发抽卡效果并更新相关状态变量
卡片计数
FlowItem() {
//Badge 用来计数 它可以计算获得卡牌相同的个数
Badge({ count: item.count, style: {} }) {
Image(item.count > 0 ? item.frontcart : item.bgcart)
.width(110)
.margin({ bottom: 10 })
}
}
.width('33.33%')
})
点击立即抽卡
Button('立即抽卡')
.width(200)
.backgroundColor(Color.Pink)
.onClick(() => {
this.curren = Math.floor(Math.random() * this.cart.length) //随机获得一个0-5数据
let item = this.cart[this.curren]
item.count++ //计数
this.cart.splice(this.curren, 1, item)
this.num = 1
//延时器 卡片动画效果
setTimeout(() => {
this.scalecart = 1
}, 100)
})
}
获得卡片
//点击抽卡 num赋值给1
//遮盖层
if (this.num == 1) {
Column({ space: 44 }) {
Text('获得卡牌')
.fontSize(30)
Image(this.cart[this.curren].frontcart)
.width('65%')
.scale({
x: this.scalecart, y: this.scalecart
})
.animation({
duration: 500
})
Button('开心收下')//统计是否获得全部
.backgroundColor(Color.Pink)
.width(200)
.onClick(() => {
let count = 0
for (let index = 0; index < this.cart.length; index++) {
const element = this.cart[index]
if (element.count > 0) {
count++
}
if (count == this.cart.length) {
this.num = 2
} else {
this.num = 0
}
}
this.scalecart = 0
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.4)')
}
集齐所有卡牌,数据清理
if (this.num == 2) {
Column() {
Text('恭喜你获得全部卡牌')
.fontColor(Color.Red)
.fontSize(35)
.margin({ bottom: 100 })
Button('确认')
.backgroundColor(Color.Pink)
.width(200)
.translate({ y: 185 })
.onClick(() => {
this.num = 0
//数据重置
this.cart = [{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10001'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10002'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10003'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10004'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10005'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10006'), count: 0 },]
})
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.9)')
}
}
.width('100%')
.height('100%')
整体代码及运行
interface Icart {
bgcart: ResourceStr //背景图
frontcart: ResourceStr //卡牌
count: number //用于计数
}
@Entry
@Component
struct Index {
//获取卡片的数据
@State
cart: Icart[] = [{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10001'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10002'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10003'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10004'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10005'), count: 0 },
{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10006'), count: 0 },]
@State curren: number = -1
@State num: number = 0
@State scalecart: number = 0
build() {
//静态布局
Column() {
Stack() {
Column({ space: 50 }) {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.cart, (item: Icart, index,) => {
FlowItem() {
//Badge 用来计数 它可以计算获得卡牌相同的个数
Badge({ count: item.count, style: {} }) {
Image(item.count > 0 ? item.frontcart : item.bgcart)
.width(110)
.margin({ bottom: 10 })
}
}
.width('33.33%')
})
}
Button('立即抽卡')
.width(200)
.backgroundColor(Color.Pink)
.onClick(() => {
this.curren = Math.floor(Math.random() * this.cart.length)
let item = this.cart[this.curren]
item.count++ //计数
this.cart.splice(this.curren, 1, item)
this.num = 1
//延时器
setTimeout(() => {
this.scalecart = 1
}, 100)
})
}
//点击抽卡 num赋值给1
//遮盖层
if (this.num == 1) {
Column({ space: 44 }) {
Text('获得卡牌')
.fontSize(30)
Image(this.cart[this.curren].frontcart)
.width('65%')
.scale({
x: this.scalecart, y: this.scalecart
})
.animation({
duration: 500
})
Button('开心收下')//统计是否获得全部
.backgroundColor(Color.Pink)
.width(200)
.onClick(() => {
let count = 0
for (let index = 0; index < this.cart.length; index++) {
const element = this.cart[index]
if (element.count > 0) {
count++
}
if (count == this.cart.length) {
this.num = 2
} else {
this.num = 0
}
}
this.scalecart = 0
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.4)')
}
if (this.num == 2) {
Column() {
Text('恭喜你获得全部卡牌')
.fontColor(Color.Red)
.fontSize(35)
.margin({ bottom: 100 })
Button('确认')
.backgroundColor(Color.Pink)
.width(200)
.translate({ y: 185 })
.onClick(() => {
//返回初始页面
this.num = 0
//获得全部卡牌时数据清零
this.cart = [{ bgcart: $r('app.media.10007'), frontcart: $r('app.media.10001'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10002'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10003'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10004'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10005'), count: 0 }, { bgcart: $r('app.media.10007'), frontcart: $r('app.media.10006'), count: 0 },]
})
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.backgroundColor('rgba( 43, 43, 43 ,0.9)')
}
}
.width('100%')
.height('100%')
}
}
}