鸿蒙案例-生效抽卡
·
本案例需要实现的是:用户通过点击"立即抽卡"按钮随机获取卡片,集齐六张不同生肖卡后触发胜利界面显示"恭喜获得手机一部",并支持重置游戏重新开始。
下面我将一步一步带你完成这个案例。
首先我们先完成静态页面:将卡片的背面以及角标和按钮静态部署好。
@Entry
@Component
struct Index {
build() {
Column() {
// 一. 初始界面
Column() {
// 图片区域
Flex({ wrap: FlexWrap.Wrap }) {
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
Badge({
count: 1,
style: { badgeSize: 16, badgeColor: '#f00', fontSize: 14 }
}) {
Image($r('app.media.bg_00'))
.width(80)
}
.margin(15)
}
.margin({ top: 100, bottom: 50 })
.padding({ left: 15 })
// 抽卡按钮
Button('立即抽卡')
.width(200)
.backgroundColor('#ED5B8C')
.stateStyles({
clicked: {
.backgroundColor('#EA446C')
}
})
.animation({
duration: 1000
})
}
}
}
}
第二步:准备一下我们的需要用到的数据,如:生肖卡的正面,角标的次数等。同时使用foreach将页面渲染。
// 初始界面卡片接口
interface Card {
url: string
num: number
}
@Entry
@Component
struct Index {
// 初始界面卡片状态
@State
images: Card[] = [
//url为图片的地址,unm是角标的次数,也就是每抽到一次卡片,角标数量会进行加1.
{url: 'app.media.bg_00', num: 0},
{url: 'app.media.bg_01', num: 0},
{url: 'app.media.bg_02', num: 0},
{url: 'app.media.bg_03', num: 0},
{url: 'app.media.bg_04', num: 0},
{url: 'app.media.bg_05', num: 0}
]
build() {
Column() {
Column() {
// 图片区域
Flex({wrap: FlexWrap.Wrap}) {
ForEach(this.images, (item: Card, index: number) => {
Badge({
count: item.num,
style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}
}) {
Image($r(`${item.url}`))
.width(80)
}
.margin(15)
})
}
.margin({top: 100, bottom: 50})
.padding({left: 15})
// 抽卡按钮
Button('立即抽卡')
.width(200)
.backgroundColor('#ED5B8C')
.stateStyles({
clicked: {
.backgroundColor('#EA446C')
}
})
.animation({
duration: 1000
})
}
}
}
}
第三步:制作我们的遮罩层,以透明的黑色为背景将整个屏幕占据,然后在中间制作出标题、卡片正面和按钮。
Column({space: 30}) {
Text('获取生肖卡')
.fontColor('#F5EBCF')
.fontSize(25)
.fontWeight(600)
Image($r('app.media.img_00'))
.width(200)
Button('开心收下')
.width(200)
.height(50)
.backgroundColor(Color.Transparent)
.border({width: 2, color: '#FFF9E0'})
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.8)')
.justifyContent(FlexAlign.Center)
.position({x: 0, y: 0})
第四步:将我们的遮罩层和两个按钮绑定起来并为卡片做缩放的动画。
在隐藏遮罩层时需要注意一点,属性不可以使用opacity。opacity是透明度 ,它只是视觉效果上看不到了,但还是存在的,会遮挡住下面的组件。所以我们这里使用visibility属性,visibility是隐藏和显示组件。
// 是否显示生肖卡界面状态
@State
isVisible: boolean = false
// 生肖卡缩放状态
@State
imgX: number = 0
@State
imgY: number = 0
// 抽卡按钮
Button('立即抽卡')
.width(200)
.backgroundColor('#ED5B8C')
.stateStyles({
clicked: {
.backgroundColor('#EA446C')
}
})
.animation({
duration: 1000
})
.onClick(() => {
this.isVisible = true
this.imgX = 1
this.imgY = 1
})
Column({space: 30}) {
Image($r('app.media.img_00'))
.width(200)
.scale({x: this.imgX, y: this.imgY})
.animation({duration: 400})
Button('开心收下')
.onClick(() => {
// 生肖卡界面隐藏;卡片隐藏
this.isVisible = false
this.imgX = 0
this.imgY = 0
})
}
// 使用状态控制整个界面显隐
.visibility(this.isVisible ? Visibility.Visible : Visibility.Hidden)
第五步:实现收下卡片后卡牌角标加1和中奖的静态页面
// 随机生肖卡序号
@State
randomIndex: number = -1
Button('立即抽卡')
.onClick(() => {
// 随机生肖卡 0-5
this.randomIndex = Math.floor(Math.random() * 6)
})
Column({space: 30}) {
// 使用生成的随机数筛选生肖卡
Image($r(`app.media.img_0${this.randomIndex}`))
Button('开心收下')
.onClick(() => {
// 收下卡片更新对象数组 -- 替换初始界面图片url和角标数字
this.images[this.randomIndex] = {
url: `app.media.img_0${this.randomIndex}`,
num: this.images[this.randomIndex].num += 1
}
})
}
// 抽奖页面-遮罩层
Column({space: 50}) {
Text('恭喜获得手机一部')
.fontColor('#F5EBCF')
.fontSize(25)
.fontWeight(600)
Image($r('app.media.hw'))
.width(300)
Button('再来一次')
.width(200)
.height(50)
.backgroundColor(Color.Transparent)
.border({width: 2, color: '#FFF9E0'})
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.8)')
.justifyContent(FlexAlign.Center)
.position({x: 0, y: 0})
第六步:实现是否中奖的判断和中奖之后的页面以及重新开始。
Column({ space: 50 }) {
Text('恭喜获得手机一部')
.fontColor('#F5EBCF')
.fontSize(25)
.fontWeight(600)
Image($r('app.media.hw'))
.width(300)
Button('再来一次')
.width(200)
.height(50)
.backgroundColor(Color.Transparent)
.border({ width: 2, color: '#FFF9E0' })
.onClick(() => {
this.ifWin = false
this.cards = [{ url: 'app.media.bg_00', countNum: 0 },
{ url: 'app.media.bg_01', countNum: 0 },
{ url: 'app.media.bg_02', countNum: 0 },
{ url: 'app.media.bg_03', countNum: 0 },
{ url: 'app.media.bg_04', countNum: 0 },
{ url: 'app.media.bg_05', countNum: 0 }]
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.8)')
.justifyContent(FlexAlign.Center)
.position({ x: 0, y: 0 })
.visibility(this.ifWin ? Visibility.Visible : Visibility.Hidden)
这样就可以实现一个完整的抽卡游戏了。最后附上全部代码
interface Card {
url: string
countNum: number
}
@Entry
@Component
struct Index {
@State cards: Card[] = [
{ url: 'app.media.bg_00', countNum: 0 },
{ url: 'app.media.bg_01', countNum: 0 },
{ url: 'app.media.bg_02', countNum: 0 },
{ url: 'app.media.bg_03', countNum: 0 },
{ url: 'app.media.bg_04', countNum: 0 },
{ url: 'app.media.bg_05', countNum: 0 }
]
@State isShow: boolean = false
@State rands: number = 0
@State imgX: number = 0
@State imgY: number = 0
@State ifWin: boolean = false
build() {
Column() {
Column({ space: 60 }) {
Flex({
wrap: FlexWrap.Wrap,
justifyContent: FlexAlign.SpaceBetween
}) {
ForEach(this.cards, (item: Card, index: number) => {
Badge({ count: item.countNum, style: {} }) {
Image($r(item.url))
.syncLoad(true)
.width(100)
}
})
}
.padding(15)
Button('立即抽卡')
.width('70%')
.backgroundColor(' #e05582 ')
.onClick(() => {
this.isShow = true
this.imgX = 1
this.imgY = 1
this.rands = Math.floor(Math.random() * 6)
})
Column({ space: 30 }) {
Text('获取生肖卡')
.fontColor('#F5EBCF')
.fontSize(25)
.fontWeight(600)
Image($r(`app.media.img_0${this.rands}`))
.width(200)
.syncLoad(true)
.scale({ x: this.imgX, y: this.imgY })
.animation({})
Button('开心收下')
.width(200)
.height(50)
.backgroundColor(Color.Transparent)
.border({ width: 2, color: '#FFF9E0' })
.onClick(() => {
this.isShow = false
this.imgX = 0
this.imgY = 0
this.cards[this.rands] =
{ url: `app.media.img_0${this.rands}`, countNum: ++this.cards[this.rands].countNum }
let count: number = 0
for (let item of this.cards) {
if (item.countNum >= 1) {
count++
} else {
break
}
}
if (count === 6) {
this.ifWin = true
}
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.8)')
.justifyContent(FlexAlign.Center)
.position({ x: 0, y: 0 })
//opacity是透明度 ,只是看不见了但是还存在。会遮挡下面的内容。
// .opacity(this.opaNum)
//visibility 隐藏和显示组件 Visibility.Visible 是显示 ,Visibility.Hidden 是隐藏
.visibility(this.isShow ? Visibility.Visible : Visibility.Hidden)
// 抽奖页面-遮罩层
Column({ space: 50 }) {
Text('恭喜获得手机一部')
.fontColor('#F5EBCF')
.fontSize(25)
.fontWeight(600)
Image($r('app.media.hw'))
.width(300)
Button('再来一次')
.width(200)
.height(50)
.backgroundColor(Color.Transparent)
.border({ width: 2, color: '#FFF9E0' })
.onClick(() => {
this.ifWin = false
this.cards = [{ url: 'app.media.bg_00', countNum: 0 },
{ url: 'app.media.bg_01', countNum: 0 },
{ url: 'app.media.bg_02', countNum: 0 },
{ url: 'app.media.bg_03', countNum: 0 },
{ url: 'app.media.bg_04', countNum: 0 },
{ url: 'app.media.bg_05', countNum: 0 }]
})
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.8)')
.justifyContent(FlexAlign.Center)
.position({ x: 0, y: 0 })
.visibility(this.ifWin ? Visibility.Visible : Visibility.Hidden)
}
.height('100%')
.justifyContent(FlexAlign.Center)
}
.width('100%')
.height('100%')
}
}
更多推荐



所有评论(0)