Pete Barber from C#, C++, Windows & other ramblingsNot an in depth post today. For a small iOS Swift/SpriteKit game I'm writing for fun I wanted a very basic grass sprite that could be scrolled; to create a parallax effect. This amounts to a 800x400 bitmap which contains sequential isosceles triangles of 40 pixels with random heights (of up to 400 pixels) and coloured using a lawn green colour.
Initially I was creating an SKShapeNode and creating the triangles above but when scrolling the redrawing of these hurt performance, especially when running on the iOS Simulator hence the desire to use a sprite.
I had a go at creating these with Photoshop. Whilst switching to a sprite improved performance the look of the triangles drawn by hand wasn't as good as the randomly generated ones. Therefore I thought I'd generate the sprite.
It wasn't really practical to do this on iOS as the file was needed in Xcode so I thought I'd try experimenting with a command line OS X (Cocoa) program in Swift. A GUI would possibly be nice to preview the results (and re-generate if needed) and to select the save-to file location but this solution sufficed.
I'd not done any non-iOS Swift development and never generated PNGs so various amounts of Googling and StackOverflow-ing was needed. Whilst the results of these searches were very helpful I didn't come across anything showing a complete program to create a bitmap, draw into it and then save so the finished program is presented below. It's also available as a gist.
1: import Cocoa
3: private func saveAsPNGWithName(fileName: String, bitMap: NSBitmapImageRep) -> Bool
5: let props: [NSObject:AnyObject] = [:]
6: let imageData = bitMap.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: props)
8: return imageData!.writeToFile(fileName, atomically: false)
11: private func drawGrassIntoBitmap(bitmap: NSBitmapImageRep)
13: var ctx = NSGraphicsContext(bitmapImageRep: bitmap)
17: NSColor(red: 124 / 255, green: 252 / 255, blue: 0, alpha: 1.0).set()
19: let path = NSBezierPath()
21: path.moveToPoint(NSPoint(x: 0, y: 0))
23: for i in stride(from: 0, through: SIZE.width, by: 40)
25: path.lineToPoint(NSPoint(x: CGFloat(i + 20), y: CGFloat(arc4random_uniform(400))))
26: path.lineToPoint(NSPoint(x: i + 40, y: 0))
34: let SIZE = CGSize(width: 800, height: 400)
36: if Process.arguments.count != 2
38: println("usage: grass <file>")
42: let grass = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(SIZE.width), pixelsHigh: Int(SIZE.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)
45: saveAsPNGWithName(Process.arguments, grass!)