简体   繁体   中英

How to correctly update a CGContext with a function call?

I'm making a little shooter game in which a little ship explores a 8x8 level of rooms filled with enemies and such. I'm currently trying to implement a map that shows the player where they've already gone. My initial implementation is simple - I've made a custom UIView, attached it to my Storyboard, and want to simply draw any new room visited on the map. I elected to do this with a CGContext, and have my first attempt shown below.

With this code, the first updateMap call works perfectly - the rectangle is drawn in the correct color and position on the player map. However, any subsequent calls don't seem to draw anything, despite the CGRect updating correctly. If I uncomment the the PopContext (or remove the PushContext), it will trigger the "Context not found" throw. While the code in its shown state below won't print "Context not found", it won't update the map either.

Admittedly, my understanding of CGContext is pretty lackluster, so I think I'm just making a conceptual error here. That being said, what exactly am I messing up?

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)
}

}

You should not call draw() method directly... You ca call setNeedsDisplay() or layoutIfNeeded()

As per Apple docs

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.

So your code becomes

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()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM