Creating random number in SpriteKit - swift

I'm trying to create a game in which a projectile is launched at a random angle.
To do this I need to be able to generate two random Int's. I looked up some tutorials and came up with this:
var random = CGFloat(Int(arc4random()) % 1500)
var random2 = CGFloat(Int(arc4random()) % -300)
self.addChild(bullet)
bullet.physicsBody!.velocity = CGVectorMake((random2), (random))
It worked for a while but now it just crashes.
Any help would be appreciated.

What I find I use the most is arc4random_uniform(upperBound) which returns a random Int ranging from zero to upperBound -1.
let random = arc4random_uniform(1500)
let random2 = arc4random_uniform(300) * -1
//pick a number between 1 and 10
let pick = arc4random_uniform(10)+1
The lowdown on the arc4 functions: arc4random man page
GameplayKit has a nice class wrapping the arc4 functions: GameplayKit Randomness
and a handy reference: Random Hipster

I dont understand very well your issue but I think it could be useful:
func getRandomPointFromCircle(radius:Float, center:CGPoint) -> CGPoint {
let randomAngle = Float(arc4random())/Float(UInt32.max-1) * Float(M_PI) * 2.0
// polar => cartesian
let x = radius * cosf(theta)
let y = radius * sinf(theta)
return CGPointMake(CGFloat(x)+center.x,CGFloat(y)+center.y)
}

Related

Finding area of n-sided polygon with array of decimal latitude and longitude

I am trying to find the area of a polygon generated by a users path. The path gives back an array of lat/lon. The path is always self closing. I have tried multiple methods that I found online. Below is what I currently have, I can't make sense of the outputted data. The area * 6378137.0 * 6378137.0 is meant to give me back an area in m^2, but the results are massive numbers.
My ideal solution would be to find a way to (with an assumed % of error) map my lat/lon to xy coordinates and apply the shoelace theorem. I understand that this is pretty hard to do accurately because of the curvature of the earth.
Building from the last paragraph, maybe the best way to map to x,y coordinates would be some sort of projection method. I have not gone too far down that path yet.
What would be the best method to try in order to solve this problem? If someone could set me on the right path or decipher the code I have already tried I would greatly appreciate it (code is done in swift playground). Thanks!
func deg2rad(_ number: Double) -> Double {
return number * .pi / 180
}
func areaCalc(lat: [Double]?, lon: [Double]?){
guard let lat = lat,
let lon = lon
else { return }
var area: Double = 0.0
if(lat.count > 2){
for i in stride(from: 0, to: lat.count - 1, by: 1) {
let p1lon = lon[i]
let p1lat = lat[i]
let p2lon = lon[i+1]
let p2lat = lat[i+1]
area = area + (deg2rad(p2lon - p1lon)) * (2 + sin(deg2rad(p1lat))) + (sin(deg2rad(p2lat)))
}
area = area * 6378137.0 * 6378137.0
area = abs(area / 2)
}
}

2D Motion vectors - calculate location of object at a given time

I am having problems understanding 2D motion vectors when moving certain objects at a given time. My knowledge of linear algebra is limited and I really don't know the exact search terms to look for, so I wanted to know whether anybody could help me or at least hint me in the right direction.
My problem looks like this:
I have two points, a startPoint, and an endPoint in space. They have each a specific location, denoted as (x_1, x_2) and (y_1, y_2) respectively. Both of these points have a time attached to it, named t_startPoint or t_endPoint, respectively. I now want to find out, for a given currentTime (= basically any point in time that is in between t_startPoint and t_endPoint), where exactly would a new point N be positioned on the connection line between those two points. I know the description is not trivial and that’s why I also added an image describing what I would like to do:
So far, this is what I have as my algorithm:
func update(_ time: Int64) {
let t_startPoint: Int64 = 1
let position_startPoint: = (1.0, 1.0)
let t_endPoint: Int64 = 5
let position_endPoint: Vector = (4.0, 5.0)
let currentTime = 3
let duration = t_endPoint - t_startPoint
let x = position_startPoint.x + ((position_endPoint.x - position_startPoint.x) / Float(duration)) * (Float(currentTime - t_startPoint))
let y = position_startPoint.y + ((position_endPoint.y - position_startPoint.y) / Float(duration)) * (Float(currentTime - t_startPoint))
//
However, no matter what I do, my objects keep overshooting, erratically moving back and forth, and I don't know where to start. Any help would be greatly appreciated!
For constant velocity moving there is relation:
(t-t1) / (t2-t1) = (x-x1) / (x2-x1)
x = x1 + (x2-t1) * (t-t1) / (t2-t1)
so your expresiion looks right. Check:
1 + (4-1) * (3-1) / (5-1) = 1 + 3 * 2 / 4 = 2.5 - exact middle, OK

Cross product fuction in swift ios

In which swift library i will get cross product funtion
like cross(normalize(vector1),normalize(vector2))
i want angle direction between three scnnode joint with line
let node0 :SCNNode = self.nodes[1]
let node1 :SCNNode = self.nodes[2]
let node2 :SCNNode = self.nodes[3]
let vector1 = float3((node0.position.x - node1.position.x), (node0.position.y - node1.position.y), (node0.position.z - node1.position.z))
let vector2 = float3((node2.position.x - node1.position.x), (node2.position.y - node1.position.y), (node2.position.z - node1.position.z))
let dotProduct = dot(normalize(vector1), normalize(vector2))
let theta = acos(dotProduct)
This is my sample code and theta is and radian angle between those point and is perfect but how to get angle direction is my question
You can import simd library so that you will get cross product function
import simd
let crossp = cross(normalize(vector1), normalize(vector2))
let dotpOfcross = dot(crossp,float3.init(node0.position))
I think this is what you want as per your question please check and let here know.

Calculating worldFront like in SCNARView

In SCNARView I can access a property of camera node called worldFront, which represents camera rotation. I would like to calculate similar vector from CoreMotion values not using SCNARView, just data from CoreMotion. So that I can get a vector that would be equal to worldFront in SCNARView if camera was facing the same direction. Can someone explain me how to calculate such a value?
The attitude property probably could help
func rollCam(motion: CMDeviceMotion) {
let attitude = motion.attitude
let roll = Float(attitude.roll-M_PI/2)
let yaw = Float(attitude.yaw)
let pitch = Float(attitude.pitch)
camNode.eulerAngles = SCNVector3Make(roll, -yaw, pitch)
}
With this piece of code, quite long time ago, I experimented a bit with CoreMotion. I was trying to first detect human walking and then (with the startDeviceMotionUpdates data) move and roll the camera near to an "anchored" SCNBox. Later on ARKit solved my need with the ARAnchor class
What feature are you looking after?
I have found the answer:
override var cameraFrontVector: double3 {
guard let quaternion = motionService.deviceMotion?.attitude.quaternion else { return .zero }
let x = 2 * -(quaternion.x * quaternion.z + quaternion.w * quaternion.y)
let z = 2 * (quaternion.y * quaternion.z - quaternion.w * quaternion.x)
let y = 2 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y) - 1
return double3(x: x, y: y, z: z)
}
This gives me values like worldFront in SCNNode.

How to get a boss character to fire at all directions at once

I'm new to SpriteKit game development. I'm trying give a boss character the ability to cast fireballs in multiple directions (16 fireballs all at once, 360 degree/16 = 22.5 degree apart).
I know how to get him to fire at a certain position by providing the player's current position, but how to get him to fire at 16 different angles regardless of player's position?
Thanks for any help in advance.
First, set up a loop over the angles
let numAngles = 16
var angle:CGFloat = 0
var angleIncr = CGFloat(2 * M_PI) / CGFloat(numAngles)
let strength:CGFloat = 50
for _ in 0..<numAngles {
...
angle += angleIncr
}
In the loop, convert the angle to the corresponding vector components and then create a vector
let dx = strength * cos (angle)
let dy = strength * sin (angle)
let vector = CGVectorMake (dx, dy)
and create a new fireball and apply an impulse to its physics body
let fireball = ...
fireball.position = player.position
fireball.zRotation = angle
// Add a physics body here
fireball.physicsBody?.appyImpulse (vector)
I'm not sure what code you have in place. for shooting. but ill give this a shot. angles in spritekit are in radians and a there are 2*pi radians in a circle. so you just need to do something like this
let fireballs = 16
let threeSixty = CGFloat(M_PI*2)
for i in 1...fireballs {
let angle = (CGFloat(i) / CGFloat(fireballs)) * threeSixty
// do something useful with your angle
}