swift - Moving SKSpriteNode to location of the touch -
above image of game. top-down game. wherever on screen player touches, want bullets go location duration. want player able drag around finger on screen, , same thing happens. player doesn't have touch screen everytime wants shoot.
i've tried different stuff far nothing seems work.
first off, dont know if should have separate function bullet. anyway, bullet function.
func spawnbullets() { let bullet = skspritenode(imagenamed: "bullet") bullet.name = "bullet" bullet.zposition = 4 bullet.position = cgpoint(x: player.position.x + 19, y: player.position.y) self.addchild(bullet) }
i have "timer" bullet in didmove function:
var timer = timer.scheduledtimer(timeinterval: 0.1, target: self, selector: selector("spawnbullets"), userinfo: nil, repeats: true)
and lastly, touchesbegan function:
override func touchesbegan(_ touches: set<uitouch>, event: uievent?) { touch in touches { let location = touch.location(in: self) let movetopoint = skaction.move(to: location, duration: 0.5) let repeataction = skaction.repeatforever(movetopoint) bullet.run(movetopoint) } }
here go - simple app ship can drag around screen , missiles shoot towards location of touch.
if touch ship can drag around; touch outside ship , missile shoot ship touch location.
import spritekit class gamescene: skscene { var ship = skspritenode() var shipistouched = false var missiledestination = cgpoint() let missilespeed: cgfloat = 800 // points per second) let missilefirerate : timeinterval = 0.2 // seconds between each missile override func didmove(to view: skview) { missiledestination = cgpoint(x: 0, y: (self.size.height / 2)) createplayership() let fire = skaction.sequence([skaction.run(firemissile), skaction.wait(forduration: missilefirerate)]) run(skaction.repeatforever(fire)) } override func touchesbegan(_ touches: set<uitouch>, event: uievent?) { if let touch = touches.first { if ship.contains(touch.location(in: self)) { shipistouched = true } else { missiledestination = touch.location(in: self) ship.zrotation = direction(to: missiledestination, from: ship.position) - cgfloat(double.pi/2) } } } override func touchesmoved(_ touches: set<uitouch>, event: uievent?) { if (shipistouched == true) { ship.position = (touches.first?.location(in: self))! ship.zrotation = direction(to: missiledestination, from: ship.position) - cgfloat(double.pi/2) } } override func touchesended(_ touches: set<uitouch>, event: uievent?) { if shipistouched { shipistouched = false } } override func update(_ currenttime: timeinterval) { // called before each frame rendered } func createplayership() { ship = skspritenode(imagenamed: "spaceship") ship.zrotation = cgfloat(-double.pi/2.0) ship.scale(to: cgsize(width: 150, height: 150)) ship.position = cgpoint(x: -size.width/2 + 200, y: 0) addchild(ship) } func firemissile() { let missile = skspritenode(color: .white, size: cgsize(width: 50, height: 10)) missile.position = ship.position let missileflighttime = traveltime(to: missiledestination, from: ship.position, atspeed: missilespeed) missile.zrotation = direction(to: missiledestination, from: missile.position) addchild(missile) let missilemove = skaction.move(to: missiledestination, duration: timeinterval(missileflighttime)) let missileremove = skaction.removefromparent() missile.run(skaction.sequence([missilemove, missileremove])) } func traveltime(to target : cgpoint, : cgpoint, atspeed speed : cgfloat) -> timeinterval { let distance = sqrt(pow(abs(target.x - from.x),2) + pow(abs(target.y - from.y),2)) return timeinterval(distance/speed) } func direction(to target : cgpoint, from: cgpoint) -> cgfloat { let x = target.x - from.x let y = target.y - from.y var angle = atan(y / x) if x < 0 { angle = angle + cgfloat.pi } return angle } }
there's bit of trickery make missiles speed consistent (since moveto takes time, not speed, if destination close missiles move slowly, , if further away they'd move faster) , make missiles rotate face destination.
you create curved path missiles follow destination, cool may not appropriate app.
edit:
if want ship stationary, , missiles follow finger, replace code down createplayership
(yes, we've lost touchesended()
, update()
:
import spritekit class gamescene: skscene { var ship = skspritenode() var missiledestination = cgpoint() let missilespeed: cgfloat = 800 // points per second) let missilefirerate : timeinterval = 0.2 // seconds between each missile override func didmove(to view: skview) { missiledestination = cgpoint(x: size.height/2, y: 0) createplayership() let fire = skaction.sequence([skaction.run(firemissile), skaction.wait(forduration: missilefirerate)]) run(skaction.repeatforever(fire)) } override func touchesbegan(_ touches: set<uitouch>, event: uievent?) { if let touch = touches.first { missiledestination = touch.location(in: self) } } override func touchesmoved(_ touches: set<uitouch>, event: uievent?) { missiledestination = (touches.first?.location(in: self))! }
Comments
Post a Comment