交互逻辑
我们继续来完成石头剪刀布的逻辑部分,本章可能对于初学者有点难度,我们一步一步来。
系统出牌方法
首先是系统出牌部分,我们可以使用随机数来获得数组中的数据来作为系统出牌结果,示例:
// 随机猜拳方法 func randomPush() { let index = Int.random(in: 0 ... 2) computerPushImage = gameModels[index] gameTimes -= 1 } 复制代码
上述代码中,我们通过random
函数获得0到2
的随机数值,然后把computerPushImage
系统出牌结果赋值为从gameModels
数组中随机取的的结果,并且每次出牌后gameTimes
游戏次数就会减少。
然后我们在立即猜拳的操作中增加点击交互,示例:
// 立即猜拳 func playGame() -> some View { Text("立即猜拳") .font(.system(size: 17)) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 10, maxHeight: 32) .padding() .foregroundColor(.white) .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255)) .cornerRadius(8) .onTapGesture { if isSelected { randomPush() } } } 复制代码
上述代码中,我们给playGame
视图中的Text
添加了onTapGesture
修饰符,当我们点击时判断下用户是否了出牌,选择后我们才调用系统随机猜拳的方法。
猜拳结果判断
有了系统猜拳后,在用户选择出牌后,我们需要合系统出牌进行对比,看看谁赢,我们这里创建一个方法来判断猜拳结果。
首先要声明3个变量
来展示所需的结果。示例:
@State var computerWinCount: Int = 0 @State var winName: String = "" @State var winMessage: String = "" 复制代码
上述代码中,我们声明了三个变量computerWinCount
计算机赢的次数,winName
谁赢,winMessage
结果的描述信息。
然后我们创建一个方法来判断猜拳结果。示例:
// 判断最终猜拳结果 func showWinner() { if computerPushImage == "rock" && selectedImage == "paper" || computerPushImage == "paper" && selectedImage == "scissors" || computerPushImage == "scissors" && selectedImage == "rock" { winName = "你输了" computerWinCount += 1 winMessage = "你还有" + String(gameTimes) + "次机会" } else if computerPushImage == selectedImage { gameTimes += 1 winName = "平手" winMessage = "你还有" + String(gameTimes) + "次机会" } else { winName = "你赢了" winMessage = "你还有" + String(gameTimes) + "次机会" } } 复制代码
上述代码中,我们创建了一个方法showWinner
。
我们判断computerPushImage
系统出牌和selectedImage
用户选择出牌的结果,如果计算机赢了,我们给winName
赋值,告知赢方。
若计算机赢了,computerWinCount
计算机赢的次数加1,且winMessage
拼接展示剩余的gameTimes
游戏次数。
若两者平手,则gameTimes
游戏次数加1,且同样展示赢方和剩余的gameTimes
游戏次数。
若用户赢了,也同样展示赢方和剩余的gameTimes
游戏次数。
然后我们在playGame
立即猜拳的视图中,点击操作时调用判断猜拳结果的方法,示例:
// 立即猜拳 func playGame() -> some View { Text("立即猜拳") .font(.system(size: 17)) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 10, maxHeight: 32) .padding() .foregroundColor(.white) .background(Color(red: 51 / 255, green: 51 / 255, blue: 51 / 255)) .cornerRadius(8) .onTapGesture { if isSelected { randomPush() showWinner() } } } 复制代码
游戏是否结束
有了系统猜拳的方法后,由于我们有几种规则:一局定胜负、三局两胜、五局三胜。
因此我们在每次猜拳后,还要根据游戏次数规则,判断游戏最终是否结束。
首先需要声明一个游戏的总次数参数,然后和系统赢的次数computerWinCount
做对比,示例:
@State var gameTotal: Int = 1 @State var isShowWinner: Bool = false 复制代码
我们声明了一个变量gameTotal
,用来存储游戏总次数,再声明了一个Bool
变量isShowWinner
,用来最后确定是否展示结果。
下一步还需要在系统规则中根据用户选择的游戏规则,对gameTotal
游戏总次数进行赋值,示例:
// 规则 func ruleView() -> some View { Menu { Button("一局定胜负") { self.gameTimes = 1 self.ruleName = "一局定胜负" self.gameTotal = 1 } Button("三局两胜") { self.gameTimes = 3 self.ruleName = "三局两胜" self.gameTotal = 3 } Button("五局三胜") { self.gameTimes = 5 self.ruleName = "五局三胜" self.gameTotal = 5 } } label: { Label(ruleName, systemImage: "slider.horizontal.3") .foregroundColor(.gray) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 10, maxHeight: 60) .background(Color(.systemGray6)) .cornerRadius(8) } } 复制代码
这时,我们就有了3个参数
来记录游戏玩的过程:gameTotal
游戏总次数,gameTimes
游戏剩余次数,computerWinCount
计算机赢的次数。
我们需要有个方法判断游戏是否结束,示例:
// 判断游戏是否结束 func isEndGame() { if gameTimes == 0 { if gameTotal == 5 && computerWinCount == 3 || gameTotal == 3 && computerWinCount == 2 || gameTotal == 1 && computerWinCount == 1 { computerWinCount = 0 gameTimes = gameTotal winName = "计算机赢了" winMessage = "游戏结束" isShowWinner = true } else { computerWinCount = 0 gameTimes = gameTotal winName = "你赢了" winMessage = "游戏结束" isShowWinner = true } } else { isShowWinner = true } } 复制代码
上述代码中,我们创建了一个方法isEndGame
,用来判断游戏是否结果。
判断规则首要判断gameTimes
游戏剩余次数是否为0
,如果游戏剩余次数为0
,则代表游戏结束。
游戏结束时,我们还需要判断gameTotal
游戏总次数和computerWinCount
计算机赢的次数的关系,如果满足规则,则代表计算机赢了。
这时我们需要重置计算机赢的次数computerWinCount``为0
,并且重置剩余的游戏次数gameTimes
等于游戏总次数,并告知winName
最终结果谁赢了,已经告知winMessage
游戏结束的信息。
如果游戏没有结束,也就是gameTimes
不为0
,则还是展示结果isShowWinner
。
我们把判断游戏是否结束的方法加到判断每次猜拳的结果方法中,示例:
// 判断最终猜拳结果 func showWinner() { if computerPushImage == "rock" && selectedImage == "paper" || computerPushImage == "paper" && selectedImage == "scissors" || computerPushImage == "scissors" && selectedImage == "rock" { winName = "你输了" computerWinCount += 1 winMessage = "你还有" + String(gameTimes) + "次机会" isEndGame() } else if computerPushImage == selectedImage { gameTimes += 1 winName = "平手" winMessage = "你还有" + String(gameTimes) + "次机会" isEndGame() } else { winName = "你赢了" winMessage = "你还有" + String(gameTimes) + "次机会" isEndGame() } } 复制代码
上述代码中,我们在每一次判断时,都调用isEndGame
判断游戏是否结束的方法。
猜拳结果展示
我们有了系统随机出牌的方法randomPush
,还有判断猜拳结果的方法showWinner
,再完成了判断游戏是否结束的方法isEndGame
。
最后我们还需要展示结果,我们可以通过Alert
弹窗来告知用户结果。示例:
// 展示猜拳结果 func showResult() -> Alert { let alert = Alert( title: Text(winName), message: Text(winMessage), dismissButton: .default(Text("继续")) { self.computerPushImage = "game" self.isSelected = false } ) return alert } 复制代码
上述代码中,我们创建了一个Alert
视图showResult
。
我们Alert
视图的标题title
关联winName
,信息message
关联winMessage
,当我们点击继续按钮时,computerPushImage
系统出牌恢复到默认图片,且用户选择isSelected
切换为未选择。
我们在body
主要视图中,调用Alert
方法,示例:
var body: some View { VStack(spacing: 20) { titleView() ruleView() computerPush() Spacer() Spacer() if isSelected { personPush() } else { personSelected() } Spacer() playGame() } .padding() .alert(isPresented: $isShowWinner) { showResult() } } 复制代码
项目成果展示
恭喜你,完成了整个项目的全部内容!
快来动手试试吧。