Shapes now have fixed per-shape colors, not random
This commit is contained in:
parent
26b5a015d2
commit
934387dfff
|
@ -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"/>
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user