Not an in depth post today. For 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
2:
3: private func saveAsPNGWithName(fileName: String, bitMap: NSBitmapImageRep) -> Bool
4: {
5: let props: [NSObject:AnyObject] = [:]
6: let imageData = bitMap.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: props)
7:
8: let myPath = NSFileManager.defaultManager().currentDirectoryPath
9:
10: return imageData!.writeToFile(fileName, atomically: false)
11: }
12:
13: private func drawGrassIntoBitmap(bitmap: NSBitmapImageRep)
14: {
15: var ctx = NSGraphicsContext(bitmapImageRep: bitmap)
16:
17: NSGraphicsContext.setCurrentContext(ctx)
18:
19: NSColor(red: 124 / 255, green: 252 / 255, blue: 0, alpha: 1.0).set()
20:
21: let path = NSBezierPath()
22:
23: path.moveToPoint(NSPoint(x: 0, y: 0))
24:
25: for i in stride(from: 0, through: SIZE.width, by: 40)
26: {
27: path.lineToPoint(NSPoint(x: CGFloat(i + 20), y: CGFloat(arc4random_uniform(400))))
28: path.lineToPoint(NSPoint(x: i + 40, y: 0))
29: }
30:
31: path.stroke()
32: path.fill()
33:
34: }
35:
36: let SIZE = CGSize(width: 800, height: 400)
37:
38: println("\(Process.arguments[0])")
39:
40: if Process.arguments.count != 2
41: {
42: println("usage: grass <file>")
43: exit(1)
44: }
45:
46: 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)
47:
48: drawGrassIntoBitmap(grass!)
49: saveAsPNGWithName(Process.arguments[1], grass!)
50: