Skip to content

Instantly share code, notes, and snippets.

@C4Code
Created December 9, 2014 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save C4Code/5ba9f368418bd91d3284 to your computer and use it in GitHub Desktop.
Save C4Code/5ba9f368418bd91d3284 to your computer and use it in GitHub Desktop.
Rough Isometric Line code, Swift C4
class Rule {
var a: IsometricPoint
var b: IsometricPoint
lazy var targets = [[IsometricPoint]]()
init(_ a: IsometricPoint, _ b: IsometricPoint) {
self.a = a
self.b = b
}
func addTarget(a: IsometricPoint, _ b: IsometricPoint) {
targets.append([a,b])
}
}
class IsometricLine {
var dx: Double = 0.0
var origin: C4Vector = C4Vector(0,0)
var rules = [String : Rule]()
internal var points: [IsometricPoint] {
didSet {
sort()
updatePath()
}
}
var a: IsometricPoint {
get {
return points[0]
}
}
var b: IsometricPoint {
get {
return points[1]
}
}
var line: C4Line
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
init(filePath: String, dx: Double, origin: C4Vector) {
self.dx = dx
self.origin = origin
let nsd = NSDictionary(contentsOfFile: filePath)
let lineRules = nsd as [String : [String]]
for lineID in lineRules.keys {
let ruleCoordinates = pointsFromLineID(lineID, dx, origin)
var rule = Rule(ruleCoordinates.0,ruleCoordinates.1)
if let targets = lineRules[lineID] {
for index in 0..<targets.count {
let targetPoints = pointsFromLineID(targets[index], dx, origin)
rule.addTarget(targetPoints.0,targetPoints.1)
}
//TODO: figure out how you're not reading the rules properly
rules[lineID] = rule
}
}
let index = random(below: rules.count)
let arr = [String](rules.keys)
let randomKey = arr[index]
let randomStartRule = rules[randomKey]!
points = [IsometricPoint]()
points.append(randomStartRule.a)
points.append(randomStartRule.b)
line = C4Line([points[0].screenCoordinate, points[1].screenCoordinate])
}
func updatePath() {
line.points = [points[0].screenCoordinate, points[1].screenCoordinate]
}
var id: String {
get {
return "\(Int(a.x)),\(Int(a.y)).\(Int(b.x)),\(Int(b.y))"
}
}
internal func sort() {
let tmpa = a
let tmpb = b
if(tmpa.y > tmpb.y) {
points[0] = tmpb
points[1] = tmpa
} else if tmpa.y == tmpb.y {
if tmpa.x > tmpb.x {
points[0] = tmpb
points[1] = tmpa
}
}
}
func run() {
if let rule = rules[self.id] {
var r = 0
if rule.targets.count > 1 {
r = random() % rule.targets.count
}
self.points = rule.targets[r]
}
delay(0.5) {
self.run()
}
}
}
func pointsFromLineID(lineID : String, dx: Double, origin: C4Vector) -> (IsometricPoint, IsometricPoint) {
let pointDescriptions = lineID.componentsSeparatedByString(".")
let pointA = pointDescriptions[0]
let pointAComponents = pointA.componentsSeparatedByString(",")
let pointB = pointDescriptions[1]
let pointBComponents = pointB.componentsSeparatedByString(",")
let x1 = pointAComponents[0].toInt()
let y1 = pointAComponents[1].toInt()
let x2 = pointBComponents[0].toInt()
let y2 = pointBComponents[1].toInt()
let a = IsometricPoint(x1!,y1!,dx,origin)
let b = IsometricPoint(x2!,y2!,dx,origin)
return (a,b)
}
class ViewController: UIViewController {
var isoLines = [IsometricLine]()
var t: NSTimer = NSTimer()
var dl = DynamicLine()
var dl2 = DynamicLine()
var visibleLine = C4Line([C4Point(0,0),C4Point(1,1)])
var dx = 16.0
var wMod = 2.75/20.0
var origin = C4Vector(0,0)
var l = [String: C4Line]()
override func viewDidLoad() {
super.viewDidLoad()
origin.x = Double(view.center.x)
origin.y = 10.0
loadDynamically()
}
func createLogoLines(fileName: String) {
let nsd = NSArray(contentsOfFile: docsDir()+"/\(fileName).plist")
let arr = nsd as [String]
for lineID in arr {
let points = pointsFromLineID(lineID, dx, origin)
let line = C4Line([points.0.screenCoordinate,points.1.screenCoordinate])
line.strokeColor = .blueColor()
line.lineWidth = dx * wMod
l[lineID] = line;
view.add(line)
}
}
func loadDynamically() {
let fileManager = NSFileManager.defaultManager()
if let enumerator = fileManager.enumeratorAtPath(docsDir()) {
for url in enumerator.allObjects {
let fileName : String = (url as String).componentsSeparatedByString(".")[0]
if fileName.hasPrefix("lines") {
createLogoLines(fileName)
}
if fileName.hasPrefix("rules") {
createIsoline(fileName)
}
}
}
}
func createIsoline(fileName: String) {
let isoline = IsometricLine(filePath: docsDir()+"/\(fileName).plist", dx: dx, origin: origin)
isoLines.append(isoline)
self.view.add(isoline.line)
isoline.run()
isoline.line.strokeColor = .blueColor()
isoline.line.lineWidth = dx * wMod
}
func load() {
createLogoLines("lines")
createLogoLines("lines3")
}
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func docsDir()-> String {
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, .UserDomainMask, true)
return paths[0] as String
}
}
struct IsometricPoint {
var x: Int = 0
var y: Int = 0
var dx: Double = 1.0
var dy: Double = 1.0
var offset: C4Vector = C4Vector(1,1)
init(_ x: Int, _ y: Int, _ dx: Double, _ off: C4Vector) {
self.x = x
self.y = y
self.dx = dx
self.dy = dx / 1.9
self.offset = off
}
var screenCoordinate: C4Point {
get {
let s = sin(45.0 * M_PI / 180.0)
let c = cos(45.0 * M_PI / 180.0)
var point = C4Point()
point.x = c * Double(x) - s * Double(y) //normalized translate
point.x *= dx //scaled
point.y = s * Double(x) + c * Double(y) //normalize translate
point.y *= dy //scaled
return point + offset //offset
}
}
}
struct DynamicLine {
internal var points: [IsometricPoint]
var a: IsometricPoint {
get {
return points[0]
} set(val) {
points[0] = val
sort()
}
}
var b: IsometricPoint {
get {
return points[1]
} set(val) {
points[1] = val
sort()
}
}
var id: String {
get {
return "\(Int(a.x)),\(Int(a.y)).\(Int(b.x)),\(Int(b.y))"
}
}
init(_ a: IsometricPoint, _ b:IsometricPoint) {
points = [IsometricPoint]()
points.append(a)
points.append(b)
sort()
}
init() {
self.init(IsometricPoint(0,0,100,C4Vector(x:160.0,y:Double(20))), IsometricPoint(0,1,100,C4Vector(x:160.0,y:Double(20))))
}
mutating internal func sort() {
let tmpa = a
let tmpb = b
if(tmpa.y > tmpb.y) {
points[0] = tmpb
points[1] = tmpa
} else if tmpa.y == tmpb.y {
if tmpa.x > tmpb.x {
points[0] = tmpb
points[1] = tmpa
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment