5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOSAdvent Calendar 2022

Day 3

SpriteKitで2D横スクロールゲームをつくろう(その2)

Last updated at Posted at 2022-12-02

Xcode-14.1 iOS-16.0

はじめに

前回の続きです。

今回はステージを作っていきます。

素材準備

背景(ちょっと適切なサイズがわからない。。。)

background

床ブロック

tile_block

実装

今回も SKScene の実装のみです。今回は全部コードで実装してますが SpriteKit Scene などのファイルを追加すれば GUI でも操作可能です。

sprite_files editor

背景表示

背景を表示します。

final class GameScene: SKScene {

    override func didMove(to view: SKView) {
        let backNode = SKSpriteNode(imageNamed: "background")
        backNode.size = frame.size
        backNode.position = .init(x: frame.midX, y: frame.midY)
        addChild(backNode)
    }
}

こんな感じです。

background

床表示

SKTileMapNode を使って床を作ります。

final class GameScene: SKScene {

    private let tilePositions: [(column: Int, row: Int)] = [
        (0, 0), (0, 1),
        (1, 0), (1, 1),
        (2, 0), (2, 1),
        (3, 0), (3, 1),
        (4, 0), (4, 1),
        (5, 0), (5, 1),
        (6, 0), (6, 1), (6, 2),
        (7, 0), (7, 1), (7, 2), (7, 3),
        (8, 0), (8, 1),
        (9, 0), (9, 1),
        (10, 0), (10, 1),
        (11, 0), (11, 1),
        (12, 0), (12, 1),
        (13, 0), (13, 1),
        (14, 0), (14, 1),
        (15, 0), (15, 1),
        (16, 0), (16, 1),
        (17, 0), (17, 1),
        (18, 0), (18, 1),
        (19, 0), (19, 1),
        (20, 0), (20, 1),
        (21, 0), (21, 1),
        (22, 0), (22, 1),
        (23, 0), (23, 1),
        (24, 0), (24, 1),
        (25, 0), (25, 1),
        (26, 0), (26, 1),
        (27, 0), (27, 1),
        (28, 0), (28, 1),
        (29, 0), (29, 1),
        (30, 0), (30, 1),
        (31, 0), (31, 1),
        (32, 0), (32, 1),
        (33, 0), (33, 1),
        (34, 0), (34, 1),
        (35, 0), (35, 1),
        (36, 0), (36, 1),
        (37, 0), (37, 1),
        (38, 0), (38, 1),
        (39, 0), (39, 1),
        (40, 0), (40, 1),
        (41, 0), (41, 1),
        (42, 0), (42, 1),
        (43, 0), (43, 1),
        (44, 0), (44, 1),
        (45, 0), (45, 1),
        (46, 0), (46, 1),
        (47, 0), (47, 1),
        (48, 0), (48, 1),
        (49, 0), (49, 1),
    ]

    override func didMove(to view: SKView) {
        let tileSize = CGSize(width: 32, height: 32)
        let group = SKTileGroup(tileDefinition: .init(texture: .init(imageNamed: "tile_block"), size: tileSize))
        let tileSet = SKTileSet(tileGroups: [group])
        let tileMap = SKTileMapNode(tileSet: tileSet, columns: tilePositions.last!.column + 1, rows: 4, tileSize: tileSize)
        tilePositions.forEach {
            tileMap.setTileGroup(group, forColumn: $0.column, row: $0.row)
        }
        tileMap.position = .zero
        tileMap.anchorPoint = .zero
        addChild(tileMap)

        // physicsBody設定
        tilePositions.forEach {
            let node = SKSpriteNode()
            node.position = .init(x: CGFloat($0.column) * tileSize.width + tileSize.width/2,
                                  y: CGFloat($0.row) * tileSize.height + tileSize.height/2)
            node.physicsBody = .init(rectangleOf: tileSize)
            node.physicsBody?.isDynamic = false
            tileMap.addChild(node)
        }
    }
}

こんな感じです。

floor

ちょっと解説。tilePositions がタイルの位置を表していて(0, 0)が左下のタイルになります。下記で設定する columnsrows は横と縦の最大値になります。今回は横に 50, 縦に(最大で)4 並べるのでその数値をそれぞれ設定しています。

let tileMap = SKTileMapNode(tileSet: tileSet, columns: tilePositions.last!.column + 1, rows: 4, tileSize: tileSize)

下記の設定は床を画面の左下起点に置きたかったのでそれぞれ .zero を設定しています。

tileMap.position = .zero
tileMap.anchorPoint = .zero

下記の処理は SKTileMapNode にいい感じに physicsBody を設定する方法がない(たぶん)のでタイル1つ1つに physicsBody 設定しています。

tilePositions.forEach {
    let node = SKSpriteNode()
    node.position = .init(x: CGFloat($0.column) * tileSize.width + tileSize.width/2,
                          y: CGFloat($0.row) * tileSize.height + tileSize.height/2)
    node.physicsBody = .init(rectangleOf: tileSize)
    node.physicsBody?.isDynamic = false
    tileMap.addChild(node)
}

おわりに

前回のと合わせるとこんな感じになります。

game

偶然にもどこかでみたことのあるようなステージになってしまいました:open_mouth:

次回は横スクロールできるようにします!

SpriteKit あまりさわったことないのでもっといい方法あればぜひ教えて下さい:bow:

まとめ

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?