gpt4 book ai didi

带有 Core Graphics 的 iOS 动画

转载 作者:搜寻专家 更新时间:2023-11-01 06:36:31 28 4
gpt4 key购买 nike

我目前正在使用 Swift 在 iOS 中创建 Hangman 游戏应用程序。

我已经完成了所有的游戏机制,并且想使用 Core Graphics 来绘制刽子手和绞刑架。我可以使用 UIBezierPath 绘制绞架和刽子手,并将 View 的每个部分(绞架、头部、 body 、左臂……)的绘制分解为单独的函数,调用这些函数来创建整个图像。所有这些都在自定义 UIView 类中。

我似乎无法弄清楚的是如何在用户做出错误猜测时添加 Hangman 图像的连续部分。我试图避免在一系列图像之间循环。相反,我想使用相同的自定义 View 使用 Core Graphics 逐个绘制火柴人。

我如何实现绘制图形的每个连续部分的函数?

类似于“self.customView.updateDrawing()”,其中 customView 中的 updateDrawing 方法将从模型中获取有关错误猜测次数的信息,并调用适当的方法来绘制简笔画所需的部分。

更新

这是我尝试实现这篇文章 https://codereview.stackexchange.com/questions/97424/hangman-in-swift 中的观点进入我自己的刽子手游戏。它们非常适合绘制绞架,但实际上我无法让图像自行更新并绘制连续的 body 部位以添加刽子手。到目前为止,这是我的代码:

GameViewTwo:这是上面帖子中的 GameView,我尝试将其拆分并将不同的部分作为层添加到 View 中。

 import UIKit

enum BodyPart: Int {
case Head = 1
case Body = 2
case LeftArm = 5
case RightArm = 6
case LeftLeg = 3
case RightLeg = 4
case LeftEye = 7
case RightEye = 8
case Mouth = 9
case Unknown = 10
}


class GameViewTwo: UIView {

var path = UIBezierPath()
var newPartLayer = CAShapeLayer()

private var bodyStart: CGPoint = CGPoint.zero
private var bodyEnd: CGPoint = CGPoint.zero
private var headMiddle: CGPoint = CGPoint.zero

struct DrawingConstants {
static let gallowBaseStartScale: CGFloat = 0.15
static let gallowBaseEndScale: CGFloat = 0.85
static let gallowBaseHeight: CGFloat = 10
static let gallowHeight: CGFloat = 0.05 //static let gallowHeight: CGFloat = 0.15
static let gallowHeightStart: CGFloat = 0.175
static let gallowHeightWidth: CGFloat = 10
static let gallowAcrossScale: CGFloat = 0.5
static let gallowTipHeight: CGFloat = 17.5
static let headRadius: CGFloat = 16
static let bodyLength: CGFloat = 25
static let bodyHeight: CGFloat = 25
static let legLength: CGFloat = 50
static let grassHeightScale: CGFloat = 0.68
static let armBack: CGFloat = 5
}

struct ScaleConstants {
static let bodyLength: CGFloat = 50
static let limbLength: CGFloat = 25
static let handHeightScale: CGFloat = 0.4
static let headRadius: CGFloat = 20
static let eyeRadius = CGFloat(0.15 * ScaleConstants.headRadius)
static let eyeOffset = CGFloat(0.3 * ScaleConstants.headRadius)
static let mouthOffSet = CGFloat(0.3 * ScaleConstants.headRadius)
static let mouthRadius = CGFloat(0.25 * ScaleConstants.headRadius)
}

var part : BodyPart?

func setPart(part: BodyPart){
self.part = part
}


// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
drawGallow()

}


func add(part: BodyPart){

let partPath = path(forPart: part)
newPartLayer.frame = bounds
newPartLayer.path = partPath.cgPath
newPartLayer.strokeColor = UIColor.black.cgColor
let strokeAnim = CABasicAnimation(keyPath: "strokeEnd")
strokeAnim.fromValue = 0
strokeAnim.toValue = 1
strokeAnim.duration = 1
layer.addSublayer(newPartLayer)
newPartLayer.add(strokeAnim, forKey: "path")

}

func path(forPart: BodyPart)-> UIBezierPath {

switch forPart {

case BodyPart.Head :
let centerX = CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale - (DrawingConstants.gallowHeightWidth / 2))
let centerY = CGFloat(bounds.size.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight + DrawingConstants.gallowTipHeight + ScaleConstants.headRadius)
let center = CGPoint(x: centerX, y: centerY)
headMiddle = center
path = UIBezierPath(arcCenter: center, radius: ScaleConstants.headRadius, startAngle: CGFloat(0), endAngle: CGFloat(2 * M_PI), clockwise: true)
path.lineWidth = CGFloat(2)

return path

case BodyPart.Body :
let add = CGFloat(DrawingConstants.gallowBaseHeight + DrawingConstants.gallowTipHeight + 2 * ScaleConstants.headRadius)
let startPointY = CGFloat(bounds.size.height * DrawingConstants.gallowHeight + add)
let startPointX = CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale - (DrawingConstants.gallowHeightWidth / 2))
let startPoint = CGPoint(x: startPointX, y: startPointY)
let endPoint = CGPoint(x: startPoint.x, y: startPoint.y + ScaleConstants.bodyLength)
bodyStart = startPoint
bodyEnd = endPoint
path.lineWidth = CGFloat(2)
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case BodyPart.LeftLeg :
let startPoint = CGPoint(x: bodyEnd.x, y: bodyEnd.y)
let endPoint = CGPoint(x: startPoint.x - ScaleConstants.limbLength, y: startPoint.y + ScaleConstants.limbLength)
path.lineWidth = CGFloat(2)
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case BodyPart.RightLeg :
let startPoint = CGPoint(x: bodyEnd.x, y: bodyEnd.y)
let endPoint = CGPoint(x: startPoint.x + ScaleConstants.limbLength, y: startPoint.y + ScaleConstants.limbLength)
path.lineWidth = CGFloat(2)
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case BodyPart.LeftArm :
let startPoint = CGPoint(x: bodyStart.x, y: bodyStart.y + ScaleConstants.handHeightScale * ScaleConstants.bodyLength)
let endPoint = CGPoint(x: startPoint.x - ScaleConstants.limbLength, y: startPoint.y - ScaleConstants.limbLength * ScaleConstants.handHeightScale)
path.lineWidth = CGFloat(2)
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case BodyPart.RightArm :
let startPoint = CGPoint(x: bodyStart.x, y: bodyStart.y + ScaleConstants.handHeightScale * ScaleConstants.bodyLength)
let endPoint = CGPoint(x: startPoint.x + ScaleConstants.limbLength, y: startPoint.y - ScaleConstants.limbLength * ScaleConstants.handHeightScale)
path.lineWidth = CGFloat(2)
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case BodyPart.LeftEye :
UIColor.black.set()
let eyeMiddle = CGPoint(x: headMiddle.x - ScaleConstants.eyeOffset, y: headMiddle.y - ScaleConstants.eyeOffset)

let path = UIBezierPath(arcCenter: eyeMiddle, radius: ScaleConstants.eyeRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true)
path.lineWidth = CGFloat(1)
return path

case BodyPart.RightEye :
UIColor.black.set()
let eyeMiddle = CGPoint(x: headMiddle.x + ScaleConstants.eyeOffset, y: headMiddle.y - ScaleConstants.eyeOffset)

let path = UIBezierPath(arcCenter: eyeMiddle, radius: ScaleConstants.eyeRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true)
path.lineWidth = CGFloat(1)
return path

default:
return path
}
}

/******************************************************************************************/

func connectPoints(bottomLeftPoint: CGPoint, bottomRightPoint: CGPoint, topLeftPoint: CGPoint, topRightPoint: CGPoint, color: UIColor) {
color.set()

let path = UIBezierPath()
path.move(to: bottomLeftPoint)
path.addLine(to: topLeftPoint)
path.addLine(to: topRightPoint)
path.addLine(to: bottomRightPoint)
path.close()
path.fill()
path.stroke()

}

func calculateMidPoint(point1: CGPoint, point2: CGPoint) -> CGPoint {
return CGPoint(x: (point1.x + point2.x) / 2, y: (point1.y + point2.y) / 2)

}

/*****************************************************************************************/

func drawGrass() {
let topStartPoint = CGPoint(x: CGFloat(0), y: CGFloat(bounds.size.height * DrawingConstants.grassHeightScale))
let topRightPoint = CGPoint(x: CGFloat(bounds.size.width), y: topStartPoint.y)
let bottomRightPoint = CGPoint(x: topRightPoint.x, y: CGFloat(bounds.size.height))
let bottomLeftPoint = CGPoint(x: CGFloat(0), y: bottomRightPoint.y)

connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topStartPoint, topRightPoint: topRightPoint, color: UIColor.green)
}

func drawSky() {
let bottomLeftPoint = CGPoint(x: CGFloat(0), y: CGFloat(bounds.size.height * DrawingConstants.grassHeightScale))
let topLeftPoint = CGPoint(x: CGFloat(0), y: CGFloat(0))
let topRightPoint = CGPoint(x: CGFloat(bounds.size.width), y: CGFloat(0))
let bottomRightPoint = CGPoint(x: CGFloat(bounds.size.width), y: CGFloat(bounds.size.height * DrawingConstants.grassHeightScale))

connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topLeftPoint, topRightPoint: topRightPoint, color: UIColor.cyan)
}

func drawGallow() {
drawGallowBase()
drawGallowHeight()
drawGallowAcross()
drawGallowTip()
}

func drawGallowBase() {
let bottomLeftPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowBaseStartScale), y: CGFloat(bounds.size.height * DrawingConstants.grassHeightScale))
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: bottomLeftPoint.y - DrawingConstants.gallowBaseHeight)
let topRightPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowBaseEndScale), y: topLeftPoint.y)
let bottomRightPoint = CGPoint(x: topRightPoint.x, y: bottomLeftPoint.y)

connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topLeftPoint, topRightPoint: topRightPoint, color: UIColor.brown)
}

func drawGallowHeight() {
let bottomLeftPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowHeightStart), y: CGFloat(bounds.size.height * DrawingConstants.grassHeightScale - DrawingConstants.gallowBaseHeight))
let bottomRightPoint = CGPoint(x: bottomLeftPoint.x + DrawingConstants.gallowHeightWidth, y: bottomLeftPoint.y)
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: bounds.size.height * DrawingConstants.gallowHeight)
let topRightPoint = CGPoint(x: bottomRightPoint.x, y: topLeftPoint.y)

connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topLeftPoint, topRightPoint: topRightPoint, color: UIColor.brown)
}

func drawGallowAcross() {
let bottomLeftPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowHeightStart) + DrawingConstants.gallowHeightWidth, y: CGFloat(bounds.size.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight))
let bottomRightPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale), y: bottomLeftPoint.y)
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: CGFloat(bounds.size.height * DrawingConstants.gallowHeight))
let topRightPoint = CGPoint(x: CGFloat(bottomRightPoint.x), y: topLeftPoint.y)
connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topLeftPoint, topRightPoint: topRightPoint, color: UIColor.brown)
}

func drawGallowTip() {
let topLeftPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale - DrawingConstants.gallowHeightWidth), y: CGFloat(bounds.size.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight))
let topRightPoint = CGPoint(x: CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale), y: topLeftPoint.y)
let bottomLeftPoint = CGPoint(x: topLeftPoint.x, y: topLeftPoint.y + DrawingConstants.gallowTipHeight)
let bottomRightPoint = CGPoint(x: topRightPoint.x, y: bottomLeftPoint.y)

connectPoints(bottomLeftPoint: bottomLeftPoint, bottomRightPoint: bottomRightPoint, topLeftPoint: topLeftPoint, topRightPoint: topRightPoint, color: UIColor.brown)
}

/*******************************************************************************************/




}

然后像这样从我的 GameViewController 中调用它

let newPart = BodyPart(rawValue: (model?.attempts)!)

self.hangmanView.add(part: newPart!)

hangmanView 是一个 GameViewTwo

最佳答案

为每个 body 部位创建一个枚举。使它成为一个整数,这样你就可以用错误答案的数量来实例化它。

enum BodyPart: Int {
case head = 0
case leftArm
case rightArm
...
}

制作一个新的 body 部位

let newPart = BodyPart(rawValue: incorrectGuesses - 1)

给你的 View 一些功能...

func add(part: BodyPart){
// first get a drawing path according to that part
let partPath = path(for: part)

// lets add a new layer so we can animate it seperately
let newPartLayer = CAShapeLayer()
newPartLayer.frame = bounds
newPartLayer.path = partPath
// linewidth, linecap you might want to play with

let strokeAnim = CABasicAnimation(keyPath: "strokeEnd")
strokeAnim.fromValue = 0
strokeAnim.toValue = 1
strokeAnim.duration = 0.5 // play with it, see what you like

layer.addSublayer(layer: newPartLayer)
newPartLayer.add(anim: strokeAnim)
}


func path(for: BodyPart) -> CGPath {

// draw your part path, return it as a CGPath
}

然后从您的 Controller 中实例化一个新部件并将其添加到您的 hangmanview 中,它将按照您在绘图代码中绘制的方式绘制图层。 UIBezierPath 有一个 .cgPath 变量可以转换为核心图形路径。

let newPart = BodyPart(rawValue: incorrectGuesses - 1)
hangmanView.add(part: newPart)

当你想要一个新游戏时,只需从 hangmanView 中删除所有子层。 CAShapeLayers 对于简单的小形状非常有用,您可以动画更改路径(keyPath:“路径”)或在任一方向上抚摸路径。会好看的如果保留对所有零件层的引用,您甚至可以独立地移动零件或使用它们做其他有趣的事情。这样,您就有点遵守模型- View - Controller 范例。你让游戏状态远离你的 View ,你的所有 View 都会添加到 body 部位,而你的 Controller 提供了这样做的部位。对于简单的事情来说,这不是什么大不了的事情,但是当您变得更好并且事情变得越来越复杂时,记住这一点是很好的。

快速编辑:您可能想尝试 keyPath: "path",给它一个起始路径(可能是主体路径)和一个结束路径,它看起来就像是从主体中长出来的部分。祝你好运!

*** 编辑后的答案。

我在这里清理了你的代码。我不完全确定为什么你在那里有某些变量或小类私有(private)结构,但没关系,我把它们留在了里面。我移动了一些东西但大部分保持不变,除非很明显你正在绘制一个矩形而不是其他形状。我没有尝试运行它。让我知道进展如何。

enum BodyPart: Int {
case noose = 0
case head
case body
case leftLeg
case rightLeg
case leftArm
case rightArm
case leftEye
case rightEye
case mouth
case unknown
}




class HangmanView: UIView {


var partLayers = [CAShapeLayer]()
private var bodyStart: CGPoint = CGPoint.zero
private var bodyEnd: CGPoint = CGPoint.zero
private var headMiddle: CGPoint = CGPoint.zero

var currentPart: BodyPart?


func clear() {

for i in partLayers {
i.removeFromSuperlayer()
}

partLayers.removeAll()
}

func add(part: BodyPart){

currentPart = part


let newPartLayer = CAShapeLayer()

let partPath = path(forPart: part)
newPartLayer.frame = bounds
newPartLayer.path = partPath.cgPath
newPartLayer.strokeColor = UIColor.black.cgColor
newPartLayer.fillColor = UIColor.clear.cgColor

newPartLayer.lineCap = kCALineCapRound
newPartLayer.lineWidth = part == .rightEye || part == .leftEye ? 1 : 2

let strokeAnim = CABasicAnimation(keyPath: "strokeEnd")
strokeAnim.fromValue = 0
strokeAnim.toValue = 1
strokeAnim.duration = 1
layer.addSublayer(newPartLayer)
newPartLayer.add(strokeAnim, forKey: "path")
partLayers.append(newPartLayer)

}

func path(forPart: BodyPart) -> UIBezierPath {

switch forPart {
case .noose:
return UIBezierPath()


case .head :
let centerX = CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale - (DrawingConstants.gallowHeightWidth / 2))
let centerY = CGFloat(bounds.size.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight + DrawingConstants.gallowTipHeight + ScaleConstants.headRadius)
let center = CGPoint(x: centerX, y: centerY)
headMiddle = center
let path = UIBezierPath(arcCenter: center, radius: ScaleConstants.headRadius, startAngle: CGFloat(0), endAngle: CGFloat(2 * M_PI), clockwise: true)

return path

case .body :
let add = CGFloat(DrawingConstants.gallowBaseHeight + DrawingConstants.gallowTipHeight + 2 * ScaleConstants.headRadius)
let startPointY = CGFloat(bounds.size.height * DrawingConstants.gallowHeight + add)
let startPointX = CGFloat(bounds.size.width * DrawingConstants.gallowAcrossScale - (DrawingConstants.gallowHeightWidth / 2))
let startPoint = CGPoint(x: startPointX, y: startPointY)
let endPoint = CGPoint(x: startPoint.x, y: startPoint.y + ScaleConstants.bodyLength)
bodyStart = startPoint
bodyEnd = endPoint
let path = UIBezierPath()
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case .leftLeg :
let startPoint = CGPoint(x: bodyEnd.x, y: bodyEnd.y)
let endPoint = CGPoint(x: startPoint.x - ScaleConstants.limbLength, y: startPoint.y + ScaleConstants.limbLength)
let path = UIBezierPath()
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case .rightLeg :
let startPoint = CGPoint(x: bodyEnd.x, y: bodyEnd.y)
let endPoint = CGPoint(x: startPoint.x + ScaleConstants.limbLength, y: startPoint.y + ScaleConstants.limbLength)
let path = UIBezierPath()
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case .leftArm :
let startPoint = CGPoint(x: bodyStart.x, y: bodyStart.y + ScaleConstants.handHeightScale * ScaleConstants.bodyLength)
let endPoint = CGPoint(x: startPoint.x - ScaleConstants.limbLength, y: startPoint.y - ScaleConstants.limbLength * ScaleConstants.handHeightScale)
let path = UIBezierPath()
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case .rightArm :
let startPoint = CGPoint(x: bodyStart.x, y: bodyStart.y + ScaleConstants.handHeightScale * ScaleConstants.bodyLength)
let endPoint = CGPoint(x: startPoint.x + ScaleConstants.limbLength, y: startPoint.y - ScaleConstants.limbLength * ScaleConstants.handHeightScale)
let path = UIBezierPath()
path.move(to: startPoint)
path.addLine(to: endPoint)
return path

case .leftEye :
let eyeMiddle = CGPoint(x: headMiddle.x - ScaleConstants.eyeOffset, y: headMiddle.y - ScaleConstants.eyeOffset)

let path = UIBezierPath(arcCenter: eyeMiddle, radius: ScaleConstants.eyeRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true)
path.lineWidth = CGFloat(1)
return path

case .rightEye :
let eyeMiddle = CGPoint(x: headMiddle.x + ScaleConstants.eyeOffset, y: headMiddle.y - ScaleConstants.eyeOffset)

let path = UIBezierPath(arcCenter: eyeMiddle, radius: ScaleConstants.eyeRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true)
path.lineWidth = CGFloat(1)
return path

default:
return UIBezierPath()
}
}




override func draw(_ rect: CGRect) {

guard let context = UIGraphicsGetCurrentContext() else { return }
// get the drawing context and save the ground state
context.saveGState()

// add sky and grass, now they are just rectangles
context.setFillColor(UIColor.cyan.cgColor)
context.fill(sky(rect))

context.setFillColor(UIColor.green.cgColor)
context.fill(grass(rect))

context.setFillColor(UIColor.brown.cgColor)

context.addPath(gallowBase(rect))
context.addPath(gallowHeight(rect))
context.addPath(gallowAcross(rect))
context.addPath(gallowTip(rect))

context.fillPath()
context.restoreGState()

}



func gallowBase(_ rect: CGRect) -> CGPath {

let bottomLeftPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowBaseStartScale), y: CGFloat(rect.height * DrawingConstants.grassHeightScale))
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: bottomLeftPoint.y - DrawingConstants.gallowBaseHeight)
let topRightPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowBaseEndScale), y: topLeftPoint.y)
let bottomRightPoint = CGPoint(x: topRightPoint.x, y: bottomLeftPoint.y)

let path = CGMutablePath()
path.addLines(between: [bottomLeftPoint,topLeftPoint, topRightPoint,bottomRightPoint])
path.closeSubpath()
return path
}

func gallowHeight(_ rect: CGRect) -> CGPath {
let bottomLeftPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowHeightStart), y: CGFloat(rect.height * DrawingConstants.grassHeightScale - DrawingConstants.gallowBaseHeight))
let bottomRightPoint = CGPoint(x: bottomLeftPoint.x + DrawingConstants.gallowHeightWidth, y: bottomLeftPoint.y)
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: rect.height * DrawingConstants.gallowHeight)
let topRightPoint = CGPoint(x: bottomRightPoint.x, y: topLeftPoint.y)

let path = CGMutablePath()
path.addLines(between: [bottomLeftPoint,topLeftPoint, topRightPoint,bottomRightPoint])
path.closeSubpath()
return path
}

func gallowAcross(_ rect: CGRect) -> CGPath {
let bottomLeftPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowHeightStart) + DrawingConstants.gallowHeightWidth, y: CGFloat(rect.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight))


let bottomRightPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowAcrossScale), y: bottomLeftPoint.y)
let topLeftPoint = CGPoint(x: bottomLeftPoint.x, y: CGFloat(rect.height * DrawingConstants.gallowHeight))
let topRightPoint = CGPoint(x: CGFloat(bottomRightPoint.x), y: topLeftPoint.y)

let path = CGMutablePath()
path.addLines(between: [bottomLeftPoint,topLeftPoint, topRightPoint,bottomRightPoint])
path.closeSubpath()
return path
}

func gallowTip(_ rect: CGRect) -> CGPath {
let topLeftPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowAcrossScale - DrawingConstants.gallowHeightWidth), y: CGFloat(rect.height * DrawingConstants.gallowHeight + DrawingConstants.gallowBaseHeight))
let topRightPoint = CGPoint(x: CGFloat(rect.width * DrawingConstants.gallowAcrossScale), y: topLeftPoint.y)
let bottomLeftPoint = CGPoint(x: topLeftPoint.x, y: topLeftPoint.y + DrawingConstants.gallowTipHeight)
let bottomRightPoint = CGPoint(x: topRightPoint.x, y: bottomLeftPoint.y)

let path = CGMutablePath()
path.addLines(between: [bottomLeftPoint,topLeftPoint, topRightPoint,bottomRightPoint])
path.closeSubpath()
return path
}



func grass(_ rect: CGRect) -> CGRect {


let grassRect = CGRect(x: 0, y: rect.height * DrawingConstants.grassHeightScale, width: rect.width, height: (1 - DrawingConstants.grassHeightScale) * rect.height)

return grassRect
}

func sky(_ rect: CGRect) -> CGRect {

let skyRect = CGRect(x: 0, y: 0, width: rect.width, height: DrawingConstants.grassHeightScale * rect.height)

return skyRect

}


func calculateMidPoint(point1: CGPoint, point2: CGPoint) -> CGPoint {
return CGPoint(x: (point1.x + point2.x) / 2, y: (point1.y + point2.y) / 2)

}


struct DrawingConstants {
static let gallowBaseStartScale: CGFloat = 0.15
static let gallowBaseEndScale: CGFloat = 0.85
static let gallowBaseHeight: CGFloat = 10
static let gallowHeight: CGFloat = 0.05 //static let gallowHeight: CGFloat = 0.15
static let gallowHeightStart: CGFloat = 0.175
static let gallowHeightWidth: CGFloat = 10
static let gallowAcrossScale: CGFloat = 0.5
static let gallowTipHeight: CGFloat = 17.5
static let headRadius: CGFloat = 16
static let bodyLength: CGFloat = 25
static let bodyHeight: CGFloat = 25
static let legLength: CGFloat = 50
static let grassHeightScale: CGFloat = 0.68
static let armBack: CGFloat = 5
}

struct ScaleConstants {
static let bodyLength: CGFloat = 50
static let limbLength: CGFloat = 25
static let handHeightScale: CGFloat = 0.4
static let headRadius: CGFloat = 20
static let eyeRadius = 0.15 * headRadius
static let eyeOffset = 0.3 * headRadius
static let mouthOffSet = 0.3 * headRadius
static let mouthRadius = 0.25 * headRadius
}
}

关于带有 Core Graphics 的 iOS 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40924633/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com