This question already has answers here:
Crash when casting the result of arc4random() to Int
(7 answers)
Closed 7 years ago.
I have a problem with one of my function: my application run perfectly on iPhone 5s, 6, etc, but on a iPhone 5 I have a problem with my code. When my function is called, I always have this problem:
switch choixDeCote {
case 1 : //Haut
let MinValue = self.size.width / 8
let MaxValue = self.size.width - 200
SpawnX = UInt32(MaxValue - MinValue)
SpawnX = arc4random_uniform(SpawnX)
SpawnY = UInt32(self.size.height)
directionX = Int(arc4random()) % Int(self.frame.size.width)
print(directionX)
directionY = 0
action = SKAction.moveTo(CGPoint(x: CGFloat(directionX),y: CGFloat(directionY)),duration: 4)
break
And Xcode says that directionX = Int(arc4random()) % Int(self.frame.size.width) has a problem, but I don't know which one.
arc4random() returns a UInt32. On a 32-bit machine like the iPhone 5, this can overflow an Int.
I would suggest instead:
directionX = Int(Int32(bitPattern: arc4random_uniform(UInt32(self.frame.size.width))))
the Int32(bitPattern:) is only a precaution and isn't really necessary since the self.frame.size.width is much smaller than MAXINT32 so the random number generated won't overflow an Int. You can just do:
directionX = Int(arc4random_uniform(UInt32(self.frame.size.width)))
Related
Below is my code so far using for loops, and this is what it looks like right now. As you can see it is very condensed
for i in 0...12{
for j in 0...16{
let block = SKSpriteNode(texture: blockImage, size: blockSize)
block.position.x = block.frame.width/2 * CGFloat(j)+1
block.position.y = frame.height - block.frame.height/2 * CGFloat(i)+1
block.zPosition = 1
addChild(block)
}
}
However, I am only trying to have 2 rows of blocks on the top and 1 row of blocks on the bottom. The screen should have a height 12 blocks and a width of 15 blocks.
Is there a way I can create a grid that is 15x12 with a cell size of 64x64 using 2d arrays? Because eventually, I want to add blocks to random cell locations in the grid(besides the fixed top and bottom rows)
I am looking for tutorials on how to do this, but I am finding people that use other open source options that are not included in swift. Please drop any tips or advice you have for me to tackle this I am very new to SpriteKit and Swift, thank you! (lmk if you need more clarification as well)
update:
I got it to look like this now, but I don't know how to remove the rest of the blocks that arent in the top and bottom rows. How would i get the location of each block?
for i in 0...12{
for j in 0...16{
let block = SKSpriteNode(texture: blockImage, size: blockSize)
block.position.x = block.frame.width/2 + CGFloat((64*j))
block.position.y = frame.height - block.frame.height/2 - CGFloat((64*i))
block.zPosition = 1
addChild(block)
}
}
I don't really code for SpriteKit but maybe can offer some tips based on the logic I see.
One way could be to add some logic in the for loop to check if you are currently iterating the first 2 rows or the last row and only in these cases, add the row of blocks.
let rows = 12
let columns = 16
let topBoundary = 1
for i in 0...rows {
for j in 0...columns {
if i <= topBoundary || i == rows {
let block = SKSpriteNode(texture: blockImage, size: blockSize)
block.position.x = block.frame.width/2 + CGFloat((64*j))
block.position.y = frame.height - block.frame.height/2 - CGFloat((64*i))
block.zPosition = 1
addChild(block)
}
}
}
This question already has answers here:
How to round a Double to the nearest Int in swift?
(9 answers)
Closed 4 years ago.
I try to use swift code to calculate 10 * 75% = 7.5
var b : Int = 10
var a : Int = 75
// result x is 0
var x = b * (a / 100)
However the result is zero. How to get 7.5 result without changing the type and value of a and b?
UPDATE:
I got it right by:
var x: Double = (Double(b) * (Double(a) / 100)) // x is 7.5
Now, how can I round it to 8 as a Int type?
You're using integer (i.e. whole number) arithmetic, when what you want is floating-point arithmetic. Change one of the types to Float, and Swift will figure out that x is also a Float.
var b : Int = 10
var a : Int = 75
var x = Float(b) * (Float(a) / 100.0) // now x is a Float (.75)
For doing arithmetic in Swift, both sides of the equation must be using the same type. Try using this code:
let b = 10.0
let a = 75.0
let x = b * (a / 100.0
print(x)
7.5
To make it round up, use the built in ceil function
print(ceil(x))
8.0
Ok then you just need to do:
var b : Int = 10
let c = (Double(b) * 0.75)
let restult = ceil(c)
This question already has an answer here:
How to generate a random number in a range (10...20) using Swift [duplicate]
(1 answer)
Closed 4 years ago.
So I'm trying to generate a random number between negative and positive range because I need to give an object a position on the x axis. I've tried with arc4random and arc4random_uniform but it doesn't work. I need a way to generate a random position on the x axis, negative and positive.
I don't think you can generate negative random number using arc4random directly
let lValue = -10 // (your negative number)
let uValue = 10 //(your positive number)
let result = Int(arc4random_uniform(UInt32(uValue - lValue + 1))) + lValue
print(result)
hope this will work
let min : UInt32 = 10
let max : UInt32 = 50
let randomNumber = arc4random_uniform(max - min) + min
if arc4random_uniform(2) == 0 {
randomNumber = randomNumber * -1
}
This question already has answers here:
How to get mathemical PI constant in Swift
(3 answers)
Closed 5 years ago.
I have this error when updating my codes to Swift3.1 with Xcode 8.3.1
'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.
My codes under below,
let center = containerShapeView.center
let startAngle = CGFloat(0.0)
let endAngle = CGFloat(M_PI*2)
let radius = containerShapeView.bounds.width * 0.21
CGFloat(M_PI*2) line gives error
How can I resolve it ?
Well, follow the instructions of the error message:
let center = containerShapeView.center
let startAngle = CGFloat(0.0)
let endAngle = CGFloat(Double.pi) * 2
let radius = containerShapeView.bounds.width * 0.21
Or better yet, to avoid the unecessary conversions:
let center = containerShapeView.center
let startAngle: CGFloat = 0
let endAngle = CGFloat.pi * 2
let radius = containerShapeView.bounds.width * 0.21
I'm creating a game using Swift 2.0 and Sprite-Kit with Xcode7. I want to implement 4 purple balls that are suppose to resemble lives. So every time the player gets hit he loses one purple ball. They are supposed to appear side by side. I was wondering if instead of hardcoding 4 balls on to the scene I could instead use a for loop to display 4 balls.
let purpleBall = SKSpriteNode(texture: purpleTexture)
purpleBall.position = CGPointMake(self.frame.size.width * 0.65, self.frame.size.height * 0.92)
self.addChild(purpleBall)
I haven't been successful on getting 4 balls to appear on the scene. This was one of my attempts.
for(var i = 0.50; i <= 0.90; i = i + 0.10) {
let purpleBall = SKSpriteNode(texture: purpleTexture)
purpleBall.position = CGPointMake(self.frame.size.width * i, self.frame.size.height * 0.92)
self.addChild(purpleBall)
}
Here I get an error: Binary operator cannot be applied to operands of type 'CGFloat' and 'Double'
Do I have to convert i to CGFloat? and will this code actually place 4 different balls side by side or only move the single one to each new position.
Your code has an off by one error in the for loop. It should be a less than sign rather than less than or equal too. Your current code is going to create five purple balls.
You shouldn't really let i equal anything but an integer it's confusing. You could rewrite the code like this and it would do the same thing, without the worry of the float/double errors you're currently getting. Note that I will also use a constant called maxBalls, and distanceBetweenBalls so that you can easily change the number of balls and the distance without any complicated rewriting:
let maxBalls = 4
for(var i = 0; i < maxBalls; i++) {
let purpleBall = SKSpriteNode(texture: purpleTexture)
let ballXPosition = .50 + (i * .1)
purpleBall.position = CGPointMake(self.frame.size.width * ballXPosition, self.frame.size.height * 0.92)
self.addChild(purpleBall)
This should avoid the issues you were facing before, hope that helps.