Swiftã§åãã¦åãã®ããã²ã¼ã ãéçºãã人åããã¥ã¼ããªã¢ã«(ãªãã¨ãã¹ãã©ã¤ã¯ãä¾ã«Step by Step解説)
ãªãã¨ãã¹ãã©ã¤ã¯ã¨ã¯
ã²ã£ã±ã£ã¦æµã«ã¶ã¤ãã¦åãä¾ã®ã²ã¼ã ãã©ãã§ãã
ããã®ä½ãæ¹ãéãã¦ãSpriteKitãå©ç¨ããiOSã¢ããªã§ã®ç»é¢è¦ç´ ã®ç§»å/å転/æ¡å¤§ç¸®å°ãè¡çªãæ¥è§¦å¦çããã©ãã°(panã¸ã§ã¹ãã£ã¼)ã¸ã®å¯¾å¿ãç»é¢é·ç§»ãå«ãéçºã®ç¬¬ä¸æ©ãè¸ã¿åºãããã®ãã¥ã¼ããªã¢ã«ã§ãã
iPhoneã¢ããªéçºç°å¢ã§ããXcodeã®æºåã¨Swiftã®ã¨ã£ãããã¨ãã¦ã¯ããã¡ãã®ãã¥ã¼ããªã¢ã«ãã覧ä¸ããã
ããã¸ã§ã¯ãéå§ã
ååã®Swiftã²ã¼ã éçºãã¥ã¼ããªã¢ã«
ãã¡ããåèã«ããæ°ããã²ã¼ã ããã¸ã§ã¯ãã®éå§ããããããããªã³ã¼ããæ¶ããã¾ã§ã®ä½æ¥ãè¡ãã¾ãããã
ãã ããProject Nameã®ã¨ããã¯ãNantokaStrikeã«ãã¦ããã¾ãããã
ã²ã£ã±ã(ãã©ãã°ãpanã¸ã§ã¹ãã£ã¼)ã®åä½ã«å¯¾å¿ãã
ã²ã£ã±ãçãªæä½ã«å¯¾å¿ããã«ã¯ãPan Gesture Recognizerã使ãã¾ãã
- Project Navigatorã§Main.storyboardãã¯ãªãã¯ãã¦éã
- å³ä¸ã®æ¤ç´¢ããã¯ã¹ã«panã¨å ¥å
- Pan Gesture Recognizerã表示ãããã®ã§ããã©ãã°ï¼ãããããã
- ã¿ãã·ã¼ãã«è¶ãã¯ã¿ã¤ã£ã½ãã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦Assistan Editorãéã
- controlãæ¼ããªããTap Gesture Recognizerããã©ãã°ãã¦ãã³ã¼ãä¸ã®GameViewControllerã®ä¸ã«ãããããã
- åºã¦ãããã¤ã¢ãã°ã§ä¸è¨ã®éãå
¥åãã¦ãconnectãã¿ã³ãæ¼ã
- Connection: Action
- Name: didPan
- Type: UIPanGestureRecognizer
- Assistant Editorã使ãçµãã£ããéãã¦ããã¾ã
ãã¾ãè¡ãã¨didPanã®ã³ã¼ããçæããã¾ã
@IBAction func didPan(sender: UIPanGestureRecognizer) { }
- Pan Gesture Recognizerãå³ã¯ãªãã¯
- åºã¦ãããã¤ã¢ãã°ã§ãOutletsã®ä¸ã«ããdelegateã®å³ã®âããã©ãã°ãã¦ãGame View Controllerã«ãããã
ä»ã®æä½ã§ã
UIPanGestureRecognizerã¨GameViewControllerã«delegateã®é¢ä¿ã追å ãã
ã®ã§ãã³ã¼ãã«ããããåæ ãã¾ãã
- GameViewController.swiftãéãã¾ã
- ã¯ã©ã¹ã®ãããã³ã«ã«UIGestureRecognizerDelegateã追å ãã¾ã
class GameViewController: UIViewController, UIGestureRecognizerDelegate {
ã²ã£ã±ãæä½ã«å¯¾ãã¦ãdelegeteããã¯ã©ã¹ã®didPanã¡ã½ãããå¼ã³åºãããã®ã§ããã®ä¸ã«å¦çãæ¸ãã¾ã
var panPointReference: CGPoint? @IBAction func didPan(sender: UIPanGestureRecognizer) { let currentPoint = sender.translationInView(self.view) if let originalPoint = panPointReference { println("currentPoint: \(currentPoint)") } else if sender.state == .Began { println(".Began") panPointReference = currentPoint } if sender.state == .Ended { println(".Ended") panPointReference = nil } }
- didPanã®ä¸ã§ã¯ãsender.stateã®å¤ã調ã¹ããã¨ã§ãã²ã£ã±ãæä½ã®ç¶æ ã確èªãããã¨ãåºæ¥ã¾ãã
- å¼ã£ã±ãä¸ã§ãããã¨ã®ç¢ºèªã¨å¼ã£ã±ãéå§ä½ç½®ã¨ã®ç¸å¯¾ä½ç½®ãè¨ç®ããããã«ãã²ã£ã±ãéå§ä½ç½®ãã¯ã©ã¹å¤æ°panPointReferenceã«å ¥ãã¦ãããã¨ã«ãã¾ãã
- ãã®ãããªåºæ¬æ§é ã«ãããã¨ã«ãã¦ãã¾ãã¯ãä¸ã¤ã®ç¶æ ãã¨ã«ãã°ãåºåããããã«ãã¦ã¿ã¾ãã
ããã§ä¸æ¦ãâ+Rã§ã¢ããªãåããã¦ãXcodeã«ãã°ãåºåããããã¨ã確èªãã¾ããã
- å·¦ä¸ã®åçãã¿ã³ãæ¼ã
- ãããã¯ãâ + R (ã³ãã³ããã¼ãæ¼ããªããRãã¼ãæ¼ã)
ã·ãã¥ã¼ã¬ã¼ã¿ã¼ä¸ã§ä½åããã©ãã°ãã¦ã¿ã¦ãã°ãæ³å®éãã«åºåããã¾ãããï¼
â»Xcodeã®ãã°åºåã¯Shift+â+Yã§show/hideãã§ãã¾ã
Xcodeã«æ»ã£ã¦ãã¢ããªãåæ¢ãã¾ããã
- å·¦ä¸ã®åæ¢ãã¿ã³ãæ¼ã
- ãããã¯ãâ+.ï¼ã³ãã³ããã¼ãæ¼ããªããããªãªããã¼ãæ¼ãï¼
å¼ã£ã±ãæä½ã表ãç¢å°ã¨èªãã£ã©ã追å ãã
ç»é¢ä¸ã§ã²ã£ã±ãæä½ã表示ããç¢å°ã追å ãã¾ã
- ãã®ç»åããarrow.pngã¨ããååã§ä¿åãã¾ããã
- ä¿åããå ´æãFinderã§éãã¦Project Navigatorã®Supporting Filesã«ãã©ãã°ï¼ãããããã
- Choose options for adding these filesãã¤ã¢ãã°
- Copy items if necessaryã«ãã§ãã¯
- finishãã¯ãªãã¯
ã²ã£ã±ã対象ã®ãã£ã©ã¯ã¿ã¼ã追å ãã¦ããã¾ã
- ãã®ç»åããnantoka.pngã¨ããååã§ä¿åãã¾ããã
- æ®ãã¯arrow.pngã¨åãè¦é ã§ã
ã³ã¼ãä¸ã§ãã®äºã¤ã®ç»åã表示ããããã«ãã¾ãã
GameScene.swiftãéãã¦ãGameSceneã¯ã©ã¹ã次ã®ããã«æ¸ãæãã¾ãããã
class GameScene: SKScene { var arrow: SKSpriteNode var nantoka: SKSpriteNode required init(coder aDecoder: NSCoder) { fatalError("NSCoder not supported") } override init(size: CGSize) { println("\(size)") arrow = SKSpriteNode(imageNamed: "arrow") arrow.alpha = 1 arrow.position = CGPoint(x: 160, y: 160) arrow.xScale = 0.2 nantoka = SKSpriteNode(imageNamed: "nantoka") nantoka.size = CGSizeMake(40, 40) nantoka.position = CGPoint(x: 120, y: 180) super.init(size: size) backgroundColor = SKColor(red: 0.9, green: 0.9, blue: 0.9, alpha: 1.0) anchorPoint = CGPoint(x: 0, y: 0) addChild(arrow) addChild(nantoka) } override func update(currentTime: CFTimeInterval) { /* Called before each frame is rendered */ } }
ã¤ãã§ã«ãSKSceneã¯ã©ã¹ã®backgroundColorãæå®ãããã¨ã§èæ¯è²ãå¤æ´ãã¾ããã
ããã§ä¸æ¦ãåä½ã確èªãã¦ããã¾ãããã
ã²ã£ã±ãæä½ã®å¦çãå®è£ ãã
ç¢å°ãç®çã®è§åº¦ã¨å¤§ããã«ãªãããã«ã¢ãã¡ã¼ã·ã§ã³ãããã¡ã½ããturnArrowãå®ç¾©ãã¾ãããã
GameScene.swiftãéãã¦GameSceneã¯ã©ã¹ã«ãã®ã³ã¼ãã追å ãã¾ãã
func turnArrow(angle: CGFloat, scale: CGFloat) { let rotateAction = SKAction.rotateToAngle(angle, duration: 0.1) let scaleAction = SKAction.scaleXTo(scale, y: 1, duration: 0.1) arrow.runAction(SKAction.group([rotateAction, scaleAction])) }
- SKAction.scaleXToã使ã£ã¦ãã²ã£ã±ãã®å¤§ããã«åããã¦ç¢å°ç»åãæ¡å¤§ãã¾ã
- scaleã¯æ¡å¤§çãæå®ãã¾ãã
- 1ãå寸大
- 大ãããããå ´åã¯ã1ãã大ããå¤
- å°ãããããå ´åã¯ã1ããå°ããå¤
- durationã¯åä½ã«ãããæéãæå®ãã¾ã
- scaleã¯æ¡å¤§çãæå®ãã¾ãã
- SKAction.rotateToAngleã使ã£ã¦ãã²ã£ã±ãã®åãã«åããã¦ç¢å°ç»åãå転ãã¾ã
- angleã¯X軸ããåæè¨åãã®è§åº¦ãã©ã¸ã¢ã³ï¼ä¸å転ã2Ïã§ãï¼ã§æå®ãã¾ã
- è§åº¦angleã¯åº¦ã§ã¯ãªããã©ã¸ã¢ã³ã§æå®ãã¾ã
- durationã¯åä½ã«ãããæéãæå®ãã¾ã
次ã«ãGameViewController.swiftãéãã¦ãdidPanä¸ããturnArrowãå¼ã³åºãããã«ãã¾ãã
@IBAction func didPan(sender: UIPanGestureRecognizer) { let currentPoint = sender.translationInView(self.view) if let originalPoint = panPointReference { println("currentPoint: \(currentPoint)") let v = sub(currentPoint, p1: originalPoint) let len = length(v) scene.arrow.alpha = 1 scene.arrow.position = scene.nantoka.position let scale = 0.2 * len / CGFloat(5.0) scene.turnArrow(vector2radian(v), scale: scale) } else if sender.state == .Began { println(".Began") panPointReference = currentPoint } if sender.state == .Ended { println(".Ended") panPointReference = nil scene.arrow.alpha = 0 } }
didPanã¡ã½ããã®ä¸ã§ã¯ã
- ã²ã£ã±ãä¸ã®ä½ç½®ã¨å¼ã£ã±ãéå§ã®ä½ç½®ããç¢å°ã®åãã¨å¤§ãããè¨ç®ãã¾ã(subã¡ã½ãã)
- ã²ã£ã±ãéå§ã§ç¢å°ã表示ãããå¼ã£ã±ãçµäºã§ç¢å°ãè¦ããªããªãããã«alphaå¤ãå¤æ´ãã¾ã
- ã²ã£ã±ãè·é¢ãè¨ç®(lengthã¡ã½ãã)ããããã«æ¯ä¾ããç¢å°ã®æ¡å¤§çãscaleã¨ãã¾ã
- ãã¯ãã«ã®åããvector2radianã§è§åº¦(ã©ã¸ã¢ã³)ã«å¤æãããã®ã¨scaleã§turnArrowãå¼ã³åºãã¾ã
ããã§ä½¿ã£ãä¸ã¤ã®ã¡ã½ããã追å ãã¦ããã¾ãã
ï¼å
容ã解説ããã¨ç©çãæ°å¦ã®ãåå¼·ã«ãªã£ã¦ãã¾ãã®ã§ã説æã¯çç¥ãã¾ãã大å¦ã®ç©çãåå¼·ãç´ãã¾ãããâ大å¦çã®ããã® åå¦å
¥éï¼
func sub(p0: CGPoint, p1: CGPoint) -> CGPoint { return CGPoint(x: p0.x - p1.x, y: p0.y - p1.y) } func length(v: CGPoint) -> CGFloat { return sqrt(v.x * v.x + v.y * v.y) } func vector2radian(v: CGPoint) -> CGFloat { let len = length(v) let t = -v.y / v.x let c = v.x / len if v.x == 0 { return acos(c) } else { var angle = CGFloat(atan(t)) return angle + CGFloat(0 < v.x ? M_PI : 0.0) } }
æå¾ã«GameViewControllerãããã®ã·ã¼ã³ã表示ããããã«ãã¾ãã
var scene: GameScene! override func viewDidLoad() { super.viewDidLoad() let skView = view as SKView skView.multipleTouchEnabled = false scene = GameScene(size: skView.bounds.size) scene.scaleMode = .AspectFill skView.presentScene(scene) }
ããã§ä¸æ¦ãã²ã¼ã ãåããã¦ã¿ã¦ãç¢å°ã®åãã確èªãã¾ãããã
ç¢å°ã®åºå§ãããå転ã12æã®ä½ç½®ãééããæã®åä½ãå¤ã§ãããä½è£ãããã°æ¹ä¿®ãã¦ã¿ã¦ä¸ããã
é£ã°ã
SpriteKitã§ç»é¢è¦ç´ ãåããããã«ã¯ãã¢ãã¡ã¼ã·ã§ã³ã使ãæ¹æ³ã®ä»ã«ãç©çæ¼ç®ã使ããã¨ãã§ãã¾ãã
ç©çæ¼ç®ã§ç©ä½ãåããã¨ãè¡çªå¤å®ãªã©ãç°¡åã«ãªãã®ã§ããã£ã©ã¯ã¿ã¼ã®åä½ã«ã¯ãç©çæ¼ç®ã使ããã¨ã«ãã¾ãã
ã§ã¯ãGameScene.swiftãä¿®æ£ãã¾ãããã
次ã«ããã£ã©ã¯ã¿ã¼ã®ç©ä½ã¨ãã¦ã®ç¹å¾´ãè¨å®ããããã«ã
super.initå¼ã³åºãã®ä¸ã«ãã®ã³ã¼ãã追å ãã¾ãã
nantoka.physicsBody = SKPhysicsBody(circleOfRadius: 16) nantoka.physicsBody?.dynamic = true
- ç©çæ¼ç®ã®å¯¾è±¡ã«ããSKSpriteNodeã®physicsBodyããããã£ãè¨å®ãã¾ã
- physicsBody: ããããã£ãç©ä½ã¨ãã¦ã®å½¢ãæå®ããSKPhysicsBodyã«ãã¾ã
- dynamic: éåãè¡çªã«ãã£ã¦ç©ä½ãåããã©ãããæå®ãã¾ã
- true: åã
- false: åºå®ããã
ã·ã¼ã³ã®physicsWorldã®è¨å®ãããããã«ã
super.initå¼ã³åºãã®æ¬¡ã«ãã®ã³ã¼ãã追å ãã¾ãã
physicsWorld.gravity = CGVectorMake(0, 0)
- ä»åã®ã²ã¼ã ã§ã¯ããã£ã©ã¯ã¿ã¼ã®åãã«éåãèæ ®ããå¿ è¦ã¯ãªãã®ã§ãgravityã«ã¯ã¼ããã¯ãã«ãè¨å®ãã¦ããã¾ãã
GameViewController.swiftãéããdidPanã®ä¸ã®ã²ã£ã±ãçµäºã®ã³ã¼ããããã¯ã®ä¸ã«ããã®ã³ã¼ãã追å ãã¾ãã
scene.nantoka.physicsBody?.velocity = acceleration(currentPoint, point: panPointReference!)
- é度ãä¸ããããã«ãvelocityããããã£ã«CGVectorãè¨å®ãã¦ãã¾ã
ããã§ä½¿ã£ãaccelerationã¡ã½ããã追å ãã¦ããã¾ãããã
func acceleration(o: CGPoint, point: CGPoint) -> CGVector { let leverage = CGFloat(50) return CGVectorMake(leverage * (point.x - o.x), leverage * (o.y - point.y)) }
- ããã§ã¯ãå¼ã£ã±ãã表ããã¯ãã«ã®å¤§ããã50åã«ãããã®ãé度ã¨ãã¦ä¸ããããã«ãã¾ããã
ã§ã¯ãããã§ä¸æ¦ãé£ã°ãå¦çã®åä½ç¢ºèªããã¾ããã
ã¶ã¤ãã対象ã®è¿½å
ã¶ã¤ãã対象ã¨ãã¦å£ã追å ãã¾ãã
å£ã¯åãç¹å¾´ãæã£ãåã¤ã®ç©ä½ãä¸ä¸å·¦å³ã«é
ç½®ããã ããªã®ã§ãä¸ã¤ã®å£ã追å ããã¡ã½ãããç¨æãã¾ãã
ãã®ã³ã¼ããGameSceneã¯ã©ã¹ã«è¿½å ãã¾ãããã
func addWall(size: CGSize, position: CGPoint) { var wall: SKSpriteNode wall = SKSpriteNode(color: UIColor.brownColor(), size: size) wall.position = position wall.anchorPoint = CGPoint(x: 0, y: 0) wall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(size.width * 2, size.height * 2)) wall.physicsBody?.dynamic = false addChild(wall) }
ä¸ä¸å·¦å³ã®å£ã®å¤§ããã¨ä½ç½®ãæå®ãã¦ããã®ã¡ã½ãããå¼ã³åºãã°å£ã®è¿½å ã¯çµäºã§ãã
ããã§ãã¤ãã§ã«ãå¾ã»ã©å©ç¨ããæµãã£ã©ã®ã©ã¤ãå¤ã²ã¼ã¸ã追å ãã¦ããã¾ã
var enemyLifeGuage: SKSpriteNode let enemyLifeGuageBase: SKSpriteNode
- GameSceneã®ã¯ã©ã¹å¤æ°ã¨ãã¦ã©ã¤ãå¤ã®è¡¨ç¤ºã«ãªãenemyLifeGuageãå®ç¾©ãã¾ãã
- æµã©ã¤ãå¤ãæ¸ã£ãã¨ãã«é»å¡ããæ®ãããã«ããããã®ç»é¢è¦ç´ ã¨ãã¦enemyLifeGuageBaseã追å ãã¾ã
initã®ä¸ã§ãsuper.init(size: size)ã®ä¸ã«ãã®ã³ã¼ãã追å ãã¾ãã
nantoka.physicsBody?.usesPreciseCollisionDetection = true nantoka.physicsBody?.friction = 0 enemyLifeGuage = SKSpriteNode(color: UIColor.yellowColor(), size: CGSizeMake(size.width, 20)) enemyLifeGuage.position = CGPoint(x: 0, y: size.height - enemyLifeGuage.size.height) enemyLifeGuage.anchorPoint = CGPoint(x: 0, y: 0) let enemyLifeGuageBase = SKSpriteNode(color: UIColor.blackColor(), size: CGSizeMake(size.width, 20)) enemyLifeGuageBase.position = CGPoint(x: 0, y: size.height - enemyLifeGuage.size.height) enemyLifeGuageBase.anchorPoint = CGPoint(x: 0, y: 0)
- ã¯ã©ã¹å¤æ°/å®æ°ã¯ãsuper.initå¼ã³åºãããå
ã«åæåããå¿
è¦ãããã¾ã
- usesPreciseCollisionDetectionãtrueã«ãã¦ããã¨ã精度ã®é«ãè¡çªå¤å®ãè¡ãããããã«ãªãã¾ã
- èªãã£ã©ã®æ©æ¦ä¿æ°frictionãã¼ãã«ãã¦ããã¾ããè¡çªãæ¥è§¦ããã¨ãã«èªãã£ã©ããããããã¦ãã¾ããªãããã«ããããã§ãã
- sizeã¯ãã®ã·ã¼ã³ã®å¤§ãããå ¥ã£ã¦ããã®ã§ãç»é¢ã®ä¸ä¸å·¦å³ããã¤ãã¦ã²ã¼ã¸ãå£ãé ç½®ããããã«å©ç¨ãã¾ã
initã®ä¸ã§ãsuper.init(size: size)ã®ä¸ã«ãã®ã³ã¼ãã追å ãã¾ã
let wallThickness: CGFloat = 10 let fieldSize = CGSizeMake(size.width - wallThickness * 2, 400) let fieldBottomY = size.height - (enemyLifeGuage.size.height + wallThickness + fieldSize.height) // upper wall addWall(CGSize(width: fieldSize.width, height: wallThickness), position: CGPoint(x: wallThickness, y: enemyLifeGuage.position.y - wallThickness)) // bottom wall addWall(CGSizeMake(fieldSize.width, wallThickness), position: CGPoint(x: wallThickness, y: fieldBottomY - wallThickness)) // right wall addWall(CGSizeMake(wallThickness, fieldSize.height), position: CGPoint(x: wallThickness + fieldSize.width, y: fieldBottomY)) // left wall addWall(CGSizeMake(wallThickness, fieldSize.height), position: CGPoint(x: 0, y: fieldBottomY)) addChild(enemyLifeGuageBase) addChild(enemyLifeGuage)
- 親ã¯ã©ã¹ã®ããããã£ã«ã¢ã¯ã»ã¹ããããã«ã¯(ããã§ã¯addChild)ãsuper.initå¼ã³åºãå¾ã«æ¸ãå¿ è¦ãããã¾ã
- å£ã®åãwallThicknessã¨å£ãç´ã¾ãé åã®å¤§ããfieldSizeãå®ç¾©ãã¾ã
- é åã®å¹ ã¯ç»é¢ã´ã£ããã«ãã¦ãé«ãã¯é©å½ã«é¸ã³ã¾ãã
- SpriteKitã§ã¯ç»é¢å·¦ä¸ã座æ¨ã®åç¹(0,0)ãªã®ã§ãããã«åãããpositionã§ããããã®å£ãé ç½®ãã¦ãã¾ã
ã§ã¯ãã²ã¼ã ããããªã£ã¦ããã¨ããã§ãåä½ç¢ºèªããã¦ã¿ã¾ãããã
åãã¦ããéä¸ã§ãã¾ãã²ã£ã±ãã¡ãã£ãããã¾ãããããæ°ã®ãã人ã¯ãã®è¾ºã®å¶å¾¡ãå ¥ãã¦ã¿ã¦ä¸ããã
è·³ãè¿ãä½ç½®ãè¥å¹²ããããã§ãããåèªã§èª¿æ´ãã¦ã¿ã¦ä¸ããã
GameViewControllerã®viewDidLoadã¡ã½ããã®ä¸ã«ãã®ã³ã¼ãã追å ãã¦ããã¨ãç©ä½ã¨ãã¦ã®è¼ªéã表示ããã¾ãã
skView.showsPhysics = true
ä»ã«ãããããã°ã«å½¹ç«ã¤æ å ±ã表示ããããã«ããã®ãããªããããã£è¨å®ã追å ãã¦ããã¦ãããã§ãããã
skView.showsDrawCount = true skView.showsFPS = true skView.showsNodeCount = true skView.showsFields = true skView.showsQuadCount = true
æµãã£ã©ã¨æ¥è§¦æã®å¦çã追å ãã
å£ã«ã¶ã¤ãã£ãã¨ãã«ã¯åã«åå°ããã ãã§è¯ãã®ã«å¯¾ãã¦ã
æµã«ã¶ã¤ãã£ãã¨ãã«ã¯æµã®ã©ã¤ãå¤ãæ¸ããå¦çãå
¥ããå¿
è¦ãããã¾ãã
ããã§ã¯æ¥è§¦å¤å®ãå©ç¨ãã¦ããã®å®è£
ããã¾ãã
æ¥è§¦å¤å®ã¨è¡çªã¯ç¬ç«ããæ¦å¿µãªã®ã§ã
ç©ä½å士ãããæããã¨ãã«æ¥è§¦å¤å®ãè¡ããã¨ãåºæ¥ã¾ãã
ãã¨ãã°ããã£ã¼ã«ãã«é
ç½®ãããã¢ã¤ãã ãã²ããããæã«ã使ãã¾ãã
ããã§ãæµãã£ã©ãé ç½®ã®æºåããã¾ããã
- æµãã£ã©ç»åã¨ãã¦ãã®ç»åãenemy.pngã¨ããååã§ä¿åãã¦ä¸ãã
- èªãã£ã©ç»åã®åãè¾¼ã¿ã¨åãæé ã§åãè¾¼ã¿ã¾ã
æ¥è§¦å¤å®ã§ã¯ãã¾ããSpriteã®ã«ãã´ãªãè¨å®ãããã¨ã«ãªãã¾ãã
ã«ãã´ãªã¯æ¥è§¦ã®ç¸æãã¨ã«å¦çãåãæ¿ããããã®UInt32åã®å¤ã§ãã
ãã®ã³ã¼ããGameSceneã®ã¯ã©ã¹å¤æ°ã¨ãã¦è¿½å ãã¾ãããã
let categoryS: UInt32 = 0x1 << 0 let categoryE: UInt32 = 0x1 << 1 var enemyLifePoint = 100
- èªãã£ã©ãcategorySãæµãã£ã©ãcategoryEã¨ããã«ãã´ãªåãã«ãã¾ãã
- ãããæ¼ç®ãããã®ã§ãåããããåã¯ã©ã¹ã表ãããã«ãã¾ã
- ã¤ãã§ã«ãæµã®ã©ã¤ãå¤ã表ãã¯ã©ã¹å¤æ°ã追å ãã¦ããã¾ã
ã¯ã©ã¹ãæ¥è§¦ã«é¢ããå¦çãåãæã¤ãã¨ã示ãããã«ã次ã®ããã«ãã¯ã©ã¹ã«SKPhysicsContactDelegateãããã³ã«ã追å ãã¾ãã
class GameScene: SKScene, SKPhysicsContactDelegate {
ãã®ã³ã¼ããsuper.initå¼ã³åºãã®ä¸ã«å ¥ãã¾ãããã
physicsWorld.contactDelegate = self nantoka.physicsBody?.categoryBitMask = categoryS nantoka.physicsBody?.contactTestBitMask = categoryE let enemy = SKSpriteNode(imageNamed: "enemy") enemy.position = CGPoint(x: 160, y: 400) enemy.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(80, 80)) enemy.physicsBody?.dynamic = false enemy.physicsBody?.categoryBitMask = categoryE enemy.physicsBody?.contactTestBitMask = categoryS enemy.physicsBody?.usesPreciseCollisionDetection = true addChild(enemy)
- contactDelegateãselfã«è¨å®ãããã¨ã§ãæ¥è§¦ãå¤å®ãããã¨ãã«GameSceneã®didBeginContactãå¼ã³åºãããããã«ãªãã¾ã
- categoryBitMaskã«ã¯èªåã®ã«ãã´ãªã表ã
- collisionBitMaskã«è¡çªã®ç¸æã¨ãªãã«ãã´ãªã示ãå¤ãè¨å®ãã¾ãã
- è¤æ°ããå ´åã¯ã|ï¼ãããORæ¼ç®åï¼åºåãã§ä¸¦ã¹ã¾ã
contactTestBitMaskãè¨å®ããSKSpriteNodeãæ¥è§¦ããã¨å¼ã³åºãããdidBeginContactãå®ç¾©ãã¾ãã
ãã®ã³ã¼ããGameSceneã¯ã©ã¹ã«è¿½å ãã¾ãããã
func didBeginContact(contact: SKPhysicsContact) { println("didBeginContact") let (starBody, other) = contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask ? (contact.bodyA, contact.bodyB) : (contact.bodyB, contact.bodyA) switch other.categoryBitMask { case categoryE: enemyLifePoint -= 10 enemyLifeGuage.size = CGSizeMake(enemyLifeGuageBase.size.width * CGFloat(enemyLifePoint) / CGFloat(100.0), enemyLifeGuageBase.size.height) default: break // nothing to do } }
- å¼æ°ã®SKPhysicsContactã«ã¯æ¥è§¦ããäºã¤ã®ç©ä½ã表ãSKPhysicsBodyã®bodyAã¨bodyBã¨ãã¦æ¸¡ããã¾ãã
- ã©ã¡ããã©ã®ã«ãã´ãªã®ç©ä½ãªã®ãã¯äºãåããã¾ããã®ã§ãããããã®categoryBitMaskãå©ç¨ãã¦ãããããé©åãªå¤æ°ã«å
¥ãç´ãã¾ãã
- ä»åã¯æ¥è§¦ããçæ¹ãå¿
ãèªãã£ã©ã§ãããã¨ã¨ãèªãã£ã©ã®categoryBitMaskãä¸çªå°ããæ°å¤ã«å¯¾å¿ãã¦ãããã¨ãå©ç¨ãã¦ãã¾ãã
- èªãã£ã©ãnantokaBodyã«ãæ¥è§¦ç¸æãotherã«å ¥ãç´ãã¦ãã¾ãã
- ä»åã¯æ¥è§¦ããçæ¹ãå¿
ãèªãã£ã©ã§ãããã¨ã¨ãèªãã£ã©ã®categoryBitMaskãä¸çªå°ããæ°å¤ã«å¯¾å¿ãã¦ãããã¨ãå©ç¨ãã¦ãã¾ãã
- æ¥è§¦ç¸æã®ç¨®é¡ã«å¿ããå¦çã«ããããã«ãother.categoryBitMaskã§switchãã¦ãã¾ãã
- ä¾ãã°ãã¢ã¤ãã ãå°å ¥ãã¦ã²ããã®å¦çã追å ããå ´åãªã©ã«ã¯ãããã®caseãå¢ããã¦è¡ããã¨ã«ãªãã¾ãã
- æµã«æ¥è§¦ããå ´åã¯ãã¨ããããæµã©ã¤ãå¤ã10æ¸ãããã¨ã«ãã¾ãã
- ã©ã¤ãå¤ã®æ¸å°ã«åããã¦ãã©ã¤ãå¤ã²ã¼ã¸ã®è¡¨ç¤ºãå¤æ´ãã¾ã
å®æã§ãï¼
ããã§ã¨ããããã¾ãï¼
ã§ã¯ããã£ããâ+Rã§ã²ã¼ã ãèµ·åãã¦ãéãã§ã¿ã¾ããã
ãã£ã¨Sprite Kitãåå¼·ãã
ãããã«
ãç²ãæ§ã§ããï¼
çæ§ãé¢ç½ãã²ã¼ã ãéçºãã¦ã楽ãã人çãããããã£ããä½ãã«ãã®è¨äºãå½¹ç«ã¦ã°ãããã«åãåã³ã¯ããã¾ããã
Swiftã®è¨äºã®ã¾ã次ã®ãã¿ãä»è¾¼ã¿ä¸ã§ãã
ãã¨ãã
åæ¥ã«ä½æ¥ããã¦ãã¦ç²ãããããµãã£ã¨é»è»ã«ä¹ã£ã¦é©å½ãªè¡ã«æ£æ©ã«è¡ãã¾ãã
æåããæ£æ©è¡ãã¤ãããªãæ£æ©ã¬ã¤ãã§ãæã£ã¦è¡ããã§ããããµãã£ã¨è¡ãã¨ããå¤ãã®ã§ããããªã¢ããªã使ã£ã¦ãã¾ãã
https://itunes.apple.com/jp/app/supotto-jiantsukaru!fotopot/id813779149?mt=8&uo=4&at=10l8JW&ct=hatenablog
èªåã®å±
ãå ´æå¨è¾ºã§è©±é¡ã«ãªã£ã¦ããã¢ããåºãåãã£ã¦è¶
便å©ã§ãã
æ£æ©ã¬ã¤ãã¯è±èªã®åå¼·ãããã¦æ´æ¸ã使ãã¾ãã楽ããã§ãã