sourcecode

Numeric operator overloading in Swift

onedayitwillmake No Comments

Sometimes when developing in Swift if you’re trying to do seemingly simple things like divide 2 numbers:

let interval:Double = 1.0/fps;

You’ll get errors like these:

binary operator '*' cannot be applied to operands of type 'CGFloat' and 'Double'
binary operator '*' cannot be applied to operands of type 'Int' and 'CGFloat'
cannot convert value of type 'Float' to expected argument type 'Double'
binary operator '*' cannot be applied to operands of type 'CGFloat' and 'Int8'

This is because Swift is more strict about how it treats numeric types, and you have to manually cast them to the same type in order for those operations to work.

However cause we can write our own operator in Swift, we can make it so that when it encounters 2 types, it will check to see if we have a matching operator and use that instead.

So as I’ve encountered them, I’ve been appending to a my little NumericOperatorOverloadingExtensions.swift file:

import Foundation

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// ADDITION ////////////////////////////////////////////////////////////////
public func +(a: Float, scalar: Int)  -> Float  { return a + Float(scalar); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////// MULTIPLICATION  //////////////////////////////////////////////////////////////
// Int *
public func *(a: Int, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int)   -> Double   { return Double(a) * scalar; }

// Int8 *
public func *(a: Int8, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int8, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int8, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int8)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int8)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int8)   -> Double   { return Double(a) * scalar; }

// Int32 *
public func *(a: Int32, scalar: CGFloat)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(a: Int32, scalar: Float)    -> Float    { return Float(a) * scalar; }
public func *(a: Int32, scalar: Double)   -> Double   { return Double(a) * scalar; }
public func *(scalar: CGFloat, a: Int32)  -> CGFloat  { return CGFloat(a) * scalar; }
public func *(scalar: Float, a: Int32)    -> Float    { return Float(a) * scalar; }
public func *(scalar: Double, a: Int32)   -> Double   { return Double(a) * scalar; }

// Float *
public func *(a: Float, scalar: Double)  -> Float  { return a * Float(scalar); }
public func *(a: Float, scalar: Double)  -> CGFloat  { return CGFloat(a * Float(scalar)); }
public func *(a: Float, scalar: Double)  -> Double  { return Double(a) * scalar; }

// CGFLOAT  *
public func *(a: CGFloat, scalar: Double)  -> CGFloat  { return a * CGFloat(scalar); }
public func *(a: CGFloat, scalar: Double)  -> Float  { return Float(a) * Float(scalar); }
public func *(a: CGFloat, scalar: Double)  -> Double  { return Double(a) * scalar; }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// DIVISION ////////////////////////////////////////////////////////////////
// Double /
public func /(a: Double, b: Int)  -> Double  { return a / Double(b); }
public func /(a: Double, b: Float)  -> Double  { return a / Double(b); }
public func /(a: Double, b: Int)  -> Int  { return Int(a) / b; }
public func /(a: Int, b: Double)  -> Double  { return Double(a) / b; }
public func /(a: Int, b: Double)  -> Int  { return Int(Double(a) / b); }

// Float /
public func /(a: Float, b: Int)  -> Float  { return a / Float(b); }
public func /(a: Float, b: Int)  -> Int  { return Int(a) / b; }
public func /(a: Int, b: Float)  -> Float  { return Float(a) / b; }
public func /(a: Int, b: Float)  -> Int  { return Int(Float(a) / b); }
public func /(a: Float, scalar: Double)  -> Float  { return a / Float(scalar); }

[iOS] Creating reusable UIViews with Storyboard

onedayitwillmake 6 comments

I’m a big fan of using Storyboards to act as the glue for your application.
It just makes everything much easier, and makes your program feel like a cohesive application instead of a random assortment of UIViewControllers

However one problem is that, Storyboards don’t lend themselves to having reusable views.
Which I find kind of odd, because it seems common that you would have a view that needs to exist in multiple screens for myriad reasons in a lot of applications.

Wellp, it’s actually not that difficult to do – although definitely falls in the ‘tricky’ category.

Calculating the gravity of the gravitational force or 0.00000000000667

onedayitwillmake No Comments

Gravity is by far the best force in the universe. Despite being the weakest of the “main” four (strong nuclear force, weak nuclear force, electromagnetism, gravity). It is the one that dominates given enough time and distances. All this even though it falls of inversely to the square of the distance, meaning, if you double the separation between the two objects you quarter the force, or if you cut the separation in half you quadruple the force of attraction.

It’s also one of my favorite things when creating visualizations, because things move so beautifully when you simply let gravity take over.

So I thought I would give it it’s own tiny blog post, in honor of its value 0.00000000000667

    // Compute the net force acting between the invoking body a and b, and
    // add to the net force acting on the invoking Body
    public void addForce(Body b) {
        Body a = this;
        double G = 0.00000000000667;
        double EPS = 0.0001;      // softening parameter
        double dx = b.rx - a.rx;
        double dy = b.ry - a.ry;
        double dist = Math.sqrt(dx*dx + dy*dy);
        double F = (G * a.mass * b.mass) / (dist*dist + EPS*EPS);
        a.fx += F * dx / dist;
        a.fy += F * dy / dist;
    }

BulletML running on iOS

onedayitwillmake No Comments

BulletML is an XML like markup language created to describe bullet barrages seen in shooters. It allows you to describe complex bullet patterns in simple XML files, then parse them and let it run. Very easy to create nice boss patterns

In this video is my first working attempt at getting it to run on the iPhone. Currently bullets can not spawn other bullets, but once I get that i’ll share the source

It runs at 60FPS, but the screen recorder drops some frames.

Project:
https://github.com/onedayitwillmake/BulletHaven

I’ve managed to get BulletML and cocos2d to work together.
Most of the bulletml files work, except for when bullets need to spawn other bullets.

Does anyone have any experience with this, perhaps it’s a callback function that needs to be inside of bullet?