Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions Sources/GameWidget/Controller.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// File.swift
//
//
// Created by rrbox on 2022/08/30.
//

import GameplayKit
import Combine

public enum ControllerData {
public struct Direction: OptionSet {
public var rawValue: UInt8
public init(rawValue: UInt8) {
self.rawValue = rawValue
}

public static let up = Direction(rawValue: 0b0001)
public static let right = Direction(rawValue: 0b0010)
public static let down = Direction(rawValue: 0b0100)
public static let left = Direction(rawValue: 0b1000)
}

public struct Input {
public var weight: CGFloat
public var direction: Direction
}

public struct Name: Hashable {
let name: String
public init(_ name: String) {
self.name = name
}
}

public static var inputs = CurrentValueSubject<[Name: Input], Never>([Name: Input]())

}

/// クリックするとコントローラーが表示される領域
class ControllerAreaNode: SKSpriteNode {
let origin = SKShapeNode(circleOfRadius: 32)
let cursor = SKShapeNode(circleOfRadius: 20)

var id: ControllerData.Name!

// 原点からの距離を計算
func distanceOf(_ v: CGPoint) -> CGFloat {
sqrt(pow(v.x, 2)+pow(v.y, 2))
}

override var isUserInteractionEnabled: Bool {
get { true }
set {}
}

override func mouseDown(with event: NSEvent) {
self.origin.position = event.location(in: self)
self.cursor.position = .zero
self.addChild(self.origin)
}

override func mouseDragged(with event: NSEvent) {
let mouse = event.location(in: self.origin)
let d = distanceOf(mouse)
let restriction = CGPoint(x: (mouse.x/d)*32, y: (mouse.y/d)*32)
if d < 32 {
self.cursor.position = mouse
} else {
self.cursor.position = restriction
}

var resultDirection: ControllerData.Direction = []

if mouse.y > abs(2*mouse.x) {
resultDirection = .up
} else if mouse.x > abs(2*mouse.y) {
resultDirection = .right
} else if mouse.y < -abs(2*mouse.x) {
resultDirection = .down
} else if mouse.x < -abs(2*mouse.y) {
resultDirection = .left
} else if mouse.x > 0 && mouse.y > 0 {
resultDirection = [.up, .right]
} else if mouse.x > 0 && mouse.y < 0 {
resultDirection = [.right, .down]
} else if mouse.x < 0 && mouse.y < 0 {
resultDirection = [.down, .left]
} else if mouse.x < 0 && mouse.y > 0 {
resultDirection = [.left, .up]
}

ControllerData.inputs.value[self.id] = ControllerData.Input(weight: d, direction: resultDirection)
}

override func mouseUp(with event: NSEvent) {
self.origin.removeFromParent()
ControllerData.inputs.value[self.id]? = ControllerData.Input(weight: 0, direction: [])
}

}

public struct ControllerArea: Widget, MoveableItem {
var size: CGSize = CGSize(width: 100, height: 100)
public var position: CGPoint = .zero

var id: ControllerData.Name

public init(_ id: ControllerData.Name) {
self.id = id
}

public func node() -> SKNode {
let result = ControllerAreaNode(color: .black, size: self.size)
result.id = self.id
ControllerData.inputs.value[self.id] = ControllerData.Input(weight: 0, direction: [])
result.color = SKColor(red: 1, green: 1, blue: 1, alpha: 0.01)
result.origin.addChild(result.cursor)
result.position = self.position
return result
}

}

public extension ControllerArea {
func size(_ value: CGSize) -> Self {
var result = self
result.size = value
return result
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ public struct Node<Content: WidgetList>: NodeWidget, WidgetList {

public func node() -> SKNode {
let result = SKNode()

result.position = self.position
result.zRotation = self.zRotation
result.xScale = self.xScale
result.yScale = self.yScale

for i in self.content.widgetNodes() {
result.addChild(i)
}
Expand Down
18 changes: 15 additions & 3 deletions Tests/GameWidgetTests/GameWidgetTests.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import XCTest
@testable import GameWidget

final class GameWidgetTests: XCTestCase {
func testExample() throws {

final class NodeTests: XCTestCase {
func testModifiers() throws {
let node = Node {
Button(.init("test"))
}
.position(CGPoint(x: 1, y: 1))
.scale(2)
.zRotation(2)
.node()

XCTAssertEqual(node.position, CGPoint(x: 1, y: 1))
XCTAssertEqual(node.xScale, 2)
XCTAssertEqual(node.yScale, 2)
XCTAssertEqual(node.zRotation, 2)
XCTAssertEqual(node.children.count, 1)
}
}