如何使用函数调用正确更新 CGContext?
How to correctly update a CGContext with a function call?
我正在制作一个小型射击游戏,其中一艘小船探索一个 8x8 级的房间,房间里满是敌人等等。我目前正在尝试实现一张地图,向玩家显示他们已经去过的地方。我的初始实现很简单——我制作了一个自定义 UIView,将其附加到我的 Storyboard,并想简单地在地图上绘制任何访问过的新房间。我选择使用 CGContext 执行此操作,并在下面显示了我的第一次尝试。
使用此代码,第一个 updateMap 调用可以完美运行 - 矩形在玩家地图上以正确的颜色和位置绘制。但是,尽管 CGRect 更新正确,但任何后续调用似乎都不会绘制任何内容。如果我取消注释 PopContext(或删除 PushContext),它将触发“找不到上下文”抛出。虽然下面所示状态的代码不会打印“找不到上下文”,但它也不会更新地图。
诚然,我对 CGContext 的理解相当乏善可陈,所以我认为我在这里犯了一个概念上的错误。话虽这么说,我到底搞砸了什么?
class MapView: UIView {
var x: Int!
var y: Int!
var drect: CGRect!
override func draw( _ frame: CGRect) {
super.draw(frame)
if let context: CGContext = UIGraphicsGetCurrentContext(){
//UIGraphicsPopContext()
context.setFillColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.0); //this is the transparent color
context.setStrokeColor(red: 0.0, green: 0.0, blue: 100.0, alpha: 1.0);
context.fill(drect);
context.stroke(drect); //this will draw the border
context.addRect(drect)
UIGraphicsPushContext(context)
} else {
print("Context not found")
return
}
}
public func updateMap(scene: GameScene){
x = scene.current_xcoords
y = scene.current_ycoords
let w = self.frame.width
let h = self.frame.height
drect = CGRect(x: (w/50) + CGFloat(x)*w/8, y: (h/100) + CGFloat(y)*h/8, width: (h / 11), height: (h / 11))
draw(self.frame)
}
}
你不应该直接调用 draw()
方法......你不能调用 setNeedsDisplay()
或 layoutIfNeeded()
This method is called when a view is first displayed or when an event
occurs that invalidates a visible part of the view. You should never
call this method directly yourself. To invalidate part of your view,
and thus cause that portion to be redrawn, call the setNeedsDisplay()
or setNeedsDisplay(_:) method instead.
所以你的代码变成了
public func updateMap(scene: GameScene){
x = scene.current_xcoords
y = scene.current_ycoords
let w = self.frame.width
let h = self.frame.height
drect = CGRect(x: (w/50) + CGFloat(x)*w/8, y: (h/100) + CGFloat(y)*h/8, width: (h / 11), height: (h / 11))
setNeedsDisplay()
}
我正在制作一个小型射击游戏,其中一艘小船探索一个 8x8 级的房间,房间里满是敌人等等。我目前正在尝试实现一张地图,向玩家显示他们已经去过的地方。我的初始实现很简单——我制作了一个自定义 UIView,将其附加到我的 Storyboard,并想简单地在地图上绘制任何访问过的新房间。我选择使用 CGContext 执行此操作,并在下面显示了我的第一次尝试。
使用此代码,第一个 updateMap 调用可以完美运行 - 矩形在玩家地图上以正确的颜色和位置绘制。但是,尽管 CGRect 更新正确,但任何后续调用似乎都不会绘制任何内容。如果我取消注释 PopContext(或删除 PushContext),它将触发“找不到上下文”抛出。虽然下面所示状态的代码不会打印“找不到上下文”,但它也不会更新地图。
诚然,我对 CGContext 的理解相当乏善可陈,所以我认为我在这里犯了一个概念上的错误。话虽这么说,我到底搞砸了什么?
class MapView: UIView {
var x: Int!
var y: Int!
var drect: CGRect!
override func draw( _ frame: CGRect) {
super.draw(frame)
if let context: CGContext = UIGraphicsGetCurrentContext(){
//UIGraphicsPopContext()
context.setFillColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.0); //this is the transparent color
context.setStrokeColor(red: 0.0, green: 0.0, blue: 100.0, alpha: 1.0);
context.fill(drect);
context.stroke(drect); //this will draw the border
context.addRect(drect)
UIGraphicsPushContext(context)
} else {
print("Context not found")
return
}
}
public func updateMap(scene: GameScene){
x = scene.current_xcoords
y = scene.current_ycoords
let w = self.frame.width
let h = self.frame.height
drect = CGRect(x: (w/50) + CGFloat(x)*w/8, y: (h/100) + CGFloat(y)*h/8, width: (h / 11), height: (h / 11))
draw(self.frame)
}
}
你不应该直接调用 draw()
方法......你不能调用 setNeedsDisplay()
或 layoutIfNeeded()
This method is called when a view is first displayed or when an event occurs that invalidates a visible part of the view. You should never call this method directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay() or setNeedsDisplay(_:) method instead.
所以你的代码变成了
public func updateMap(scene: GameScene){
x = scene.current_xcoords
y = scene.current_ycoords
let w = self.frame.width
let h = self.frame.height
drect = CGRect(x: (w/50) + CGFloat(x)*w/8, y: (h/100) + CGFloat(y)*h/8, width: (h / 11), height: (h / 11))
setNeedsDisplay()
}