// // 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 initialXPosition: Int? var body: some View { GeometryReader { (geometry) in VStack { HStack { VStack(spacing: 0) { Text("Held") if self.controller.heldTetromino != nil { Group { TetrominoView(tetromino: self.controller.heldTetromino!) }.frame(width: 50, height: 50, alignment: .center) } else { Rectangle().foregroundColor(.clear).frame(width: 50, height: 50) } } } BoardView(board: self.$controller.board, currentPiece: self.$controller.currentPiece, droppedPiece: self.$controller.currentPieceAtDropPoint) .aspectRatio(CGSize(width: self.controller.width, height: self.controller.height), contentMode: .fit) .onAppear(perform: self.startTimer) .onDisappear(perform: self.stopTimer) .onTapGesture(perform: self.onTap) .gesture(self.horizDragGesture(geometry: geometry).simultaneously(with: self.verticalDragGesture)) // .gesture(ExclusiveGesture(horizDragGesture, verticalDragGesture)) // .gesture(horizDragGesture.simultaneously(with: verticalDragGesture)) HStack { Spacer() Button(action: self.controller.hold) { Image(systemName: "arrow.up.square.fill").resizable().frame(width: 50, height: 50) } Spacer() Button(action: self.onTap) { Image(systemName: "goforward").resizable().frame(width: 50, height: 50) } Spacer() } 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 } if self.initialXPosition == nil { self.initialXPosition = currentPiece.topLeft.0 } var moved = currentPiece let xPosition = self.initialXPosition! + Int((state.translation.width / (geometry.size.width / 10)).rounded()) moved.topLeft = (xPosition, currentPiece.topLeft.1) if !self.controller.overlapsAny(moved) { self.controller.currentPiece = moved } }.onEnded { (state) in self.initialXPosition = nil } } var verticalDragGesture: some Gesture { DragGesture() .onEnded { (state) in if abs(state.translation.height) > 80 { if state.translation.height > 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() { self.controller.hold() } func onSwipeDown() { self.controller.drop() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }