I have multiple NSButtons generated with this code:
var height = 0
var width = 0
var ar : Array<NSButton> = []
var storage = NSUserDefaults.standardUserDefaults()
height = storage.integerForKey("mwHeight")
width = storage.integerForKey("mwWidth")
var x = 0
var y = 0
var k = 1
for i in 1...height {
for j in 1...width {
var but = NSButton(frame: NSRect(x: x, y: y + 78, width: 30, height: 30))
but.tag = k
but.title = ""
but.action = Selector("buttonPressed:")
but.target = self
but.bezelStyle = NSBezelStyle(rawValue: 6)!
ar.append(but)
self.view.addSubview(but)
x += 30
k++
}
y += 30
x = 0
}
And I need to add the NSClickGestureRecognizer to each of them to recognize secondary mouse button clicks. Is there any way to do that programmatically?
This should work:
let g = NSClickGestureRecognizer()
g.target = self
g.buttonMask = 0x2 // right button
g.numberOfClicksRequired = 1
g.action = Selector("buttonGestured:")
but.addGestureRecognizer(g)
and later
func buttonGestured(g:NSGestureRecognizer) {
debugPrintln(g)
debugPrintln(g.view)
if let v = g.view as? NSButton {
debugPrintln("tag: \(v.tag)")
}
}
Related
I am making a game with sprite kit in xcode and i want let the game finish when the player touch the monster, do you know how to use categorymask?
here is part of the code :
import SpriteKit
import GameplayKit
import CoreMotion
class GameScene: SKScene, SKPhysicsContactDelegate {
var player : SKSpriteNode!
var playerCategory : UInt32 = 0x1 << 0
var gameTimer2 : Timer!
var possiblealien = ["alien", "alien2", "alien3"]
let alienCategory : UInt32 = 0x1 << 1
override func didMove(to view: SKView) {
player = SKSpriteNode (imageNamed: "player")
player.position = CGPoint (x: self.frame.size.width / 2 - 500 , y:
player.size.height / 2 - 560)
player.size = CGSize(width: player.size.width * 6 ,
height: player.size.height * 6)
self.addChild(player)
player.zPosition = 2
self.physicsWorld.gravity = CGVector (dx: 0 , dy: 0 )
self.physicsWorld.contactDelegate = self
player.physicsBody?.contactTestBitMask = playerCategory
player.physicsBody? = SKPhysicsBody(rectangleOf: player.size)
player.physicsBody?.isDynamic = true
player.physicsBody?.categoryBitMask = monsterCategory
player.physicsBody?.collisionBitMask = 0
gameTimer2 = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(addalien), userInfo: nil, repeats: true)
motionManager.accelerometerUpdateInterval = 0.2
motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { ( data: CMAccelerometerData?, error:Error?)in
if let accelerometerData = data {
let acceleration = accelerometerData.acceleration
self.xAcceleration = CGFloat(acceleration.x) * 0.65 + self.xAcceleration * 0.25
}
}
#objc func addalien () {
possiblealien = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: possiblealien) as! [String]
let alien = SKSpriteNode(imageNamed: possiblealien[0])
let randomalienposition = GKRandomDistribution(lowestValue: -480, highestValue: +800 )
let position = CGFloat(randomalienposition.nextInt())
alien.position = CGPoint (x: position - 200 , y: self.frame.size.height * 0.5 + alien.size.height)
alien.physicsBody = SKPhysicsBody(rectangleOf: alien.size)
alien.physicsBody?.isDynamic = true
alien.physicsBody?.categoryBitMask = alienCategory
alien.physicsBody?.contactTestBitMask = playerCategory
alien.physicsBody?.collisionBitMask = 0
alien.zPosition = 2
alien.size = CGSize(width: alien.size.width * 1 ,
height: alien.size.height * 1)
self.addChild(alien)
let animationduration:TimeInterval = 6
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: position, y: -1000 ),duration: animationduration))
actionArray.append(SKAction.removeFromParent())
alien.run(SKAction.sequence(actionArray))
}
I see your problem, you need to declare it's physics body in a Physics Category, Otherwise, there would be no body for it at all
struct PhysicsCategory {
static let None:UInt32 = 0
static let All:UInt32 = UInt32.max
static let Player:UInt32 = 0b1
Also, The contactbitmasks should be what they will collide with along with collisiontestbitmask. catergorybitmask should be the category of the sprite in the struct
ex:
let alien = SKSpritenode()
alien.physicsBody?.categoryBitMask = PhysicsCategory.Alien
alien.physicsBody?.contactBitMask = PhysicsCategory.Player
alien.physicsBody?.collisionTestBitMask = PhysicsCategory.Player
Also, you can use | to declare if they will collide with multiple things
Hello guys, I create 14 buttons in for loop but each 7 buttons in one variable for example:
for i in 0...6 {
var button = UIButton()
...
var button2 = UIButton()
...
}
But I want create 14 buttons in one variable with for loop like in the picture:
In the picture I do it with two buttons in one for loop
And my sizes, xAxis and yAxis it must be :
let buttonWidth = self.view.frame.size.width / 7
var xAxis : CGFloat = 1
let yAxis : CGFloat = self.view.frame.size.height - (tileWidth * 2) - 100
let yAxis2 : CGFloat = self.view.frame.size.height - (tileWidth + 100)
So how can I create 14 button with using for loop with same sizes and axises ? like this :
for i in 0...13 {
var button = UIButton()
...
}
Edit
let emptySpace:CGFloat = 40 //how much you want (left + right)
var xAxis:CGFloat = emptySpace/2
let space:CGFloat = 2
let buttonWidth = ((self.view.frame.size.width)-((space*7)+emptySpace)) / 7
var yAxis : CGFloat = self.view.frame.size.height - (tileWidth * 2) - 100
let yAxis2 : CGFloat = self.view.frame.size.height - (tileWidth + 100)
for i in 1...14 {
let button = UIButton(type: .roundedRect)
button.frame = CGRect(x: xAxis, y: yAxis, width: buttonWidth, height: buttonWidth)
button.layer.cornerRadius = 10
xAxis = xAxis+buttonWidth+space
button.backgroundColor = UIColor.orange
view.addSubview(button)
if i%7 == 0 {
xAxis = emptySpace/2
yAxis = yAxis2+space
}
}
I have scrollView in which if there is no data, I need to hide (collapse the space occupied by it) so that the lower view can come upwards.
I tried this code with no luck. Please help me.
if(dataForScroll==0){
var newFrame:CGRect = self.myScroll.frame;
newFrame.size.height = 0;
self.myScroll.frame = newFrame
}
A simple example with Swift 3 version, i think it might be solves your problem. Let me know if have any queries
#IBOutlet var mainScrollView: UIScrollView!
#IBOutlet var view1: UIView!
#IBOutlet var view2: UIView!
#IBOutlet var view3: UIView!
var data1 = NSArray()
var data2 = NSArray()
var data3 = NSArray()
func setFrame()
{
// data = Something you need to get
if data1.count == 0
{
self.view1.frame.size.height = 0
}
else
{
// return its actual height you need
}
if data2.count == 0
{
self.view2.frame.size.height = 0
}
else
{
// return its actual height you need
}
if data3.count == 0
{
self.view3.frame.size.height = 0
}
else
{
// return its actual height you need
}
var frame = self.view1.frame
frame.origin.y = 5
self.view1.frame = frame
frame = self.view2.frame
frame.origin.y = self.view1.frame.origin.y + self.view1.frame.size.height + 5
self.view2.frame = frame
frame = self.view3.frame
frame.origin.y = self.view2.frame.origin.y + self.view2.frame.size.height + 5
self.view3.frame = frame
var scrollHeight:CGFloat = 0.0
var contentRect:CGRect = CGRect.zero
for views in self.mainScrollView.subviews
{
let subView:UIView = views
contentRect = contentRect.union(subView.frame)
print(subView.frame.size.height)
scrollHeight = scrollHeight + subView.frame.size.height
}
self.mainScrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: scrollHeight + 20) // the "+ 20" reamains the spaces between the views, you can change as per your need
}
This is with out launch screen.
This is with launch screen.
Any thoughts on what I might have done wrong?
Ok I had paste in sections because it would complain about the format other wise.
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate
var bird: SKSpriteNode = SKSpriteNode()
var overlay: SKSpriteNode = SKSpriteNode()
var scoreLabel: SKLabelNode = SKLabelNode(fontNamed: "System-Bold")
var ground1: SKSpriteNode = SKSpriteNode()
var ground2: SKSpriteNode = SKSpriteNode()
var background1: SKSpriteNode = SKSpriteNode()
var background2: SKSpriteNode = SKSpriteNode()
var mainPipe: Pipe = Pipe()
var pipes: [Pipe] = []
var space: Float = 90
var prevNum: Float = 0
var maxRange: Float = 175
var minRange: Float = -100
var birdCategory: UInt32 = 1
var pipeCategory: UInt32 = 2
var score: Int = 0
var movingSpeed: CGFloat = 3.3
var isMoving: Bool = false
var isGroundMoving: Bool = true
override func didMoveToView(view: SKView)
mainPipe = Pipe(color: UIColor.blackColor(), size: CGSize(width: view.bounds.size.width / 6, height: view.bounds.size.height))
overlay = SKSpriteNode(color: UIColor.grayColor(), size: self.view!.bounds.size)
overlay.alpha = 0.7
overlay.zPosition = 11
overlay.position.x += overlay.size.width / 2
overlay.position.y += overlay.size.height / 2
background1 = SKSpriteNode(imageNamed: "Background")
background2 = SKSpriteNode(imageNamed: "Background")
background1.position.x = view.bounds.size.width * 0.5
background2.position.x = view.bounds.size.width * 1.5
background1.position.y = view.bounds.size.height * 0.5
background2.position.y = view.bounds.size.height * 0.5
background1.texture!.filteringMode = SKTextureFilteringMode.Nearest
background2.texture!.filteringMode = SKTextureFilteringMode.Nearest
ground1 = SKSpriteNode(imageNamed: "Ground")
ground2 = SKSpriteNode(imageNamed: "Ground")
ground1.size.width = view.bounds.size.width + 2
ground2.size.width = view.bounds.size.width + 2
ground1.position.x = view.bounds.size.width * 0.5
ground2.position.x = view.bounds.size.width * 1.5
ground1.position.y = ground1.size.height * 0.4
ground2.position.y = ground2.size.height * 0.4
ground1.physicsBody = SKPhysicsBody(rectangleOfSize: ground1.size)
ground2.physicsBody = SKPhysicsBody(rectangleOfSize: ground2.size)
ground1.physicsBody!.dynamic = false
ground2.physicsBody!.dynamic = false
ground1.zPosition = 10
ground2.zPosition = 10
ground1.texture!.filteringMode = SKTextureFilteringMode.Nearest
ground2.texture!.filteringMode = SKTextureFilteringMode.Nearest
bird.physicsBody = SKPhysicsBody(circleOfRadius: 8)
bird.physicsBody!.dynamic = false
bird.physicsBody!.contactTestBitMask = pipeCategory
bird.physicsBody!.collisionBitMask = pipeCategory
bird.zPosition = 9
//bird.lineWidth = 0
bird = SKSpriteNode(imageNamed: "jennaface")
//bird.fillColor = UIColor.redColor()
bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.width / 2.5)
bird.position = CGPoint(x: 150, y: view.bounds.height / 2 - 10)
scoreLabel.position.x = 13
scoreLabel.position.y = view.bounds.height - 50
scoreLabel.text = "Score: 0"
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Left
scoreLabel.hidden = true
self.physicsWorld.contactDelegate = self;
self.physicsWorld.gravity = CGVectorMake(0, -3.5)
self.addChild(background1)
self.addChild(background2)
self.addChild(ground1)
self.addChild(ground2)
self.addChild(bird)
self.addChild(scoreLabel)
func spawnPipeRow(offs: Float)
{
let offset = offs - space / 2
let pipeBot = mainPipe.copy() as Pipe
let pipeTop = mainPipe.copy() as Pipe
pipeBot.texture = SKTexture(imageNamed: "BotPipe")
pipeTop.texture = SKTexture(imageNamed: "TopPipe")
pipeBot.texture!.filteringMode = SKTextureFilteringMode.Nearest
pipeTop.texture!.filteringMode = SKTextureFilteringMode.Nearest
pipeBot.isBottom = true
let xx = Float(self.view!.bounds.size.width)
self.setPositionRelativeBot(pipeBot, x: xx, y: offset)
self.setPositionRelativeTop(pipeTop, x: xx, y: offset + space)
pipeBot.physicsBody = SKPhysicsBody(rectangleOfSize: pipeBot.size)
pipeTop.physicsBody = SKPhysicsBody(rectangleOfSize: pipeTop.size)
pipeBot.physicsBody!.dynamic = false
pipeTop.physicsBody!.dynamic = false
pipeBot.physicsBody!.contactTestBitMask = birdCategory
pipeTop.physicsBody!.contactTestBitMask = birdCategory
pipeBot.physicsBody!.collisionBitMask = birdCategory
pipeTop.physicsBody!.collisionBitMask = birdCategory
pipes.append(pipeBot)
pipes.append(pipeTop)
self.addChild(pipeBot)
self.addChild(pipeTop)
}
func setPositionRelativeBot(node: SKSpriteNode, x: Float, y: Float)
{
let xx = (Float(node.size.width) / 2) + x
let yy = Float(self.view!.bounds.size.height) / 2 - (Float(node.size.height) / 2) + y
node.position.x = CGFloat(xx)
node.position.y = CGFloat(yy)
}
func setPositionRelativeTop(node: SKSpriteNode, x: Float, y: Float)
{
let xx = (Float(node.size.width) / 2) + x
let yy = Float(self.view!.bounds.size.height) / 2 + (Float(node.size.height) / 2) + y
node.position.x = CGFloat(xx)
node.position.y = CGFloat(yy)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
if (!bird.physicsBody!.dynamic)
{
//First touch
self.spawnPipeRow(0)
bird.physicsBody!.dynamic = true
bird.physicsBody!.velocity = CGVectorMake(0, 175)
scoreLabel.hidden = false
isMoving = true
} else if (isMoving)
{
var vel: CGFloat = 200
if (self.view!.bounds.size.height - bird.position.y < 85)
{
vel -= 85 - (self.view!.bounds.size.height - bird.position.y)
}
bird.physicsBody!.velocity = CGVectorMake(0, vel)
} else
{
overlay.removeFromParent()
for pi in pipes
{
pi.removeFromParent()
}
pipes.removeAll(keepCapacity: false)
score = 0
bird.physicsBody!.dynamic = false
bird.position = CGPoint(x: 150, y: view!.bounds.size.height / 2 - 10)
scoreLabel.hidden = true
isGroundMoving = true
}
}
override func update(currentTime: CFTimeInterval)
{
if (isGroundMoving)
{
ground1.position.x -= movingSpeed
ground2.position.x -= movingSpeed
if (ground1.position.x <= -self.view!.bounds.size.width / 2)
{
ground1.position.x = self.view!.bounds.size.width * 1.5 - 2
}
if (ground2.position.x <= -self.view!.bounds.size.width / 2)
{
ground2.position.x = self.view!.bounds.size.width * 1.5 - 2
}
background1.position.x -= movingSpeed / 3
background2.position.x -= movingSpeed / 3
if (background1.position.x <= -self.view!.bounds.size.width / 2)
{
background1.position.x = self.view!.bounds.size.width * 1.5 - 2
}
if (background2.position.x <= -self.view!.bounds.size.width / 2)
{
background2.position.x = self.view!.bounds.size.width * 1.5 - 2
}
if (isMoving)
{
for (var i = 0; i < pipes.count; i++)
{
let pipe = pipes[i]
if (pipe.position.x + (pipe.size.width / 2) < 0)
{
pipe.removeFromParent()
continue
}
if (pipe.position.x + (pipe.size.width / 2) < self.view!.bounds.size.width / 2 && pipe.isBottom && !pipe.pointAdded)
{
score++
pipe.pointAdded = true
}
pipe.position.x -= movingSpeed
if (i == pipes.count - 1)
{
if (pipe.position.x < self.view!.bounds.width - pipe.size.width * 2.0)
{
self.spawnPipeRow(self.randomOffset())
}
}
}
scoreLabel.text = "Score: \(score)"
}
}
}
func didBeginContact(contact: SKPhysicsContact!)
{
if (isMoving)
{
isMoving = false
isGroundMoving = false
bird.physicsBody!.velocity = CGVectorMake(0, 0)
for pi in pipes
{
pi.physicsBody = nil
}
self.addChild(overlay)
} else
{
bird.physicsBody!.velocity = CGVectorMake(0, 0)
}
}
func randomOffset() -> Float
{
let max = maxRange - prevNum
let min = minRange - prevNum
var rNum: Float = Float(arc4random() % 61) + 40 //40 - 100
var rNum1: Float = Float(arc4random() % 31) + 1
if (rNum1 % 2 == 0)
{
var tempNum = prevNum + rNum
if (tempNum > maxRange)
{
tempNum = maxRange - rNum
}
rNum = tempNum
} else
{
var tempNum = prevNum - rNum
if (tempNum < minRange)
{
tempNum = minRange + rNum
}
rNum = tempNum
}
prevNum = rNum
return rNum
}
class Pipe: SKSpriteNode
{
var isBottom: Bool = false
var pointAdded: Bool = false
}
The second day in a row I can not solve the problem with scroll area in Starling. Here is my code:
protected function onTouch(event:TouchEvent):void
{
var touches:Vector.<Touch> = event.getTouches(this, TouchPhase.MOVED);
if (touches.length == 1)
{
// one finger touching -> move
var delta:Point = touches[0].getMovement(parent);
x += delta.x;
y += delta.y;
}
else if (touches.length == 2)
{
// two fingers touching -> rotate and scale
var touchA:Touch = touches[0];
var touchB:Touch = touches[1];
var currentPosA:Point = touchA.getLocation(parent);
var previousPosA:Point = touchA.getPreviousLocation(parent);
var currentPosB:Point = touchB.getLocation(parent);
var previousPosB:Point = touchB.getPreviousLocation(parent);
var currentVector:Point = currentPosA.subtract(currentPosB);
var previousVector:Point = previousPosA.subtract(previousPosB);
if (_enableRotation)
{
var currentAngle:Number = Math.atan2(currentVector.y, currentVector.x);
var previousAngle:Number = Math.atan2(previousVector.y, previousVector.x);
var deltaAngle:Number = currentAngle - previousAngle;
}
// update pivot point based on previous center
var previousLocalA:Point = touchA.getPreviousLocation(this);
var previousLocalB:Point = touchB.getPreviousLocation(this);
pivotX = (previousLocalA.x + previousLocalB.x) * 0.5;
pivotY = (previousLocalA.y + previousLocalB.y) * 0.5;
// update location based on the current center
x = (currentPosA.x + currentPosB.x) * 0.5;
y = (currentPosA.y + currentPosB.y) * 0.5;
if (_enableRotation)
{
// rotate
rotation += deltaAngle;
}
// scale
var sizeDiff:Number = currentVector.length / previousVector.length;
var diffSize:Number = scaleX * sizeDiff;
if(( diffSize>= _minScale) && (diffSize <= _maxScale))
{
scaleX *= sizeDiff;
scaleY *= sizeDiff;
}
}
var touch:Touch = event.getTouch(this, TouchPhase.ENDED);
if (touch)
{
//here is my problem!
}
}
In last if I wanna check where is my child object (image), and if this object is out of screen, I wanna move scroll area (sprite) in center of screen. But I don't know how I can do this.
You can use ContainerLayout from Gazman SDK to do this job. It works with every starling displayObject.
Some this like this:
var layout = new ContainerLayout();
layout.horizontalCenter = 0;
layout.applyLayoutOn(myScroller);