opencv中的snake_如何在SwiftUI中创建Snake游戏

opencv中的snake

枚举和变量 (Enum and Variables)

We are going to detect the swipe direction and have the snake move in that direction constantly until the direction changes. Let’s first create an enum for the directions:

我们将检测滑动方向,并让蛇不断朝该方向移动,直到方向改变为止。 首先,为这些方向创建一个枚举:

enum direction {
    case up, down, left, right
}

We will have a timer to control the snake’s speed. To make the snake slower or faster, we can change the timer’s intervals. The snake size is used instead of a grid. It will help us control the position of the snake and its food. We will need the following variables in our game:

我们将有一个计时器来控制蛇的速度。 为了使蛇变慢或变快,我们可以更改计时器的间隔。 使用蛇大小而不是网格。 这将帮助我们控制蛇及其食物的位置。 我们的游戏中将需要以下变量:

@State var startPos : CGPoint = .zero // the start poisition of our swipe
@State var isStarted = true // did the user started the swipe?
@State var gameOver = false // for ending the game when the snake hits the screen borders
@State var dir = direction.down // the direction the snake is going to take
@State var posArray = [CGPoint(x: 0, y: 0)] // array of the snake's body positions
@State var foodPos = CGPoint(x: 0, y: 0) // the position of the food
let snakeSize : CGFloat = 10 // width and height of the snake 
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect() // to updates the snake position every 0.1 second

蛇视图元素 (Snake View Elements)

Inside our body, add a ZStack. Inside of that, you can add color for your background. We are going to need another ZStack for our snake rectangle and the food rectangle. To create the snake body, we are going to iterate the array that holds the snake body position. Give both rectangles the width and height of our snakeSize variable. The last element inside our view is a text view that appears when our gameOver variable is toggled on:

在我们体内,添加一个ZStack 。 在其中,您可以为背景添加颜色。 我们将需要另一个ZStack用于我们的蛇形矩形和食物矩形。 为了创建蛇体,我们将迭代保留蛇体位置的​​数组。 将两个矩形的宽度和高度都指定为snakeSize变量。 视图中的最后一个元素是文本视图,该文本视图在打开gameOver变量时显示:

var body: some View {
        ZStack {
            Color.pink.opacity(0.3)
            ZStack {
                ForEach (0..<posArray.count, id: \.self) { index in
                    Rectangle()
                        .frame(width: self.snakeSize, height: self.snakeSize)
                        .position(self.posArray[index])
                }
                Rectangle()
                    .fill(Color.red)
                    .frame(width: snakeSize, height: snakeSize)
                    .position(foodPos)
            }
            
            if self.gameOver {
                Text("Game Over")
            }
        }
    }

功能 (Functions)

Create a function that determines the position of our rectangles. To position the snake and food in an invisible grid, we need to utilize the snake size to find how many rows and columns we can have inside our view:

创建一个确定矩形位置的函数。 要将蛇和食物放置在不可见的网格中,我们需要利用蛇的大小来查找视图中可以容纳的行和列的数量:

let minX = UIScreen.main.bounds.minX
let maxX = UIScreen.main.bounds.maxX
let minY = UIScreen.main.bounds.minY
let maxY = UIScreen.main.bounds.maxY


func changeRectPos() -> CGPoint {
        let rows = Int(maxX/snakeSize)
        let cols = Int(maxY/snakeSize)
        
        let randomX = Int.random(in: 1..<rows) * Int(snakeSize)
        let randomY = Int.random(in: 1..<cols) * Int(snakeSize)
        
        return CGPoint(x: randomX, y: randomY)
    }

To one of our ZStacks, we can add .onAppear to set the position for our snake and food using the function we created above:

在我们的一个ZStacks ,我们可以添加.onAppear以使用上面创建的函数设置蛇和食物的位置:

.onAppear() {
     self.foodPos = self.changeRectPos()
     self.posArray[0] = self.changeRectPos()
}

Create a function that checks whether the snake is inside or outside the screen borders, checks the direction of the user’s swipe, and then moves the snake in that direction:

创建一个函数来检查蛇是否在屏幕边界之内或之外,检查用户滑动的方向,然后沿该方向移动蛇:

func changeDirection () {
        if self.posArray[0].x < minX || self.posArray[0].x > maxX && !gameOver{
            gameOver.toggle()
        }
        else if self.posArray[0].y < minY || self.posArray[0].y > maxY  && !gameOver {
            gameOver.toggle()
        }
        var prev = posArray[0]
        if dir == .down {
            self.posArray[0].y += snakeSize
        } else if dir == .up {
            self.posArray[0].y -= snakeSize
        } else if dir == .left {
            self.posArray[0].x += snakeSize
        } else {
            self.posArray[0].x -= snakeSize
        }
        
        for index in 1..<posArray.count {
            let current = posArray[index]
            posArray[index] = prev
            prev = current
        }
    }

We can determine which direction the user has swiped in with the following code that uses the DragGesture to get the start and end positions of the swipe and then calculates the differences between the x-coordinates and y-coordinates to determine the swipe direction. Add the following function to our first ZStack:

我们可以使用以下代码来确定用户向哪个方向滑动,该代码使用DragGesture获取滑动的开始和结束位置,然后计算x坐标和y坐标之间的差值,以确定滑动方向。 将以下功能添加到我们的第一个ZStack

.gesture(DragGesture()
        .onChanged { gesture in
            if self.isStarted {
                self.startPos = gesture.location
                self.isStarted.toggle()
            }
        }
        .onEnded {  gesture in
            let xDist =  abs(gesture.location.x - self.startPos.x)
            let yDist =  abs(gesture.location.y - self.startPos.y)
            if self.startPos.y <  gesture.location.y && yDist > xDist {
                self.dir = direction.down
            }
            else if self.startPos.y >  gesture.location.y && yDist > xDist {
                self.dir = direction.up
            }
            else if self.startPos.x > gesture.location.x && yDist < xDist {
                self.dir = direction.right
            }
            else if self.startPos.x < gesture.location.x && yDist < xDist {
                self.dir = direction.left
            }
            self.isStarted.toggle()
            }
        )

All we need to add to our ZStack to finish up the game is a .onReceieve function that takes our timer and updates the snake and food’s positions. When the snake is on top of the food, append a new position to our array of snake body positions to make the snake longer:

我们需要添加到ZStack来完成游戏的全部是.onReceieve函数,该函数需要我们的计时器并更新蛇和食物的位置。 当蛇在食物上方时,将新位置附加到我们的蛇体位置数组中以使蛇变长:

.onReceive(timer) { (_) in
         if !self.gameOver {
              self.changeDirection()
              if self.posArray[0] == self.foodPos {
                   self.posArray.append(self.posArray[0])
                    self.foodPos = self.changeRectPos()
               }
         }
       }
        .edgesIgnoringSafeArea(.all)
Image for post

All done! Thanks for reading.

全做完了! 谢谢阅读。

翻译自: https://medium.com/better-programming/how-to-create-the-snake-game-in-swiftui-14a7e8162bf3

opencv中的snake

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值