mirror of
https://github.com/ivanvorobei/SwiftUI.git
synced 2026-04-11 03:27:12 +02:00
Add 2048 Game
This commit is contained in:
116
Examples/2048 Game/SwiftUI2048/Views/BlockGridView.swift
Executable file
116
Examples/2048 Game/SwiftUI2048/Views/BlockGridView.swift
Executable file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// BlockGridView.swift
|
||||
// SwiftUI2048
|
||||
//
|
||||
// Created by Hongyu on 6/5/19.
|
||||
// Copyright © 2019 Cyandev. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
fileprivate struct IdentifiableIndexedBlock : Identifiable {
|
||||
|
||||
typealias ID = String
|
||||
typealias IdentifiedValue = IndexedBlock<IdentifiedBlock>
|
||||
|
||||
static var uniqueBlankId = 0
|
||||
|
||||
let indexedBlock: IndexedBlock<IdentifiedBlock>
|
||||
|
||||
var id: Self.ID {
|
||||
if let id = indexedBlock.item?.id {
|
||||
return "\(id)"
|
||||
}
|
||||
|
||||
// TODO: (Refactor) Don't mix two types of block views.
|
||||
IdentifiableIndexedBlock.uniqueBlankId += 1
|
||||
return "Blank_\(IdentifiableIndexedBlock.uniqueBlankId)"
|
||||
}
|
||||
|
||||
var identifiedValue: Self.IdentifiedValue {
|
||||
return indexedBlock
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension AnyTransition {
|
||||
|
||||
static func blockAppear(from: Edge) -> AnyTransition {
|
||||
return .asymmetric(
|
||||
insertion: AnyTransition.opacity
|
||||
.combined(with: .move(edge: from)),
|
||||
removal: .identity)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct BlockGridView : View {
|
||||
|
||||
typealias SupportingMatrix = BlockMatrix<IdentifiedBlock>
|
||||
|
||||
let matrix: Self.SupportingMatrix
|
||||
let blockEnterEdge: Edge
|
||||
|
||||
func createBlock(_ block: IdentifiedBlock?) -> some View {
|
||||
if let block = block {
|
||||
return BlockView(number: block.number)
|
||||
}
|
||||
return BlockView.blank()
|
||||
}
|
||||
|
||||
// FIXME: This is existed as a workaround for a Swift compiler bug.
|
||||
func zIndex(_ block: IdentifiedBlock?) -> Double {
|
||||
if block == nil {
|
||||
return 1
|
||||
}
|
||||
return 1000
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
ForEach(
|
||||
self.matrix.flatten.map { IdentifiableIndexedBlock(indexedBlock: $0) }
|
||||
) { block in
|
||||
self.createBlock(block.item)
|
||||
.frame(width: 65, height: 65, alignment: .center)
|
||||
.position(x: CGFloat(block.index.0) * (65 + 12) + 32.5 + 12,
|
||||
y: CGFloat(block.index.1) * (65 + 12) + 32.5 + 12)
|
||||
.zIndex(self.zIndex(block.item))
|
||||
.transition(.blockAppear(from: self.blockEnterEdge))
|
||||
.animation(block.item == nil ? nil : .spring(mass: 1, stiffness: 400, damping: 56, initialVelocity: 0))
|
||||
}
|
||||
}
|
||||
.frame(width: 320, height: 320, alignment: .center)
|
||||
.background(
|
||||
Rectangle()
|
||||
.fill(Color(red:0.72, green:0.66, blue:0.63, opacity:1.00))
|
||||
)
|
||||
.clipped()
|
||||
.cornerRadius(6)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
struct BlockGridView_Previews : PreviewProvider {
|
||||
|
||||
static var matrix: BlockGridView.SupportingMatrix {
|
||||
var _matrix = BlockGridView.SupportingMatrix()
|
||||
_matrix.place(IdentifiedBlock(id: 1, number: 2), to: (2, 0))
|
||||
_matrix.place(IdentifiedBlock(id: 2, number: 2), to: (3, 0))
|
||||
_matrix.place(IdentifiedBlock(id: 3, number: 8), to: (1, 1))
|
||||
_matrix.place(IdentifiedBlock(id: 4, number: 4), to: (2, 1))
|
||||
_matrix.place(IdentifiedBlock(id: 5, number: 512), to: (3, 3))
|
||||
_matrix.place(IdentifiedBlock(id: 6, number: 1024), to: (2, 3))
|
||||
_matrix.place(IdentifiedBlock(id: 7, number: 16), to: (0, 3))
|
||||
_matrix.place(IdentifiedBlock(id: 8, number: 8), to: (1, 3))
|
||||
return _matrix
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
BlockGridView(matrix: matrix, blockEnterEdge: .top)
|
||||
.previewLayout(.sizeThatFits)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user