I am making a simple side scrolling game using apple's swift programming language and I want to make my character move left when the left half of the screen is touched and right when the other half is touched. I have done this using this code:
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame){
character.position.x -= 30
} else if location.x > CGRectGetMidX(self.frame){
character.position.x += 30
} else {
println("jump")
}
}
but he stops moving immediately after he moves 30 px over. my question is, can someone explain how to make him keep moving until the user lifts their finger?
This is my GameScene.swift file:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let character = SKSpriteNode(texture: SKTexture(imageNamed: "character"))
override func didMoveToView(view: SKView) {
/* Setup your scene here */
//world
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0)
//background
var background = SKSpriteNode(imageNamed: "background")
background.size.height = self.frame.size.height
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(background)
//character
character.position = CGPointMake(self.frame.size.width * 0.6, self.frame.size.height * 0.6)
character.setScale(0.015)
character.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(character.size.width / 2))
var charPos = character.position
character.physicsBody?.dynamic = true
self.addChild(character)
//platform 1
var platformTexture = SKTexture(imageNamed: "platform")
var platform = SKSpriteNode(texture: platformTexture)
platform.position = CGPointMake(self.frame.size.width * 0.6, CGRectGetMidY(self.frame))
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.dynamic = false
platform.setScale(0.25)
self.addChild(platform)
//platform 2
var platformTexture2 = SKTexture(imageNamed: "platform")
var platform2 = SKSpriteNode(texture: platformTexture2)
platform2.position = CGPointMake(self.frame.size.width * 0.4, self.frame.size.height * 0.3)
platform2.physicsBody = SKPhysicsBody(rectangleOfSize: platform2.size)
platform2.physicsBody?.dynamic = false
platform2.setScale(0.25)
self.addChild(platform2)
//platform main
var platformTexture3 = SKTexture(imageNamed: "platform")
var platform3 = SKSpriteNode(texture: platformTexture2)
platform3.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + platform3.size.height / 3)
platform3.physicsBody = SKPhysicsBody(rectangleOfSize: platform3.size)
platform3.physicsBody?.dynamic = false
platform3.setScale(1)
platform3.size.width = platform3.size.width * CGFloat(2.0)
self.addChild(platform3)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
}
You have to apply force constantly to character in every update: call in order to move it without stopping. You can also apply impulses in order to move character, or make it jump. Here is an example based on you code, to give you a basic idea how you can move characters using physics (or by changing velocity vector of a character manually). Look through the comments to find what is important.
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let character = SKSpriteNode(texture: SKTexture(imageNamed: "pauseButton"))
//Boolean variable to store information about move signal (updated in touchesBegan and touchesEnded method)
var move = false
override func didMoveToView(view: SKView) {
/* Setup your scene here */
//world
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0)
self.physicsWorld.contactDelegate = self; //don't forget to set contact delegate if you want to use contact detection and methods like didBeginContact and didEndContact
//background
//just a physical border so that character can't escape from us :)
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//character
character.position = CGPointMake(self.frame.size.width * 0.6, self.frame.size.height * 0.6)
character.setScale(0.415)
character.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(character.size.width / 2))
var charPos = character.position
character.physicsBody?.dynamic = true
self.addChild(character)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
//Hold finger at upper area to move character constantly to the right.
if location.y > 400{
//moving allowed, force is applied in update method. read the docs about applyImpulse and applyForce methods and the differences between those two.
move = true
}else{
if location.x < CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: -30, dy: 0))
//tap somewhere above this to make character jump
if(location.y > 250) {
character.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
}
} else if location.x > CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: 30, dy: 0))
//tap somewhere above this to make character jump
if(location.y > 250) {
character.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
}
}
}
}
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
move = false
//character.physicsBody?.velocity = CGVector(dx: 0, dy: 0) //you can make character to stop by manually setting its velocity vector to (0,0)
}
override func update(currentTime: CFTimeInterval) {
if(move){character.physicsBody?.applyForce(CGVector(dx: 30, dy: 0))}
//if(move){character.position = CGPoint(x: character.position.x+1, y:character.position.y)} //not recommended if you need physics simulation (eg. collisions)
}
}
Note that you can change node's position in every update call to achieve what you want, like this :
if(move){character.position = CGPoint(x: character.position.x+1, y:character.position.y)}
But this way you will pull the node out of physics simulation and you can experience unexpected results. Search SO about this topic, there are some good posts about all this.
Hope this helps a bit.
Related
On the screenshot provided, the red arrow and cross are just for demonstration purposes and are not in the game. I would like the sprite of the spaceship to face the direction of the ball it shoots.
Link to image
Here is my current code for touch location
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
var bullet = SKSpriteNode(imageNamed: "bullet")
bullet.position = cannon.position
bullet.size = CGSize(width: 35, height: 35)
//physics
bullet.physicsBody = SKPhysicsBody(circleOfRadius: bullet.size.width/2)
bullet.physicsBody?.categoryBitMask = PhysicsCategory.bullet
bullet.physicsBody?.collisionBitMask = PhysicsCategory.enemy
bullet.physicsBody?.contactTestBitMask = PhysicsCategory.enemy
bullet.name = "bullet"
bullet.physicsBody?.affectedByGravity = false
self.addChild(bullet)
var dx = CGFloat(location.x - cannon.position.x)
var dy = CGFloat(location.y - cannon.position.y)
let magnitude = sqrt(dx * dx + dy * dy)
dx /= magnitude
dy /= magnitude
let vector = CGVector(dx: 120.0 * dx, dy: 120.0 * dy) //adjust constant to increase impluse.
bullet.physicsBody?.applyImpulse(vector)
// I found this code bellow this comment, but it just moves the cannon's y position
let direction = SKAction.moveTo(
CGPointMake(
400 * -cos(bullet.zRotation - CGFloat(M_PI_2)) + bullet.position.x,
400 * -sin(bullet.zRotation - CGFloat(M_PI_2)) + bullet.position.y
),
duration: 0.8)
cannon.runAction(direction)
}
}
Here is the code I found which works perfectly.
Rotate a sprite to sprite position not exact in SpriteKit with Swift
let angle = atan2(location.y - cannon.position.y , location.x - cannon.position.x)
cannon.zRotation = angle - CGFloat(M_PI_2)
I had been working some time ago in something like what you want so, here is my results
first you need to use VectorMath.swift created by Nick Lockwood and this is my code to make my spider move towards user touch
import SpriteKit
import SceneKit
class GameScene: SKScene {
let sprite = SKSpriteNode(imageNamed:"Aranna")
var velocity = Vector2(x: 0, y: 0)
var positionV2D = Vector2(x: 0, y: 0)
var headingVector = Vector2(x: 0, y: 1)
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let myLabel = SKLabelNode(fontNamed:"Chalkduster")
myLabel.text = "Hello, World!";
myLabel.fontSize = 45;
myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
sprite.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
positionV2D = Vector2(point:sprite.position);
let testVector = Vector2(x: 10, y: 14);
velocity += testVector;
print(velocity.toString());
velocity += Vector2(x: 1, y: 1);
//velocity = velocity + testVector;
print(velocity.toString());
velocity *= 0.5;
velocity.printVector2D();
velocity = Vector2(x: 2, y: 2);
velocity.normalized();
velocity.printVector2D();
self.addChild(sprite)
}
func ToRad(grados:CGFloat) ->CGFloat
{
return ((CGFloat(M_PI) * grados) / 180.0)
}
func ToDeg(rad:CGFloat) ->CGFloat
{
return (180.0 * rad / CGFloat(M_PI))
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
let toTarget = Vec2DNormalize(Vector2(point:location) - positionV2D);
let angle2 = headingVector.angleWith(toTarget);
print(ToDeg(CGFloat(angle2)));
headingVector.printVector2D();
self.sprite.runAction(SKAction.rotateToAngle(CGFloat(angle2), duration: 0.1))
self.sprite.runAction(SKAction.moveTo(location, duration: 0.5))
positionV2D = Vector2(point: location);
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
I hope this helps you
If you want to rotate only you shouldn't call the moveTo action.
Calculate the angle between touch location and location of the cannon and call action rotateToAngel
here is the code
let angle = atan2(dy, dx) - CGFloat(M_PI_2)
let direction = SKAction.rotateToAngle(angle, duration: 0.4, shortestUnitArc: true)
cannon.runAction(direction)
I found that with the answer submitted by James that this caused it to rotate in the wrong way, fine if you have something like a canonball but as it was used on my game which had a mage and a fireball with a trail it caused an issue, this can be easily fixed with
let angle = atan2(touchlocation.x - cannon.position.x , touchlocation.y -
cannon.position.y)
cannon.zRotation = -(angle - CGFloat(Double.pi/2))
use Double.pi / 2 and M_PI_2 is depriciated now
I want to make a simple platformer game in Xcode using Swift so that when I hold the left side of the screen, it continuously moves left until let go and vice versa. I have already added a jump feature but if you have any other suggestions I am open to take advice.
Here is my GameController.swift code:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let character = SKSpriteNode(imageNamed:"square.png")
let block = SKSpriteNode(imageNamed: "square.png")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
//Physics
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0)
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//Character
character.position = CGPoint(x:CGRectGetMidX(self.frame),
y:CGRectGetMidY(self.frame))
character.setScale(0.25)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
self.addChild(character)
//block
block.position = CGPoint(x: CGRectGetMidX(self.frame), y:
CGRectGetMidY(self.frame)*0.3)
block.setScale(0.2)
block.physicsBody = SKPhysicsBody(rectangleOfSize: block.size)
block.physicsBody?.dynamic = false
self.addChild(block)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch:AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) && location.y <
CGRectGetMidY(self.frame)*0.7{
character.physicsBody?.applyImpulse(CGVector(dx: -50, dy: 0))
} else if location.x > CGRectGetMidX(self.frame) && location.y <
CGRectGetMidY(self.frame)*0.7{
character.physicsBody?.applyImpulse(CGVector(dx: 50, dy: 0))
} else if location.y > character.position.y + 15 {
character.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
}
func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
character.removeActionForKey("moveAction")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch:AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
moveAction = SKAction.repeatActionForever(SKAction.moveByX(-20, y: 0, duration: 0.1))
let character.runAction(moveAction, withKey: "moveAction")
} else if location.x > CGRectGetMidX(self.frame) && location.y < CGRectGetMidY(self.frame)*0.7{
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(20, y: 0, duration: 0.1))
character.runAction(moveAction, withKey: "moveAction")
} else if location.y > character.position.y + 15 {
let moveAction = SKAction.repeatActionForever(SKAction.moveByX(0, y: 20, duration: 0.1))
character.runAction(moveAction, withKey: "moveAction")
}
}
}
I edited the touchesBegan method and I added a touchesEnded method. You seem to have tried to embed touchesEnded (and update) into the touchesBegan, which you definitely cannot do.
Okay, so, the code is pretty self explanatory, but anyway:
Instead of what you had with the vectors, I added an SKAction that runs forever. Changing the duration will change how fast the object moves. A lower duration results in a faster object, and vice versa (because lower duration means less time to get somewhere, hence a faster speed). When touchesEnded is called, the action, whose key is "moveAction" is removed from character, thereby stopping it.
That's pretty much it. If you have any questions, please, tell me!
By the way, I'm not sure if you intended for this, but when you run the action for the object to move up, character ultimately ends up bouncing up and down because of the gravity.
I've asked a few times but haven't really found what I'm looking for. I need a simple character controller that allows my character to continuously move left if the left side of the screen is held and right side as well. When let go I would like the character to stop moving.
My GameScene.swift file:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let character = SKSpriteNode(texture: SKTexture(imageNamed: "character"))
var move = false
override func didMoveToView(view: SKView) {
/* Setup your scene here */
//world
self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -5.0)
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//character
character.position = CGPointMake(self.frame.size.width * 0.6, self.frame.size.height * 0.6)
character.setScale(0.2)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.dynamic = true
character.physicsBody?.allowsRotation = false
self.addChild(character)
character.physicsBody?.affectedByGravity = true
//platform 1
var platform = SKSpriteNode(texture: SKTexture(imageNamed: "platform"))
platform.position = CGPointMake(self.frame.size.width * 0.6, CGRectGetMidY(self.frame))
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.dynamic = false
platform.setScale(0.25)
platform.physicsBody?.friction = 1
platform.physicsBody?.restitution = 0
platform.physicsBody?.linearDamping = 0
self.addChild(platform)
//platform 2
var platformTexture2 = SKTexture(imageNamed: "platform")
var platform2 = SKSpriteNode(texture: platformTexture2)
platform2.position = CGPointMake(self.frame.size.width * 0.4, self.frame.size.height * 0.3)
platform2.physicsBody = SKPhysicsBody(rectangleOfSize: platform2.size)
platform2.physicsBody?.dynamic = false
platform2.setScale(0.25)
platform2.physicsBody?.friction = 1
platform2.physicsBody?.restitution = 0
platform2.physicsBody?.linearDamping = 0
self.addChild(platform2)
//platform main
var platformTexture3 = SKTexture(imageNamed: "platform")
var platform3 = SKSpriteNode(texture: platformTexture2)
platform3.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + platform3.size.height / 3)
platform3.physicsBody = SKPhysicsBody(rectangleOfSize: platform3.size)
platform3.physicsBody?.dynamic = false
platform3.setScale(1)
platform3.size.width = platform3.size.width * CGFloat(2.0)
platform3.physicsBody?.friction = 1
platform3.physicsBody?.restitution = 0
platform3.physicsBody?.linearDamping = 0
self.addChild(platform3)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: -50, dy: 0))
} else if location.x > CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: 50, dy: 0))
}
}
func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
character.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
};
}
Use a UIGestureRecognizer to track when the finger is pressed and held down. The UILongPressGestureRecognize is what you need. Check the official documentation here:
Long Press Gesture Recognizer
When the gesture recognizer is called, you could then apply the impulse in the same manner that you are doing now. However, you should probably turn off friction on your physics bodies everywhere since that will obviously decelerate whatever you want to move. If you really want friction to stay, then you can then use an SKAction and have the node move by a certain X. Then, run that action repeatedly.
The Long Press GestureRecognizer will change its state when the user lifts their finger. When that happens, all you have to do is - (if you are using the physics way): turn velocity of the node to zero OR (if you are using SKAction): stop the action.
edit: Here is more or less what you should have:
Implement the UILongPressGestureRecognizer:
UILongPressGestureRecognizer *pressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(performLongPress)];
then create a method:
-(int)performLongPress(UILongPressGestureRecognizer *){
if (gesture.state == UIGestureRecognizerStateBegan){
//you know that the user just started pressing screen.
if([gesture locationInView:self] == wherever you want it to be...){
//apply your impulse here instead
}
}
}
then set friction to zero everywhere.
I'm making a game in sprite kit and in order to move my character I am applying an impulse but that is a problem because that moves him every 50 pixels or so. My question is, could someone please show me how to make a simple character controller so my character can move continuously until the user lets go from holding down the screen?
My GameScene.swift file:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let character = SKSpriteNode(texture: SKTexture(imageNamed: "character"))
var move = false
override func didMoveToView(view: SKView) {
/* Setup your scene here */
//world
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
//character
character.position = CGPointMake(self.frame.size.width * 0.6, self.frame.size.height * 0.6)
character.setScale(0.2)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.dynamic = true
character.physicsBody?.allowsRotation = false
self.addChild(character)
character.physicsBody?.affectedByGravity = true
//platform 1
var platform = SKSpriteNode(texture: SKTexture(imageNamed: "platform"))
platform.position = CGPointMake(self.frame.size.width * 0.6, CGRectGetMidY(self.frame))
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.dynamic = false
platform.setScale(0.25)
platform.physicsBody?.friction = 1
platform.physicsBody?.restitution = 0
platform.physicsBody?.linearDamping = 0
self.addChild(platform)
//platform 2
var platformTexture2 = SKTexture(imageNamed: "platform")
var platform2 = SKSpriteNode(texture: platformTexture2)
platform2.position = CGPointMake(self.frame.size.width * 0.4, self.frame.size.height * 0.3)
platform2.physicsBody = SKPhysicsBody(rectangleOfSize: platform2.size)
platform2.physicsBody?.dynamic = false
platform2.setScale(0.25)
platform2.physicsBody?.friction = 1
platform2.physicsBody?.restitution = 0
platform2.physicsBody?.linearDamping = 0
self.addChild(platform2)
//platform main
var platformTexture3 = SKTexture(imageNamed: "platform")
var platform3 = SKSpriteNode(texture: platformTexture2)
platform3.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + platform3.size.height / 3)
platform3.physicsBody = SKPhysicsBody(rectangleOfSize: platform3.size)
platform3.physicsBody?.dynamic = false
platform3.setScale(1)
platform3.size.width = platform3.size.width * CGFloat(2.0)
platform3.physicsBody?.friction = 1
platform3.physicsBody?.restitution = 0
platform3.physicsBody?.linearDamping = 0
self.addChild(platform3)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: -50, dy: 0))
} else if location.x > CGRectGetMidX(self.frame){
character.physicsBody?.applyImpulse(CGVector(dx: 50, dy: 0))
}
}
func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
character.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
};
}
One way to accomplish this is to maintain a variable to keep track of the state of the touch events (left, right, or none). Here are the basic steps:
In touchesBegan, set touch state variable to left or right
In update, apply impulse continuously while user is touching the screen
In touchesEnded, reset the touch state variable
Here's an example of how to implement this...
Above GameScene class definition, add the following
enum TouchState {
case Left
case Right
case None
}
In GameScene, add the following variable
var touchLocation:TouchState = .None
In GameScene, add or replace the following methods
override func update(currentTime: CFTimeInterval) {
// Apply impulse to physics body while users is touching the screen
switch (touchState) {
case .Left:
character.physicsBody?.applyImpulse(CGVector(dx: -1, dy: 0))
case .Right:
character.physicsBody?.applyImpulse(CGVector(dx: 1, dy: 0))
case .None:
break
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) {
touchState = .Left
} else if location.x > CGRectGetMidX(self.frame) {
touchState = .Right
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
// Update touch status
touchState = .None
}
Here's the GameScene.swift...
import SpriteKit
enum TouchLocation {
case Left
case Right
case None
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var character = SKSpriteNode(imageNamed: "character")
var touchLocation:TouchLocation = .None
override func didMoveToView(view: SKView) {
/* Setup your scene here */
scaleMode = .ResizeFill
//character
character.position = CGPointMake(view.frame.size.width * 0.5, view.frame.size.height * 0.5)
character.setScale(0.1)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.dynamic = true
character.physicsBody?.allowsRotation = false
self.addChild(character)
character.physicsBody?.affectedByGravity = true
//platform 1
var platform = SKSpriteNode(texture: SKTexture(imageNamed: "platform"))
platform.position = CGPointMake(view.frame.size.width * 0.6, CGRectGetMidY(view.frame))
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.dynamic = false
platform.setScale(0.25)
platform.physicsBody?.friction = 1
platform.physicsBody?.restitution = 0
platform.physicsBody?.linearDamping = 0
self.addChild(platform)
//platform 2
var platformTexture2 = SKTexture(imageNamed: "platform")
var platform2 = SKSpriteNode(texture: platformTexture2)
platform2.position = CGPointMake(view.frame.size.width * 0.4, view.frame.size.height * 0.3)
platform2.physicsBody = SKPhysicsBody(rectangleOfSize: platform2.size)
platform2.physicsBody?.dynamic = false
platform2.setScale(0.25)
platform2.physicsBody?.friction = 1
platform2.physicsBody?.restitution = 0
platform2.physicsBody?.linearDamping = 0
self.addChild(platform2)
//platform main
var platformTexture3 = SKTexture(imageNamed: "platform")
var platform3 = SKSpriteNode(texture: platformTexture2)
platform3.position = CGPointMake(CGRectGetMidX(view.frame), CGRectGetMinY(view.frame) + platform3.size.height / 3)
platform3.physicsBody = SKPhysicsBody(rectangleOfSize: platform3.size)
platform3.physicsBody?.dynamic = false
platform3.setScale(1)
platform3.size.width = platform3.size.width * CGFloat(2.0)
platform3.physicsBody?.friction = 1
platform3.physicsBody?.restitution = 0
platform3.physicsBody?.linearDamping = 0
self.addChild(platform3)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
switch (touchLocation) {
case .Left:
character.physicsBody?.applyImpulse(CGVector(dx: -1, dy: 0))
case .Right:
character.physicsBody?.applyImpulse(CGVector(dx: 1, dy: 0))
case .None:
break
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch:AnyObject in touches {
let location = touch.locationInNode(self)
if location.x < CGRectGetMidX(self.frame) {
touchLocation = .Left
} else if location.x > CGRectGetMidX(self.frame) {
touchLocation = .Right
}
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touchLocation = .None
}
}
My code for my touches began function is this:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let moveBall = SKAction.moveToY(380, duration: 0.4)
let moveBalldown = SKAction.moveToY(293, duration: 0.4)
if ball.position.y == 293 {
ball.runAction(moveBall)
}
if ball.position.y == 380 {
ball.runAction(moveBalldown)
}
When I tap the screen, nothing happens.
I want the ball to move up and down depending on the tap.
The ball should move up on the first tap and then back down once it is at y = 380, and the screen is tapped again.
Here is the rest of the code that affects the ball.
var ball = SKSpriteNode(imageNamed: "ball")
self.ball.position = CGPoint(x:40, y:293)
self.addChild(self.ball)
self.ball.yScale = 0.17
self.ball.xScale = 0.17
self.physicsWorld.gravity = CGVectorMake(0, 0)
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height * 0.08)
ball.physicsBody?.dynamic = true
var degreeRotation = CDouble(self.SBEBSpeed) * M_PI / 180
self.ball.zRotation -= CGFloat(degreeRotation)
let moveBall = SKAction.moveToY(380, duration: 0.4)
let moveBalldown = SKAction.moveToY(293, duration: 0.4)
if ball.position.y == 293 {
ball.runAction(moveBall)
}
if ball.position.y == 380 {
ball.runAction(moveBalldown)
}
I haven't touched SpriteKit in some time but I wanted to test your code. I'm currently running XCode Version 6.3.1, and I see they've updated the touchesBegan function to now take a Set of NSObjects. But your actual code inside the method runs just fine, so as long as you have set your "ball" to the right coordinates when it is initially rendered. Here is my working example:
import SpriteKit
class GameScene: SKScene {
var ball = SKSpriteNode()
override func didMoveToView(view: SKView) {
var ballTexture = SKTexture(imageNamed: "ball.png")
ball = SKSpriteNode(texture: ballTexture)
ball.position = CGPoint(x: CGRectGetMidX(self.frame), y: 293)
self.addChild(ball)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let moveBall = SKAction.moveToY(380, duration: 0.4)
let moveBalldown = SKAction.moveToY(293, duration: 0.4)
if ball.position.y == 293 {
ball.runAction(moveBall)
}
if ball.position.y == 380 {
ball.runAction(moveBalldown)
}
}
EDIT: (Because I can't comment yet, and I didn't want to make a new answer) I ran your code after you updated it and the ball does not even appear on my screen. Is that happening to you when you say nothing is happening? The only problem was the x-position. I would recommend using coordinates that are relative of self.frame