質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.46%

  • iOS

    2881questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

SpriteKit: アイテムを一定時間に出現させるには?

解決済

回答 1

投稿 2016/07/27 07:04

  • 評価
  • クリップ 0
  • VIEW 362

rockbooker

score 0

前提・実現したいこと

初投稿失礼します。
現在SwiftとSpriteKitを使った2Dゲームを作成しております。
そこで一定時間が経過したらハートをフィールドに出現させる方法を考えています。
よくApp Storeなどの放置ゲームなどで実装されているようなものです。
またプレイヤーが再度ゲームを開いたら経過時間に応じたハートがすでに出現しているという状況にしたいと思っております。
必死に考えたのですが、どうしても、どうしても解決できなかったので質問させていただきました。
見にくいコードかとは思いますが、どうかよろしくお願いいたします。
ソースでなくても考え方だけでもどうかお願い致します。

該当のソースコード

// ハート配置関数の初期化
let settingHearts = setHeart()

if numberOfHearts != HeartsMax {
    self.heartTimer = NSTimer.scheduledTimerWithTimeInterval(20, target: self, 
                     selector: #selector(GameScene.settingHearts), userInfo: nil, repeats: true)
}


// 省略

    /// まだ存在していない場所にハートを出現させる
    func setHeart() -> (Void) -> Void {
        let heartMax = 20       // フィールドに存在できるハートの上限
        var currentHeartCnt = self.hearts.count

        let texture = SKTexture(imageNamed: "Heart")

        // 上限に達したらそのままリターン
        if currentHeartCnt == heartMax { return { _ in return Void() } }

        // フィールドに出現するハートの位置を指定
        func makingHeartPosition() -> [CGPoint] {
            // 画面を元に座標を求めるための倍率を格納
            let XPos = [0.3, 0.4, 0.5, 0.6, 0.7]
            let YPos = [0.45, 0.55, 0.65, 0.75]

            var heartPositions: [CGPoint] = []
            for y in YPos {
                for x in XPos {
                    let p = CGPoint(x: self.size.width * CGFloat(x), y: self.size.height * CGFloat(y))
                    heartPositions.append(p)
                }
            }

            return heartPositions
        }

        let heartPositions = makingHeartPosition()

        func closure() {
            let heart = SKSpriteNode(texture: texture)

            var index: Int = 20
            // メモに含まれている添字をロードした場合はやり直す
            while true {
                index = (Int)(arc4random_uniform(20))
                if self.heartMemo.contains(index) {
                    continue
                } else {
                    break
                }
            }
            // 引き当てた添字はメモ
            self.heartMemo.append(index)

            heart.position = heartPositions[index]
            heart.zPosition = -5
            heart.name = "heart\(index)"
            heart.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
            heart.physicsBody?.dynamic = false
            heart.physicsBody?.resting = true
            heart.physicsBody?.allowsRotation = true
            heart.physicsBody?.contactTestBitMask = 1
            heart.physicsBody?.restitution = 1.0
            heart.physicsBody?.friction = 1.0


            let scaleUp = SKAction.scaleTo(1.5, duration: 1.0)
            let scaleDw = SKAction.scaleTo(1.0, duration: 1.0)
            let scaleUpDown = SKAction.sequence([scaleUp, scaleDw])
            heart.runAction(SKAction.repeatActionForever(scaleUpDown))

            hearts.append(heart)
            self.addChild(heart)


        }

        return closure

    }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

解決しました。お騒がせしました!!!!

// 末尾のBool値でフィールドに出現しているか否かを判断する
var hearts = [Int : (SKSpriteNode, CGPoint, Bool)]()


// 省略

 /// ハートの初期化処理
    func setFirstHeart() {


        // フィールドに出現するハートの位置を指定
        func makingHeartPosition() -> [CGPoint] {
            // 画面を元に座標を求めるための倍率を格納
            let XPos = [0.3, 0.4, 0.5, 0.6, 0.7]
            let YPos = [0.45, 0.55, 0.65, 0.75]

            var heartPositions: [CGPoint] = []
            for y in YPos {
                for x in XPos {
                    let p = CGPoint(x: self.size.width * CGFloat(x), y: self.size.height * CGFloat(y))
                    heartPositions.append(p)
                }
            }

            return heartPositions
        }

        // 20個のハートのそれぞれの位置が格納された配列
        let heartPositions = makingHeartPosition()
        let texture = SKTexture(imageNamed: "Heart")

        for i in 0...19 {
            let heart = makeHeart(texture)
            heart.position = heartPositions[i]
            heart.name = "heart\(i)"
            hearts[i] = (heart, heart.position, true)
            self.addChild(heart)

        }
    }

    // 一つのハートを生成する処理
    func makeHeart(texture: SKTexture) -> SKSpriteNode {
        let heart = SKSpriteNode(texture: texture)
        heart.physicsBody = SKPhysicsBody(texture: texture, size: texture.size())
        heart.physicsBody?.dynamic = false
        heart.physicsBody?.resting = true
        heart.physicsBody?.allowsRotation = true
        heart.physicsBody?.contactTestBitMask = 1
        heart.physicsBody?.restitution = 1.0
        heart.physicsBody?.friction = 1.0

        let scaleUp = SKAction.scaleTo(1.5, duration: 1.0)
        let scaleDw = SKAction.scaleTo(1.0, duration: 1.0)
        let scaleUpDown = SKAction.sequence([scaleUp, scaleDw])
        heart.runAction(SKAction.repeatActionForever(scaleUpDown))


        return heart
    }


    /// ハートを消す処理
    func removeHeart() {


    }


    /// ハートを出現させる処理
    func appearHeart() {
        let texture = SKTexture(imageNamed: "Heart")

        for i in 0...19 {
            if hearts[i]!.2 == false {
                hearts[i]!.0 = makeHeart(texture)
                hearts[i]!.0.position = hearts[i]!.1
                hearts[i]!.0.name = "heart\(i)"
                // 再度登録
                hearts[i]!.2 = true
                self.addChild(hearts[i]!.0)
                return
            }
        }
    }
}

投稿 2016/07/27 09:48

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.46%

関連した質問

  • 解決済

    swiftで分割した画像をSKShapeNodeに貼り付けたい

    お世話になります。 swiftで一枚の画像を3x3の画像に分割して、9つ(3x3)のSKShapeNode(四角形)のTextureに設定したいです。 以下のサイトで実

  • 解決済

    Swift2, SpriteKitのSKActionについて質問です

    問題を出題して、違う答えをタップしたら ×と表示させて、その後消える。 と言った動きをしたいのですが、上手くいきません。 最初の一回目は上手くできるのですが、2回目以降が上手く

  • 解決済

    SKActionが終わった後に何か動作をさせたい時

    SKActionが実行され、そのアクションが終わった時に呼ばれる関数というものは存在しますか?

  • 解決済

    UIButtonのカスタムクラスで、ボタンをおいているViewの座標を取得したい

    UIButtonのカスタムクラスで、6角形のボタンを作ろうとしています。 ストーリーボードでボタンを置き、そのクラスを下記のカスタムクラスに設定してます。親ビューの(0,0)の位

  • 解決済

    touchesBeganが動作しない

    Swift Playgroundで以下のようなプログラムを作成しています(前に質問させていただいたものと同じです) import UIKit import SpriteKit

  • 解決済

    xcodeでシミュレータに表示されない

    連投になってしまって申し訳御座いません。前回の質問がまだ解決していないのにベストアンサーをつけてしまい解決済みになってしまいました。本格的に使うのは初めてでして何分ご容赦を。

  • 解決済

    SpriteKitによる画像のドラッグ

    swift SpriteKit で画像を横にスライドした分だけx軸方向にスライドさせるプログラムを組みたいです。画像は表示されるのですが画像をドラッグすることができません。何が足り

  • 解決済

    敵が表示されない

    無限に敵が上から出てくるプログラムを組みたいです。このままビルドすると背景は表示されるのですが、敵が表示されません。しかも無限に繰り返せるか微妙です。どうしたら良いですか?

同じタグがついた質問を見る

  • iOS

    2881questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。