Tetris/Tetris/ContentView.swift

130 lines
4.3 KiB
Swift

//
// ContentView.swift
// Tetris
//
// Created by Shadowfacts on 10/14/19.
// Copyright © 2019 Shadowfacts. All rights reserved.
//
import SwiftUI
import TetrisKit
import TetrisUI
struct ContentView: View {
@ObservedObject var controller: GameController = {
let c = GameController()
c.start()
return c
}()
@State var timer: Timer?
@State var prevHorizTranslation: CGFloat?
var body: some View {
GeometryReader { (geometry) in
VStack {
BoardView(board: self.$controller.board, currentPiece: self.$controller.currentPiece, droppedPiece: self.$controller.currentPieceAtDropPoint)
.aspectRatio(CGSize(width: 10, height: 16), contentMode: .fit)
.onAppear(perform: self.startTimer)
.onDisappear(perform: self.stopTimer)
.onTapGesture(perform: self.onTap)
.gesture(self.horizDragGesture(geometry: geometry))
// .gesture(ExclusiveGesture(horizDragGesture, verticalDragGesture))
// .gesture(horizDragGesture.simultaneously(with: verticalDragGesture))
HStack {
Button(action: self.onTap) {
Image(systemName: "goforward").resizable().frame(width: 50, height: 50)
}
}
HStack {
Button(action: self.controller.left) {
Image(systemName: "arrow.left.square.fill").resizable().frame(width: 50, height: 50)
}
Spacer()
Button(action: self.controller.drop) {
Image(systemName: "arrow.down.square.fill").resizable().frame(width: 50, height: 50)
}
Spacer()
Button(action: self.controller.right) {
Image(systemName: "arrow.right.square.fill").resizable().frame(width: 50, height: 50)
}
}
}
}
}
func horizDragGesture(geometry: GeometryProxy) -> some Gesture {
DragGesture(coordinateSpace: .global)
.onChanged { (state) in
guard let currentPiece = self.controller.currentPiece else { return }
// let position = (state.location.x) / geometry.size.width * 10
// let moved = currentPiece.moved(by: (Int(position.rounded()) - currentPiece.topLeft.0, 0))
// if !self.controller.overlapsAny(moved) {
// self.controller.currentPiece = moved
// }
if self.prevHorizTranslation == nil {
self.prevHorizTranslation = state.translation.width
}
let delta = state.translation.width - self.prevHorizTranslation!
let amount = Int((delta / 20).rounded())
let moved = currentPiece.moved(by: (amount, 0))
if !self.controller.overlapsAny(moved) {
self.controller.currentPiece = moved
self.prevHorizTranslation = state.translation.width
}
}.onEnded { (state) in
self.prevHorizTranslation = nil
}
}
var verticalDragGesture: some Gesture {
DragGesture()
.onEnded { (state) in
let deltaY = state.location.y - state.startLocation.y
if abs(deltaY) > 40 {
if deltaY > 0 {
self.onSwipeDown()
} else {
self.onSwipeUp()
}
}
}
}
func startTimer() {
self.timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { (_) in
self.controller.step()
}
}
func stopTimer() {
timer?.invalidate()
}
func onTap() {
self.controller.rotate(direction: .clockwise)
}
func onSwipeLeft() {
self.controller.left()
}
func onSwipeRight() {
self.controller.right()
}
func onSwipeUp() {
// hold
}
func onSwipeDown() {
self.controller.drop()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}