I would like to take this sample code
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = .greenColor()
button.setTitle("Test Button", forState: .Normal)
button.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func buttonAction(sender: UIButton!) {
print("Button tapped")
}
...and place the code to create the button in another file. So it would look more like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
makeButton(vControl: self)
}
@objc func buttonAction(sender: UIButton!) {
print("Button tapped")
}
}
Of course the main flaw is that I would have to pass a pointer to the function buttonAction.
Something like we do in C
makeButton(vControl: self, bFunc: &buttonAction)
Have Googled a lot but can't seem to find the way to do this. How do I set up the makeButton page to recieve this?
func makeButton (vControl: ViewController, bFunc: ???)
What would the ??? be in reality?
thanks
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have a very simple app. All SKSpriteNodes, myBall, myBlue, and myRed.
Only myBall moves, affected by gravity, and bounces off of different objects (myRed and myBlue).
What I can't figure out is how to make myBall bounce harder or softer depending on which body it hits?
I hav been playing with the density of all the objects, but it doesn't seem to make any difference? Is there some property I am unaware of? Or are there other methods?
I've created a ball, and boxed my game scene.
The balls physics settings are:
self.physicsBody!.affectedByGravity = true
self.physicsBody!.restitution = 1.0
self.physicsBody!.linearDamping = 0
self.physicsBody!.friction = 0.3
self.physicsBody!.isDynamic = true
self.physicsBody!.mass = 0.5
self.physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
self.physicsBody?.collisionBitMask = bodyMasks.edgeMask.rawValue
self.physicsBody?.categoryBitMask = bodyMasks.ballMask.rawValue
When I box the game scene with:
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
the ball bounces back up as intended.
However, if I replace edgeLoopFrom with my own custom borders:
yourLine.lineWidth = 5
yourLine.path = pathToDraw
yourLine.isUserInteractionEnabled = false
yourLine.strokeColor = .clear
yourLine.isHidden = false
yourLine.zPosition = 10
yourLine.physicsBody = SKPhysicsBody(edgeLoopFrom: pathToDraw)
yourLine.physicsBody?.affectedByGravity = false
yourLine.physicsBody?.pinned = true
yourLine.physicsBody?.categoryBitMask = bodyMasks.edgeMask.rawValue
yourLine.physicsBody?.collisionBitMask = bodyMasks.ballMask.rawValue
yourLine.physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
the ball just comes down with a thud, stops, and doesn't bounce.,
So am trying to figure out what physics settings I have to give to my custom made edges so that the ball bounces?
I have an SkSpriteNode (ball) in a box. Gravity is set to false, otherwise it has an SkPhysicsBody to bounce off of walls.
Is there a method to give the ”ball” an initial push in a specified direction and velocity/strength wise?
I know it's uncool to ask vague questions here, but what do they call it when you create a world and follow it with a camera in Swift? Like an RPG? Like Doom?
I want to try and learn that now. And more importantly can it be done without using the Xcode scene builder? Can it be done all via code?
Thanks, as always. Without the forum I would never have gotten much farther than "Hello World!"
In my app, I have greyBars and one border bar. The border bar keeps the greyBars from falling off the screen.
Only one greyBar is used at a time. When it is completely filed with colored gems, a new bar is created and brought up from the bottom of the screen, with the code below.
The result I want is that the new bar, the one with all white diamonds pushes up the old bar and the new bar remains on the bottom. You can see by the screenshot that somehow the new bar ended up on top, even though it was coming from the bottom.
I slowed down the duration of the greyBar's movement to see what was going wrong.
While the two greyBars do clash with each other, the new one (the one on the bottom) ends up pushing THROUGH the top bar.
My assumption was that the new greyBar would just push up the old bar(s), and remain on the bottom.
Is there some "solidity" type property that I am missing?
myGreyBar[0].physicsBody?.categoryBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].isHidden = false;
myGV.gameScene?.addChild(myGreyBar[0])
let moveAction = SKAction.move(to: CGPoint(x:(myGV.safeSceneRect.width/2) - (size.width/2), y: (myGemBase?.size.height)! + (myGV.border?.size.height)! + 200), duration: 10.0)
myGreyBar[0].run(moveAction, completion:{myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.borderMask.rawValue|bodyMasks.greyBarMask.rawValue})
I have an SKSpriteNode with an SKAction being run on it:
theGem!.run(premAction, completion: {theGem!.run(repeatAction)})
Can't seem to find out the proper steps to run another action, such as:
theGem.run(endsequence, completion: {theGem.removeAllActions(); theGem.run(stopAction)})
Should I stop the previous action first?
Is there a way to turn the repeat part off so that the first SKAction ends smoothly?
I handled everything through touchesEnded. Was curious if I could hand off the call to touchesEnded from touchesCancelled?
It's a small thing, but every time I open my current Xcode project the default iOS device to run my app on is my phone. Is there a way to change it to one of the simulators? i.e. iPhone Pro 11?
Just curious why I get touchesCanceled even after I process:
@objc func tappedView(_ sender:UITapGestureRecognizer)
It's requiring a lot of extra coding to determine a real cancel vs I just got a tap.
I was looking to find a way to find out if my SKSpriteNode with an SKPhysicsBody is in motion.
I create a box, raise it above the bar, then set the bar and box masks to collide. The bar is pinned, but would love to know when the box stops bouncing.
I am using debug labels so I know when I get any touchesBegan, touchesMoving, touchesEnded, and touchesCanceled.
I get everything I expect, touchesBegan, touchesMoved, and touchesEnded. However, it would appear that if I barely, just barely move an SKSPriteNode, I get a touchesCanceled instead of touchesEnded. Even thought the call right before is touchesMoved.
Is this as intended? Is there some threshold you have to reach to get an ended instead of a canceled? And if so, can I see and change it?
Thanks
More than glad to put my code, tho not sure how that would change anything.
While debugging I would like to get a specific subclass's property. So far I can do this:
if let myPeg = getTargetSlot(node: node, location touchLocation){
print (myPeg.index)
}
Is it possible to write it in one line? Something like this?
print ("\(getTargetSlot(node: node, location touchLocation).index")
Because if there is a way, I cannot figure out the syntax.
Thanks
I know this is a silly question, but I just want to be safe.
I have multiple subclasses of SKSpriteNode in my app. In touchesBegan I am looking for a specific type, MyPeg. I just want to make sure that the code below fails if the node is not a MyPeg. I have this fear that if another of my subclasses is the same size, or too similar, or even has the same variables that I might get a positive.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
super.touchesBegan(touches , with:event)
guard let touch = touches.first else { return }
let location = touch.location(in: self)
let touchedNodes = self.nodes(at: location)
for theNode in touchedNodes{
if let node = theNode as? MyPeg{
In my app I create mutiple SKSpriteNodes, gems. Code snippet 1
When I loop through nodes from the main scene in a tap gesture, Code snippet 2, the gems register in a perfect square shape even though they are not. I have highlighted all areas that the orange gem registers in a tap as white. Here is the screen shot http://98.7.37.117/gem.png
Since the gem is itself not a square, I'd like to know if there is a way refine its shape so it would only show up in the list of nodes in UITapGestureRecognizer if the orange part is tapped. I have even tried by assigning it a physicsBody. But that made no difference.
Code Snippet 1
class MyGem : SKSpriteNode{
init(iColor : Gems) {
fileName = "\(iColor)_gem"
let skTexture = SKTexture(imageNamed: fileName)
super.init(texture: skTexture, color: .clear, size: .zero)
self.isHidden = true
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.size = CGSize(width: myGV.gemSize.width, height: myGV.gemSize.height)
self.zPosition = theZ.gem
self.position = CGPoint(x: 0, y: 0 )
self.isUserInteractionEnabled = false
self.name = "gem"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Code Snippet 2
@objc func tappedView(_ sender:UITapGestureRecognizer) {
if sender.state == .ended{
var post = sender.location(in: sender.view)
post = self.convertPoint(fromView: post)
for node in self.nodes(at: post){
if let touchNode = node as? MyGem
print("touched gem")
highliteGem(theGem: touchNode, clearAll: false)
return
}