Shapes now have fixed per-shape colors, not random

This commit is contained in:
Amy G. Bowersox 2020-05-27 14:56:59 -06:00
parent 26b5a015d2
commit 934387dfff
11 changed files with 55 additions and 22 deletions

View File

@ -16,21 +16,21 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rZI-CB-OQn"> <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rZI-CB-OQn">
<rect key="frame" x="264" y="250" width="84" height="100"/> <rect key="frame" x="310" y="315" width="84" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="whitebg" translatesAutoresizingMaskIntoConstraints="NO" id="2kD-q4-jVs"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="whitebg" translatesAutoresizingMaskIntoConstraints="NO" id="2kD-q4-jVs">
<rect key="frame" x="0.0" y="0.0" width="84" height="100"/> <rect key="frame" x="0.0" y="0.0" width="84" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="SCORE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="InR-1s-zXh"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SCORE" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="InR-1s-zXh">
<rect key="frame" x="7" y="20" width="70" height="21"/> <rect key="frame" x="7" y="20" width="70" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Avenir-Black" family="Avenir" pointSize="15"/> <fontDescription key="fontDescription" name="Avenir-Black" family="Avenir" pointSize="15"/>
<color key="textColor" red="0.13333333333333333" green="0.6470588235294118" blue="0.82745098039215681" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="0.13333333333333333" green="0.6470588235294118" blue="0.82745098039215681" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="999" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Zja-c9-zBQ"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="999" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Zja-c9-zBQ">
<rect key="frame" x="0.0" y="45" width="84" height="39"/> <rect key="frame" x="0.0" y="45" width="84" height="39"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Avenir-Light" family="Avenir" pointSize="35"/> <fontDescription key="fontDescription" name="Avenir-Light" family="Avenir" pointSize="35"/>
@ -40,21 +40,21 @@
</subviews> </subviews>
</view> </view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5g3-e3-yLO"> <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5g3-e3-yLO">
<rect key="frame" x="264" y="417" width="84" height="100"/> <rect key="frame" x="310" y="482" width="84" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="whitebg" translatesAutoresizingMaskIntoConstraints="NO" id="nRI-Ry-bjG"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="whitebg" translatesAutoresizingMaskIntoConstraints="NO" id="nRI-Ry-bjG">
<rect key="frame" x="0.0" y="0.0" width="84" height="100"/> <rect key="frame" x="0.0" y="0.0" width="84" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="LEVEL" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Boc-bL-hFe"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LEVEL" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Boc-bL-hFe">
<rect key="frame" x="7" y="20" width="70" height="21"/> <rect key="frame" x="7" y="20" width="70" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Avenir-Black" family="Avenir" pointSize="15"/> <fontDescription key="fontDescription" name="Avenir-Black" family="Avenir" pointSize="15"/>
<color key="textColor" red="0.54509803921568623" green="0.45490196078431372" blue="0.76078431372549016" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="0.54509803921568623" green="0.45490196078431372" blue="0.76078431372549016" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="999" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="G8x-d8-J4Q"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="999" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="G8x-d8-J4Q">
<rect key="frame" x="0.0" y="45" width="84" height="39"/> <rect key="frame" x="0.0" y="45" width="84" height="39"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Avenir-Light" family="Avenir" pointSize="35"/> <fontDescription key="fontDescription" name="Avenir-Light" family="Avenir" pointSize="35"/>

View File

@ -35,10 +35,6 @@ enum BlockColor: Int, CustomStringConvertible, CaseIterable {
var description: String { var description: String {
return self.spriteName return self.spriteName
} }
static func random() -> BlockColor {
return BlockColor.allCases.shuffled().first!
}
} }
// Represents a single block in the game. // Represents a single block in the game.

View File

@ -31,25 +31,31 @@ class GameScene: SKScene {
override init(size: CGSize) { override init(size: CGSize) {
super.init(size: size) super.init(size: size)
print("Init scene with size \(size)") //print("Init scene with size \(size)")
textureAtlas = SKTextureAtlas(named: "Sprites") textureAtlas = SKTextureAtlas(named: "Sprites")
anchorPoint = CGPoint(x: 0, y: 1.0) anchorPoint = CGPoint(x: 0, y: 1.0)
let background = SKSpriteNode(imageNamed: "background") let background = SKSpriteNode(imageNamed: "background")
print("Background is sized \(background.size)") //print("Background is sized \(background.size)")
// Scale computations
let scaleFactor = min(size.width / background.size.width, size.height / background.size.height)
background.position = CGPoint(x: 0, y: 0) background.position = CGPoint(x: 0, y: 0)
background.anchorPoint = CGPoint(x: 0, y: 1.0) background.anchorPoint = CGPoint(x: 0, y: 1.0)
background.setScale(scaleFactor)
addChild(background) addChild(background)
gameLayer.setScale(scaleFactor)
addChild(gameLayer) addChild(gameLayer)
// Load and add the game board and shape layer
let gameBoardTexture = SKTexture(imageNamed: "gameboard") let gameBoardTexture = SKTexture(imageNamed: "gameboard")
let gameBoard = SKSpriteNode(texture: gameBoardTexture, size: CGSize(width: BlockSize * CGFloat(NumColumns), height: BlockSize * CGFloat(NumRows))) let gameBoard = SKSpriteNode(texture: gameBoardTexture, size: CGSize(width: BlockSize * CGFloat(NumColumns), height: BlockSize * CGFloat(NumRows)))
gameBoard.anchorPoint = CGPoint(x: 0, y: 1.0) gameBoard.anchorPoint = CGPoint(x: 0, y: 1.0)
gameBoard.position = LayerPosition gameBoard.position = LayerPosition
shapeLayer.position = LayerPosition shapeLayer.position = LayerPosition
shapeLayer.addChild(gameBoard) shapeLayer.addChild(gameBoard)
gameLayer.addChild(shapeLayer) gameLayer.addChild(shapeLayer)

View File

@ -31,6 +31,10 @@ class JShape: Shape {
*/ */
// Rotates around block #1 // Rotates around block #1
override var color: BlockColor? {
return .Blue
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(1, 0), (1, 1), (1, 2), (0, 2)], Orientation.Zero: [(1, 0), (1, 1), (1, 2), (0, 2)],

View File

@ -32,6 +32,10 @@ class LShape: Shape {
*/ */
// Pivots about block #1 // Pivots about block #1
override var color: BlockColor? {
return .Green
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(0, 0), (0, 1), (0, 2), (1, 2)], Orientation.Zero: [(0, 0), (0, 1), (0, 2), (1, 2)],

View File

@ -22,6 +22,10 @@ class LineShape: Shape {
*/ */
// Hinges about the second block // Hinges about the second block
override var color: BlockColor? {
return .Teal
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(0, 0), (0, 1), (0, 2), (0, 3)], Orientation.Zero: [(0, 0), (0, 1), (0, 2), (0, 3)],

View File

@ -21,6 +21,10 @@ class SShape: Shape {
* marks the row/column indicator for the shape * marks the row/column indicator for the shape
*/ */
override var color: BlockColor? {
return .Purple
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(0, 0), (0, 1), (1, 1), (1, 2)], Orientation.Zero: [(0, 0), (0, 1), (1, 1), (1, 2)],

View File

@ -9,8 +9,6 @@
import Foundation import Foundation
import SpriteKit import SpriteKit
//let NumOrientations: UInt32 = 4
// Represents the orientation of a shape in increments of 90 degrees // Represents the orientation of a shape in increments of 90 degrees
enum Orientation: Int, CustomStringConvertible, CaseIterable { enum Orientation: Int, CustomStringConvertible, CaseIterable {
case Zero = 0, Ninety, OneEighty, TwoSeventy case Zero = 0, Ninety, OneEighty, TwoSeventy
@ -56,9 +54,6 @@ let FourthBlockIdx: Int = 3
// Base class representing a shape consisting of four blocks. Derived classes represent the different // Base class representing a shape consisting of four blocks. Derived classes represent the different
// tetramino shapes. // tetramino shapes.
class Shape: Hashable, CustomStringConvertible { class Shape: Hashable, CustomStringConvertible {
// The color of the shape
let color: BlockColor
// The blocks comprising the shape // The blocks comprising the shape
var blocks = Array<Block>() var blocks = Array<Block>()
// The current orientation of the shape // The current orientation of the shape
@ -68,6 +63,12 @@ class Shape: Hashable, CustomStringConvertible {
// Required overrides // Required overrides
// Subclasses must override this property
// The color of the shape
var color: BlockColor? {
return nil
}
// Subclasses must override this property // Subclasses must override this property
// Returns the relative positions of the shape blocks based on the shape orientation // Returns the relative positions of the shape blocks based on the shape orientation
var blockRowColumnPositions: [Orientation: Array<(columnDiff: Int, rowDiff: Int)>] { var blockRowColumnPositions: [Orientation: Array<(columnDiff: Int, rowDiff: Int)>] {
@ -102,11 +103,13 @@ class Shape: Hashable, CustomStringConvertible {
// CustomStringConvertible // CustomStringConvertible
var description: String { var description: String {
guard let color = color else {
return "<invalid color> block facing \(orientation): \(blocks[FirstBlockIdx]), \(blocks[SecondBlockIdx]), \(blocks[ThirdBlockIdx]), \(blocks[FourthBlockIdx])"
}
return "\(color) block facing \(orientation): \(blocks[FirstBlockIdx]), \(blocks[SecondBlockIdx]), \(blocks[ThirdBlockIdx]), \(blocks[FourthBlockIdx])" return "\(color) block facing \(orientation): \(blocks[FirstBlockIdx]), \(blocks[SecondBlockIdx]), \(blocks[ThirdBlockIdx]), \(blocks[FourthBlockIdx])"
} }
init(column: Int, row: Int, color: BlockColor, orientation: Orientation) { init(column: Int, row: Int, orientation: Orientation) {
self.color = color
self.column = column self.column = column
self.row = row self.row = row
self.orientation = orientation self.orientation = orientation
@ -114,7 +117,7 @@ class Shape: Hashable, CustomStringConvertible {
} }
convenience init(column: Int, row: Int) { convenience init(column: Int, row: Int) {
self.init(column: column, row: row, color: BlockColor.random(), orientation: Orientation.random()) self.init(column: column, row: row, orientation: Orientation.random())
} }
// Initialize the blocks of the shape based on the current position, color, and orientation. // Initialize the blocks of the shape based on the current position, color, and orientation.
@ -124,7 +127,7 @@ class Shape: Hashable, CustomStringConvertible {
} }
blocks = blockRowColumnTranslations.map { (diff) -> Block in blocks = blockRowColumnTranslations.map { (diff) -> Block in
return Block(column: column + diff.columnDiff, row: row + diff.rowDiff, color: color) return Block(column: column + diff.columnDiff, row: row + diff.rowDiff, color: color!)
} }
} }

View File

@ -16,6 +16,10 @@ class SquareShape: Shape {
*/ */
// The square shape wll not rotate // The square shape wll not rotate
override var color: BlockColor? {
return .Red
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(0, 0), (1, 0), (0, 1), (1, 1)], Orientation.Zero: [(0, 0), (1, 0), (0, 1), (1, 1)],

View File

@ -31,6 +31,10 @@ class TShape: Shape {
* marks the row/column indicator for the shape * marks the row/column indicator for the shape
*/ */
override var color: BlockColor? {
return .Yellow
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(1, 0), (0, 1), (1, 1), (2, 1)], Orientation.Zero: [(1, 0), (0, 1), (1, 1), (2, 1)],

View File

@ -21,6 +21,10 @@ class ZShape: Shape {
* marks the row/column indicator for the shape * marks the row/column indicator for the shape
*/ */
override var color: BlockColor? {
return .Orange
}
override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] {
return [ return [
Orientation.Zero: [(1, 0), (1, 1), (0, 1), (0, 2)], Orientation.Zero: [(1, 0), (1, 1), (0, 1), (0, 2)],