All my textures are stretched vertically in Spritekit/Swift - swift

Let's say I have a basketball texture made up of pixel art and it's 21x21. I put it in the game:
ball = SKSpriteNode(imageNamed: "ball")
ball.position.x = CGFloat.random(min: 0 , max: self.frame.width)
ball.position.y = self.frame.height + ball.frame.height * 2
ball.zPosition = 1
ball.size = CGSizeMake(21 , 21)
ball.setScale(10)
ball.texture!.filteringMode = .Nearest
//then all the physics stuff
self.addChild(ball)
but when they spawn, the pixels are stretched vertically, and when the balls roll, it's always stretched vertically-so the problem seems to be rooted somewhere in the engine. What should I try next?
Thanks yall

Related

Shooting balls from a rotating cannon

I'm making a SpriteKit game. I have six cannons that I've made rotate back and fourth. I want to shoot cannonballs from each cannon that sync with the rotation of each cannon. I want a duration of one second between each cannonball.
So basically: A cannon that is in constant rotation is shooting cannonballs in the same direction as the rotation.
For the cannons i'm using an extension:
extension CGFloat {
func degreesToRadians() -> CGFloat {
return self * CGFloat.pi / 180
}
}
I'm gonna put the code for just one cannon, since I should be able to figure out how to adjust one of the cannonball movements to the others. Here is one:
func createCannons() {
let cannonLeftBottom = SKSpriteNode(imageNamed: "Cannon")
cannonLeftBottom.anchorPoint = CGPoint(x: 0.5, y: 0.5)
cannonLeftBottom.position = CGPoint(x: -325, y: -420)
cannonLeftBottom.zPosition = 4
cannonLeftBottom.setScale(0.4)
cannonLeftBottom.zRotation = CGFloat(65).degreesToRadians()
let rotateLB = SKAction.rotate(byAngle:
CGFloat(-65).degreesToRadians(), duration: 2)
let rotateBackLB = SKAction.rotate(byAngle:
CGFloat(65).degreesToRadians(), duration: 2)
let repeatRotationLB =
SKAction.repeatForever(SKAction.sequence([rotateLB,rotateBackLB]))
cannonLeftBottom.run(repeatRotationLB)
self.addChild(cannonLeftBottom)
}
Here is my function for the cannonball:
func createBalls() {
let cannonBallLB = SKSpriteNode(imageNamed: "Ball")
cannonBallLB.name = "CannonBall"
cannonBallLB.position = CGPoint(x: -325, y: -420)
cannonBallLB.physicsBody = SKPhysicsBody(circleOfRadius:
cannonBallLB.size.height / 2)
cannonBallLB.physicsBody?.affectedByGravity = false
cannonBallLB.zPosition = 3
cannonBallLB.setScale(0.1)
self.addChild(cannonBallLB)
}
THX!
You need to convert from Polar Coordinates to Rectangular Coordinates.
You do this by using sin and cos
E.G.
let speed = 100 //This would mean move 100 points per second
let force = CGVector(dx:cos(cannon.zRotation) * speed,dy:sin(cannon.zRotation) * speed)
cannonBall.applyForce(force)
Note: Now unless they changed this, force used to be in units of points, if they fixed it to units of meters, then you need to divide your speed by 150, since 150 points = 1 meter in Spritekit

Draw a circular SKSpriteNode with texture?

Is there a way to draw a circular SKSpriteNode with texture? Or alternatively, draw a SKShapeNode with texture?
It is to consider that all images are rectangle/squares. What we see as round, is how we show colored pixels: what is outside the circle, is transparent and what is inside, is the colored part.
we need a circle
we texture it
we add it to the scene
we take back a new texture from this shape node that we just added to the scene
we make a new sprite using this new texture
we add the sprite to the scene
let shape: SKShapeNode = SKShapeNode(circleOfRadius: 50)
shape.name = "shape"
shape.lineWidth = 1 // this way we see that this is a circle
shape.fillColor = .white // to see the true colors of our image
//shape.strokeColor = .white
//shape.glowWidth = 0
shape.fillTexture = SKTexture(imageNamed:"myImage")
shape.position = CGPoint(x: 0, y:200)
self.addChild(shape)
let newTexture: SKTexture = (self.view?.texture(from: self.childNode(withName: "shape")!))!
let sprite: SKSpriteNode = SKSpriteNode(texture: newTexture)
self.addChild(sprite)
shape.removeFromParent()

Sprite positioning at wrong points in y axis

so I know this is a dumb question, but maybe it'll help other people like me out too. Basically, I'm making a sprite appear at the top of the screen and then move to the bottom but in a random x position. There's nothing wrong with moving to the random x position, the problem is that it doesn't start out at the top of the screen. Here is my code:
let sprite = SKSpriteNode(imageNamed: "comet")
sprite.size = CGSize(width: 150, height: 100)
sprite.position = CGPoint(x: self.frame.size.width/2, y: 0)
sprite.zPosition = 100
self.addChild(sprite) `
let randomNum = CGPoint(x:Int (arc4random() % 1000), y: 1)
let actionMove = SKAction.moveTo(randomNum, duration: 1)
let actionComet = SKAction(actionMove)
sprite.runAction(actionComet)
Any help is appreciated.
You are placing your sprite at location (0,0) which is left bottom of the screen. If you want to place the sprite at the top use:
sprite.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height + sprite.size.height / 2.0)

Rotate a SKShapeNode with texture

I'm trying to rotate an SKShapeNode with a texture, but it's not working. Basically, I have a circle with a texture and I'm trying to make it rotate using the same way I have done with an SKSpriteNode:
let spin = SKAction.rotateByAngle(CGFloat(M_PI/4.0), duration: 1)
The problem is that the circle is rotating, but not the texture. I can check this by using this code:
let wait = SKAction.waitForDuration(0.5)
let block = SKAction.runBlock({
print(self.circle.zRotation)
})
let sequence = SKAction.sequence([wait, block])
self.runAction(SKAction.repeatActionForever(sequence))
This is the code I have for creating the SKShapeNode:
let tex:SKTexture = SKTexture(image: image)
let circle = SKShapeNode(circleOfRadius: 100 )
circle.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 200)
circle.strokeColor = SKColor.clearColor()
circle.glowWidth = 1.0
circle.fillColor = SKColor.whiteColor()
circle.fillTexture = tex
self.addChild(circle)
// Runing the action
circle.runAction(spin)
Please help. Thanks in advance!
PS: I know that using an SKSpriteNode would be better but my goal is to place a square image in a circular frame and I figured that using an SKShapeNode would be perfect. If anyone know how to create a circular SKSpriteNode, feel free to post it in the answers section! :)
This is what I'm trying to achieve (with the capability of rotating it):
You can achieve what you want by using SKCropNode and setting its mask property to be a circle texture:
override func didMoveToView(view: SKView) {
let maskShapeTexture = SKTexture(imageNamed: "circle")
let texture = SKTexture(imageNamed: "pictureToMask")
let pictureToMask = SKSpriteNode(texture: texture, size: texture.size())
let mask = SKSpriteNode(texture: maskShapeTexture) //make a circular mask
let cropNode = SKCropNode()
cropNode.maskNode = mask
cropNode.addChild(pictureToMask)
cropNode.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(cropNode)
}
Let's say that picture to mask has a size of 300x300 pixels. The circle you are using as a mask, in that case, has to have the same size. Means the circle itself has to have a radius of 150 pixels (diameter of 300 pixels) when made in image editor.
Mask node determines the visible area of a picture. So don't make it too large. Mask node has to be a fully opaque circle with transparent background.

How to fix some physics bodies behavior, when some bodies go off the physics edges?

I am working with a game, which has a physics world. I create physics box around the whole scene for prevent the sprites go off the screen. But the issue is, when i add too many bodies to the scene, some of them go off this physics box.
This is the physics box around the scene:
homeArea.size = CGSizeMake(self.frame.size.width, self.frame.size.height)
homeArea.position = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0)
homeLayer.addChild(homeArea)
homeArea.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRectMake(-homeArea.frame.width / 2.0, -homeArea.frame.height / 2.0, homeArea.frame.size.width, homeArea.frame.size.height))
This is these too many bodies:
func addSprites() {
for i in 0...20 {
for j in 0...20 {
let shape = SKShapeNode(rect: CGRectMake(-5.0, -5.0, 10.0, 10.0))
shape.fillColor = SKColor.redColor()
shape.position = CGPointMake(self.frame.size.width - (shape.frame.size.width * CGFloat(i)), 0.0 + (shape.frame.size.height * CGFloat(j)))
shape.physicsBody = SKPhysicsBody(rectangleOfSize: shape.frame.size)
shape.physicsBody?.dynamic = true
addChild(shape)
}
}
}
And i create a cannon shooting to these bodies. There i want to create something like splash from cannon's bullet. I shoot to this wall from sprites, and notice from nodes count, that because of my bullet, some sprites go off the screen. I added the method usesPreciseCollisionDetection. But it's all the same.