i have scrolling ground node in game player can jump , run on. how can change picture of ground node while game running? example, i'm spawning platforms periodically simple random number generator , if else condition spawns various platforms depending on number came number generator.
i want if number generator gives me number 4 picture of ground node changes water picture if touches water dies. code wrote picture of ground node wont change. i've tried this:
code ground node:
func initializingscrollingground() { var index = 0; index < 2; index += 1 { var ground = skspritenode(imagenamed: imagename) ground.size = cgsize(width: frame.width, height: frame.height / 6) ground.position = cgpoint(x: index * int(ground.size.width), y: -30) ground.zposition = 5 ground.anchorpoint = cgpointzero ground.name = "ground" let offsetx = ground.size.width * ground.anchorpoint.x let offsety = ground.size.height * ground.anchorpoint.y let path = cgpathcreatemutable() cgpathmovetopoint(path, nil, 0 - offsetx, 48 - offsety) cgpathaddlinetopoint(path, nil, 0 - offsetx, 0 - offsety) cgpathaddlinetopoint(path, nil, 655 - offsetx, 0 - offsety) cgpathaddlinetopoint(path, nil, 668 - offsetx, 48 - offsety) cgpathclosesubpath(path) ground.physicsbody = skphysicsbody(polygonfrompath: path) ground.physicsbody?.categorybitmask = physicscatagory.ground ground.physicsbody?.collisionbitmask = physicscatagory.player ground.physicsbody?.contacttestbitmask = physicscatagory.player ground.physicsbody?.affectedbygravity = false ground.physicsbody?.dynamic = false self.addchild(ground) } } func moveground() { self.enumeratechildnodeswithname("ground", usingblock: { (node, stop) -> void in if let ground = node as? skspritenode { ground.position = cgpoint(x: ground.position.x - self.groundvelocity, y: ground.position.y) // checks if ground node scrolled off screen, if yes, puts @ end of other node. if ground.position.x <= -ground.size.width { ground.position = cgpointmake(ground.position.x + ground.size.width * 2, ground.position.y) } } }) }
code random number generator:
func dicerollplatforms() { let diceroll = arc4random_uniform(4) + 1; if diceroll == 1 { // normal platforms imagename = "ground_layer" platforms_1() } if diceroll == 2 { // normal platforms imagename = "ground_layer" platforms_2() } if diceroll == 3 { // normal platforms imagename = "ground_layer" platforms_3() } if diceroll == 4 { // platforms water beneath them imagename = "water_layer" platformswithwater() } }
there old discussion how handle kind of events. agree way of thinking sees wrong use of update
method. why? because function called automatically 60 times per second (if it's possible) should fight counters, booleans and/or dispatch_once
fire event in specific time.
the timers.
in sprite-kit bad way trigger event in time timer:
+ (nstimer *)scheduledtimerwithtimeinterval:(nstimeinterval)ti target:(id)atarget selector:(sel)aselector userinfo:(nullable id)userinfo repeats:(bool)yesorno
in fact , opinion , according answer of learncocos2d here in sprite-kit must stay away : nstimer, performselector:afterdelay: , grand central dispatch because these timing methods ignore node's, scene's or view's paused state.
if want make timer in sprite-kit can use skaction
. don't runblock
, have thought extension.
code: swift 2.x , swift 3.x
extension skaction { class func scheduledtimerwithtimeinterval(time:nstimeinterval, selector: selector,withobject: anyobject = sknode(), repeats:bool)->skaction { // instead of nstimer use skactions let call = skaction.customactionwithduration(0.0) { node, _ in node.performselectoronmainthread(selector, withobject: withobject, waituntildone:false) } let wait = skaction.waitforduration(time) let seq = skaction.sequence([wait,call]) let callselector = repeats ? skaction.repeatactionforever(seq) : seq return callselector } }
// swift3
extension skaction { class func scheduledtimerwithtimeinterval(time:timeinterval, selector: selector,withobject: anyobject = sknode(), repeats:bool)->skaction { // instead of nstimer use skactions let call = skaction.customaction(withduration: 0.0) { node, _ in node.performselector(onmainthread: selector, with: withobject, waituntildone: false) } let wait = skaction.wait(forduration: time) let seq = skaction.sequence([wait,call]) let callselector = repeats ? skaction.repeatforever(seq) : seq return callselector } }
usage:
let time = 10.0 // or can generate random time let changeblocktimer = skaction.scheduledtimerwithtimeinterval(time, selector: #selector(gamescene.dicerollplatforms), repeats: true) self.runaction(changeblocktimer,withkey: "changeblocktimer") // stop self.removeactionforkey("changeblocktimer")
if want increase randomness of events can use function in code:
code:
func randombool() -> bool { return arc4random_uniform(2) == 0 ? true: false }
usage:
if randombool() { // give special gift enemies (shield, strong arms..) }
Comments
Post a Comment