create pause function for game using spritkit - xcode

i create a race game using spritkit
well i create button if the user click on it then it will pause the game , well my problem is that the Scene stop from moving but the car will stop slowly like the real car , i want to make stop without gravity
this is my code
physicsWorld.gravity = CGVectorMake(0.0,0.3);
physicsWorld.contactDelegate = self
this is player code
playerNode = SKSpriteNode(imageNamed: "car")
playerNode!.position = CGPoint(x: size.width / 2.0, y: 120.0)
playerNode!.physicsBody =
SKPhysicsBody(circleOfRadius: playerNode!.size.width / 2)
playerNode!.physicsBody!.dynamic = true
playerNode!.physicsBody!.linearDamping = 1.0
playerNode!.physicsBody!.allowsRotation = true
playerNode!.physicsBody!.categoryBitMask = CollisionCategoryPlayer
playerNode!.physicsBody!.contactTestBitMask =
CollisionCategoryPowerUpOrbs
playerNode!.physicsBody!.collisionBitMask = 0
foregroundNode!.addChild(playerNode!)
and finally this is the pause function
if (pasueornot){ // true or false
physicsWorld.gravity = CGVectorMake(0.0,gravitySpeed)
}
else{
physicsWorld.gravity = CGVectorMake(0.0,0.0) // the Scene stop from moving but the car will stop slowly like the real car pasueornot
}

Related

Godot duplicate and tween flicky

I am using Godot v3.42-v3.45 to make an implemetation of the boardgame Citadel. In order to make a card move, I develop a tween system. But sometimes the original card node will be "queue_free()"ed immediately after the tween starts, and the card will be gone from the screen and I don't want to wait till it's finished. So I try to make a copy node for just animation, hide the original one, set the final values on the original node, run the tween, show the original node and hide the copied node. But it gets flicky, the copied node seems to blink when the tween is finished. I try a lot of measures but it still blinks. Could anybody help me? Please run the ani_flip_move() function.
extends Node2D
onready var TimerGlobal = get_node("/root/Main/Timer") # a global timer stick to the main scene
onready var Data = get_node("/root/Main/Data") # Data.XXX is just some constants, Data.FAR_AWAY = Vector2(99999, 99999)
onready var Signal = get_node("/root/Main/Signal") # a signal bus stick to the main scene
class Trans:
var motion_list: Array
var copies: Dictionary
func _init() -> void:
motion_list = []
copies = {}
func add(node: Node2D, prop_name: String, start_val, end_val, ani_time: float = 1) -> void:
var copy
if node in copies:
copy = copies[node]
else:
copy = node.duplicate(node.DUPLICATE_USE_INSTANCING)
copies[node] = copy
node.set(prop_name, end_val)
motion_list.append([node, copy, prop_name, start_val, end_val, ani_time])
class Interval:
var wait_time: float
func _init(times: float) -> void:
wait_time = times
func animate(action_list: Array) -> void:
var _useless
var tween = Tween.new()
add_child(tween)
for action in action_list:
if action is Trans:
for motion in action.motion_list:
var orgi_node = motion[0]
var copy_node = motion[1]
var prop_name = motion[2]
var start_val = motion[3]
var end_val = motion[4]
var ani_time = motion[5]
orgi_node.set(prop_name, end_val)
orgi_node.set_visible(false)
if not copy_node.is_inside_tree():
add_child(copy_node)
_useless = tween.interpolate_property(
copy_node,
prop_name,
start_val,
end_val,
ani_time,
Tween.TRANS_CUBIC,
Tween.EASE_IN_OUT
)
_useless = tween.start()
yield(tween, "tween_all_completed")
for motion in action.motion_list:
var orgi_node = motion[0]
var copy_node = motion[1]
if is_instance_valid(orgi_node):
orgi_node.set_visible(true)
orgi_node.set_z_index(0)
if is_instance_valid(copy_node):
copy_node.set_z_index(0)
copy_node.queue_free()
elif action is Interval:
TimerGlobal.set_wait_time(action.wait_time)
TimerGlobal.start()
yield(TimerGlobal, "timeout")
remove_child(tween)
tween.queue_free()
Signal.emit_signal("all_ani_completed")
func ani_flip_move(
obj: Node2D,
end_pos: Vector2 = Data.FAR_AWAY,
end_scale: Vector2 = Data.FAR_AWAY,
end_visible: bool = true,
end_face_up: bool = true,
ani_time: int = 1
) -> void:
if end_scale == Data.FAR_AWAY:
end_scale = obj.scale
if end_pos == Data.FAR_AWAY:
end_pos = obj.global_position
var a1 = Trans.new()
var z_index = obj.z_index
a1.add(obj, "global_position", obj.global_position, end_pos, ani_time)
a1.add(obj, "scale", obj.scale, end_scale, ani_time)
a1.add(obj, "z_index", 1, 1, ani_time)
if "face_up" in obj:
a1.add(obj, "face_up", obj.face_up, end_face_up, ani_time)
animate([a1])

Expected Declaration Swift (Sprite Kit)

I'm using Xcode 7 with swift and when I type
class Block {
var Block = SKShapeNode(circleOfRadius: 15)
Block.fillColor = SKColor.redColor() //Error Here
Block.physicsBody = SKPhysicsBody(circleOfRadius: 15)
Block.physicsBody?.affectedByGravity = true
Block.physicsBody?.restitution = 0
Block.physicsbody?.LinearDamping = 0
self.addChild(Block)
It gives me an error that says "expected declaration" (on the line with the comment) and I don't know why
There are some errors:
You have a class and are trying to change class properties outside the scope of a method or an initializer.
The line Block.physicsbody?.LinearDamping = 0 should be Block.physicsBody?.linearDamping = 0; case-sensitivity.
You name your SKShapeNode instance as Block, the same name as your class. By naming convention, class (type) names begin with Capital letters, whereas class properties use small letters in their names.
With these three fixed, we can proceed to looking at your scene.
With help from Leo Dabus (thanks!), we should have enough to set you up with a minimal working example (using your code) of the SKScene:
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let block = SKShapeNode(circleOfRadius: 15)
// you will also need to set your node initial position
// if you would like your red circle to fall from the middle of the top of your scene you need to use the scene frame midX and maxY (not the view frame). the scene it is not necessarily the same size of your view)
block.position = CGPoint(x: scene!.frame.midX, y: scene!.frame.maxY)
block.fillColor = SKColor.redColor()
block.physicsBody = SKPhysicsBody(circleOfRadius: 15)
block.physicsBody?.affectedByGravity = true
block.physicsBody?.restitution = 0
block.physicsBody?.linearDamping = 0
self.addChild(block)
}
// ...
}

Xcode 6: Sprite node does not come in contact with other sprite node when tapped? Falls off screen?

I'm working in Swift and have created an SKSpriteNode to be the ground in my game. I've set it to the proper position and made the physics body as wide as the screen:
//Ground
var groundTexture = SKTexture(imageNamed: "groundBar")
var groundBar = SKSpriteNode(texture: groundTexture)
groundBar.setScale(2)
groundBar.position = CGPointMake(self.size.width/2, self.size.height/2)
groundBar.hidden = true
self.addChild(groundBar)
var ground = SKNode()
ground.position = CGPointMake(0, groundTexture.size().height)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height*2))
ground.physicsBody?.dynamic = false
self.addChild(ground)
Then I have another SKSpriteNode that is the character in my game, and when tapped I have this character jump up and to the right:
//Savior character
var saviorTexture = SKTexture(imageNamed: "character")
saviorTexture.filteringMode = SKTextureFilteringMode.Nearest
savior = SKSpriteNode(texture: saviorTexture)
savior.setScale(1)
savior.position = CGPoint(x: self.frame.size.width * 0.5, y: self.frame.size.height * 0.4)
savior.physicsBody = SKPhysicsBody(circleOfRadius: savior.size.height/2)
savior.physicsBody?.dynamic = true
savior.physicsBody?.allowsRotation = false
self.addChild(savior)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
savior.physicsBody?.velocity = CGVectorMake(0, 0) //pt it returns to?
savior.physicsBody?.applyImpulse(CGVectorMake(5, 30)) //direction/height that it jumps }
Before it is tapped, the character sits on the ground node and therefore doesn't fall off the screen. When tapped, however, the character jumps up and falls off the screen. It's as if it doesn't come in contact with the ground.
I've tried resizing the ground, repositioning the ground, but the character still falls off the screen. Mind you that when the vector is (0,30) and it just jumps straight up, it doesn't fall off the screen.
What is happening here?
In your view controller you can do skView.showsPhysics = true and see if the physics bodies are where you think they are. Also, be sure that their physicsBody.collisionBitMask are not the same.

Scrolling and dragging in Corona --> BUG?

I have a event listener assigned to an object. This then triggers the startDrag function. I'm moving my character in the game with dragging. But as soon as I scroll or move the display, my dragging function gets all messed up. It doesn't react as it should and the object(event.target) can't be controlled at all.
Did anyone else had this experience?
Is this a corona bug?
How can I solve this?
Can I temporarily disable the startDrag event listener for the time of scrolling? Or maybe restart it?
All help would be greatly appreciated.
Here is the code...
local physics = require( "physics" )
physics.start()
physics.setContinuous( false )
display.setStatusBar( display.HiddenStatusBar )
physics.setScale( 60 )
physics.setDrawMode( "hybrid" )
local height = display.contentHeight
local width = display.contentWidth
local allElements = display.newGroup()
local texsGroup = display.newGroup()
local backGround = display.newRect(0,0-height,width,2*height)
backGround:setFillColor(91,91,91)
backGround:toBack()
local wallBottom = display.newRect(texsGroup, 0,height-20,width,20)
physics.addBody(wallBottom, "static", { density=5, friction=0.5, bounce=0.3 } )
local tex = {}
local numberRips = 60
local texSize = {
-- w: texwidth, h: texheight, s: strength required
{w=30, h=20, s=1},
{w=20, h=10, s=1.5},
{w=10, h=10, s=2},
}
local r
local lim = display.newGroup()
local function createRips()
local originX = 0
local originY = height -75
for i=0,numberRips do
r = math.random(3)
local x = originX + math.random(width)
local y = originY - math.random(2*height)
tex[i] = display.newRect(lim, x, y, texSize[r].w, texSize[r].h)
tex[i].status = "active"
tex[i].size = texSize[r].s
if (r == 1) then
tex[i]:setFillColor(51,255,0)
elseif (r == 2) then
tex[i]:setFillColor(255,51,51)
elseif (r == 3) then
tex[i]:setFillColor(51,51,255)
end
end
end
createRips()
local w, h, r = width/2, height - 265, 12
local L = display.newCircle(w-115,h+29,r)
local buttonRadius = 35
local button3 = display.newCircle((L.x),(L.y),buttonRadius)
button3.myName = "L"
allElements:insert(button3)
allElements:insert(lim)
allElements:insert(L)
local d, f, b = 15, 1, 0.15
physics.addBody(L, "dynamic", { density=d, friction=f, bounce=b, radius=r } )
button3.isVisible = false
button3.isHitTestable = true
physics.addBody( button3, "static", { density=1, radius=buttonRadius } )
local function addFrictionJoint(a, b, posX, posY, lowerAngle, upperAngle, mT)
local j = physics.newJoint ( "pivot", a, b, posX, posY, rFrom, rTo)
j.isLimitEnabled = true
j:setRotationLimits (lowerAngle, upperAngle)
return j
end
-- JOINTS
addFrictionJoint( button3, L, L.x, L.y, 0, 0 )
local function startDrag( event, params )
local body = event.target
local phase = event.phase
local stage = display.getCurrentStage()
local direction = event.direction
if "began" == phase then
stage:setFocus( body, event.id )
body.isFocus = true
event.target.bodyType = "dynamic"
-- Create a temporary touch joint and store it in the object for later reference
if params and params.center then
-- drag the body from its center point
body.tempJoint = physics.newJoint( "touch", body, body.x, body.y )
else
-- drag the body from the point where it was touched
body.tempJoint = physics.newJoint( "touch", body, event.x, event.y )
end
--body.tempJoint.maxForce = 0.25*body.tempJoint.maxForce
-- Apply optional joint parameters
if params then
local maxForce, frequency, dampingRatio
if params.maxForce then
-- Internal default is (1000 * mass), so set this fairly high if setting manually
body.tempJoint.maxForce = params.maxForce
end
if params.frequency then
-- This is the response speed of the elastic joint: higher numbers = less lag/bounce
body.tempJoint.frequency = params.frequency
end
if params.dampingRatio then
-- Possible values: 0 (no damping) to 1.0 (critical damping)
body.tempJoint.dampingRatio = params.dampingRatio
end
end
elseif body.isFocus then
if "moved" == phase then
-- Update the joint to track the touch
body.tempJoint:setTarget( event.x, event.y )
elseif "ended" == phase or "cancelled" == phase then
stage:setFocus( body, nil )
body.isFocus = false
-- Remove the joint when the touch ends
body.tempJoint:removeSelf()
body.bodyType = "static"
end
end
-- Stop further propagation of touch event
return true
end
function moveCamera(e)
if button3.y < -lim.y + 300 then
allElements.y = -(button3.y - 300)
end
end
Runtime:addEventListener("enterFrame", moveCamera)
button3:addEventListener( "touch", startDrag )
When you scroll the screen the touch event and the physics object are in different coordinate systems. See localToContent/globalToContent

Bodies do not collide

i have set 2 bodies, a world with gravity,a tick method with step,and all the bodies are moving just fine,and i can apply forces on them, gravity is also working.
but no collision.
when body1 hit the ground he just go out of screen and not hit it and jump like a real ball.
when body1 hit body2 the just continue movement as nothing was happen.
the bodies have shape ,the world have edges, but no collision.
what am i missing here ?
here are some functions that i call from the init :
- (void)addBoxBodyForSprite:(CCSprite *)sprite {
b2BodyDef spriteBodyDef;
spriteBodyDef.type = b2_dynamicBody;
spriteBodyDef.position.Set(sprite.position.x/PTM_RATIO,sprite.position.y/PTM_RATIO);
spriteBodyDef.userData = sprite;
spriteBody = world->CreateBody(&spriteBodyDef);
b2PolygonShape spriteShape;
spriteShape.SetAsBox(sprite.contentSize.width/PTM_RATIO/2,sprite.contentSize.height/PTM_RATIO/2);
b2FixtureDef spriteShapeDef;
spriteShapeDef.shape = &spriteShape;
spriteShapeDef.density = 10.0;
spriteShapeDef.isSensor = true;
spriteBody->CreateFixture(&spriteShapeDef);
}
-(void)worldEdge
{
CGSize winSize = [CCDirector sharedDirector].winSize;
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = world->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
}
-(void)tick:(ccTime) dt
{
world->Step(dt,10,10);
for(b2Body *b=world->GetBodyList(); b; b=b->GetNext())
{
if(b->GetUserData() !=NULL )
{
CCSprite *sprite=(CCSprite *) b->GetUserData();//every b of the world will be update his position
sprite.position=ccp( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO ) ;
sprite.rotation=-1*CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
everything is moving allright but no collision ever.
The specific problem is this line:
spriteShapeDef.isSensor = true;
In box2d, when you set an fixture as a sensor, it will not collide with other fixtures.

Resources