cocos2d swift how to show a sprite? - ios

So I have my scene presenting and am trying to display a sprite when I press a button. I know the function is called because of a NSLog but I can't get the sprite to show.
func ShowShip() {
var booster = CCBReader.load("ccbResources/Booster")
booster.position = CGPoint(x: 0, y: 0)
self.addChild(booster)
NSLog("created sprite")
}
The log is called but the sprite isn't displayed. I looked at the quickstart tutorial and couldn't see much difference.
edit: tried calling the .png resource directly but got unwrapping error

Try direct method:
//method_1 : read image from disk
var booster = CCSprite(imageNamed:"Booster.png")
booster.position = CGPoint(x: 50, y: 50)
self.addChild(booster, z:3)
//method_2 : read image from sprite sheet
var frame1 = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName("Booster.png") as CCSpriteFrame
var booster = CCSprite(spriteFrame: frame1)
booster.position = CGPoint(x: 50, y: 50)
self.addChild(booster, z:3)

Related

Swift Change UIView Image

I am trying to make a basic game for iOS10 using swift 3 and scenekit. In one part of my games code I have a function that adds fishes to the screen, and gives each one a certain tag so i can find them later:
let fish = UIImageView(frame: CGRect(x: 0, y: 0, width: CGFloat(fishsize.0), height: CGFloat(fishsize.1)))
fish.contentMode = .scaleAspectFit
fish.center = CGPoint(x: CGFloat(fishsize.0) * -0.6, y: pos)
fish.animationImages = fImg(Fishes[j].size, front: Fishes[j].front)
fish.animationDuration = 0.7
fish.startAnimating()
fish.tag = j + 200
self.view.insertSubview(fish, belowSubview: big1)
What I would like is to be able to, at a certain point, recall the fish and
Change the images shown, and
Stop the animation.
Is this possible? I've been trying it with var fish = view.viewWithTag(killer+200)! but from this I can't seem to change any image properties of the new variable fish.
Any help would be much appreciated.
Tom
Try to cast the UIView to UIImageView like this.
if let fish = view.viewWithTag(killer+200) as? UIImageView {
//Perform your action on imageView object
}

How to create a ring with 3D effect using Sprite Kit?

I want to create a ring with a 3D effect using Sprite Kit. (SEE IMAGES)
I tried subclassing a SKNode and adding two nodes as children. (SEE CODE)
One node was a complete SKShapeNode ellipse, and the other was half ellipse using SKCropNode with a higher zPosition.
It looks good, but the SKCropNode increases the app CPU usage from 40% to 99%.
Any ideas on how to reduce the SKCropNode performance cost, or any alternative to create the same ring 3D effect?
class RingNode: SKNode {
let size: CGSize
init(size: CGSize, color: SKColor)
{
self.size = size
self.color = color
super.init()
ringPartsSetup()
}
private func ringPartsSetup() {
// LEFT PART (half ellipse)
let ellipseNodeLeft = getEllipseNode()
let leftMask = SKSpriteNode(texture: nil, color: SKColor.blackColor(), size: CGSize(
width: ellipseNodeLeft.frame.size.width/2,
height: ellipseNodeLeft.frame.size.height))
leftMask.anchorPoint = CGPoint(x: 0, y: 0.5)
leftMask.position = CGPoint(x: -ellipseNodeLeft.frame.size.width/2, y: 0)
let leftNode = SKCropNode()
leftNode.addChild(ellipseNodeLeft)
leftNode.maskNode = leftMask
leftNode.zPosition = 10 // Higher zPosition for 3D effect
leftNode.position = CGPoint(x: -leftNode.frame.size.width/4, y: 0)
addChild(leftNode)
// RIGHT PART (complete ellipse)
let rightNode = getEllipseNode()
rightNode.position = CGPoint(x: 0, y: 0)
rightNode.zPosition = 5
addChild(rightNode)
}
private func getEllipseNode() -> SKShapeNode {
let ellipseNode = SKShapeNode(ellipseOfSize: CGSize(
width: size.width,
height: size.height))
ellipseNode.strokeColor = SKColor.blackColor()
ellipseNode.lineWidth = 5
return ellipseNode
}
}
You've got the right idea with your two-layer approach and the half-slips on top. But instead of using a shape node inside a crop node, why not just use a shape node whose path is a half-ellipse? Create one using either CGPath or UIBezierPath API — use a circular arc with a transform to make it elliptical — then create your SKShapeNode from that path.
You may try converting your SKShapeNode to an SKSpriteNode. You can use SKView textureFromNode: (but we aware of issues with scale that require you to use it only after the node has been added to the view and at least one update cycle has run), or from scratch using an image (created programatically with a CGBitmapContext, of course).

SKPhysicsJointLimit EXC_BAD_ACCESS?

I'm using Sprite Kit (iOS), but whenever I try to add a SKPhysicsJointLimit to the physicsWorld, the app crashes with EXC_BAD_ACCESS (code=1, address=0xc0). Other joint types work fine, which is what's confusing me. Here's an example of what crashes:
var node1 = SKSpriteNode(color: SKColor.blueColor(), size: CGSize(width: 50, height: 50))
node1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 50, height: 50))
self.addChild(node1)
var node2 = SKSpriteNode(color: SKColor.blueColor(), size: CGSize(width: 50, height: 50))
node2.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 50, height: 50))
self.addChild(node2)
var joint = SKPhysicsJointLimit()
joint.maxLength = 1000
joint.bodyA = node1.physicsBody
joint.bodyB = node2.physicsBody
self.physicsWorld.addJoint(joint)
When I replace SKPhysicsJointLimit() with SKPhysicsJointFixed() (and remove the line setting maxLength) or some other joint type, the code works as expected.
I'm new to Sprite Kit, any ideas on how to solve this?
The app is crashing because you're not setting the joint's anchor point properties. From the docs, anchorA is
A connection point on the first body in the scene’s coordinate system.
and anchorB is
A connection point on the second body in the scene’s coordinate system.
Here's an example of how to create a SKPhysicsJointLimit object with physics bodies and anchor points as arguments:
let joint = SKPhysicsJointLimit.jointWithBodyA(node1.physicsBody!, bodyB: node2.physicsBody!, anchorA: node1.position, anchorB: node2.position)
joint.maxLength = 1000
physicsWorld.addJoint(joint)
I'm not sure if you can't set the anchor points directly.

How to Detect if a SKSpriteNode is in a SKShapeNode

I put a circular attack oval on a blue space ship and, if any SKSpriteNode enters the SKShapeNode (attack oval) the blue space ship can fire on the SKSpriteNode. The problem is that I can't figure out how to do the detection. I have tried physical bodies but, I can't have contact without having a collision.
Here is an example. I want the purple/blue attack circle to detect A,B,C,D,E
Here is the code I think you will need. RSSprite is short for red ship sprite
blueShip.position = CGPoint(x: 800, y: 400)
attackCircle = SKShapeNode(ellipseOfSize: CGSize(width: 1000, height: 400))
attackCircle.position = CGPoint(x: blueShip.position.x, y: blueShip.position.y)
RSSprite!.position = CGPoint(x: 200, y: 700)
RSSprite!.physicsBody = SKPhysicsBody(rectangleOfSize: RSSprite!.size)
In the update method you can check for an intersection of 2 nodes like this:
if([nodeA intersectsNode:nodeB]) {
// you have a collision
}

checking to see if location in scene is occupied by sprite

I am building my first iPhone game using Xcode, SpriteKit and Swift. I am new to these technologies but I am familiar with general programming concepts.
Here is what I am trying to do in English. I want circles to randomly appear on the screen and then begin to expand in size. However, I do not want a circle to appear in a location where a circle currently exists. I am having trouble determining each circle's position.
Inside GameScene.swift I have the following code inside the didMoveToView:
runAction(SKAction.repeatActionForever(
SKAction.sequence([
SKAction.runBlock(addCircle), SKAction.waitForDuration(3, withRange: 2)]
)))
The piece of code above calls my "addCircle" method:
func addCircle() {
// Create sprite.
let circle = SKSpriteNode(imageNamed: "grad640x640_circle")
circle.name = "circle"
circle.xScale = 0.1
circle.yScale = 0.1
// Determine where to position the circle.
let posX = random(min: 50, max: 270)
let posY = random(min: 50, max: 518)
// ***Check to see if position is currently occupied by another circle here.
circle.position = CGPoint(x: posX, y: posY)
// Add circle to the scene.
addChild(circle)
// Expand the circle.
let expand = SKAction.scaleBy(2, duration: 0.5)
circle.runAction(expand)
}
The random function above just chooses a random number within the given range. How can I check to see if my random functions are generating a location that is currently occupied by another circle?
I was thinking of using a do..while loop to randomly generate a set of x and y coordinates and then check to see if a circle is at that location but I cannot find how to check for that condition. Any help would be greatly appreciated.
There are a few methods which can help you in this regard:
(BOOL) intersectsNode: (SKNode*)node, available with SKNode, and
CGRectContainsPoint() as well as the CGRectContainsRect() methods.
For instance the loop to check for intersection can look as follows:
var point: CGPoint
var exit:Bool = false
while (!exit) {
let posX = random(min: 50, max: 270)
let posY = random(min: 50, max: 518)
point = CGPoint(x: posX, y: posY)
var pointFound: Bool = true
self.enumerateChildNodesWithName("circle", usingBlock: {
node, stop in
let sprite:SKSpriteNode = node as SKSpriteNode
if (CGRectContainsPoint(sprite.frame, point))
{
pointFound = false
stop.memory = true
}
})
if (pointFound)
{
exit = true
}
}
//point contains CGPoint where no other circle exists
//Declare new circle at point

Resources