目前,我正在开发一款新游戏,其中有一个名为background
的SKTileMapNode,作为供角色在各个瓷砖之间行走的游乐场。除此之外,我还有一个名为objects
的SKTileMapNode,它显示在background
(z方向)的顶部,在这里我对于树或岩石等字符的移动有不同的障碍。 “我的场景”包含一个光标和一个游戏控制器,并带有上,下,左,右,A和B按钮。
我已经实现了逻辑,可以将光标移动到字符上方并选择它。选择之后,如果没有障碍物,我可以选择平铺以移动所选角色。至此一切都按需进行。
我现在想要的是实现一种方法,使玩家在选择角色后能够看到箭头,从而显示角色必须走到的瓷砖,然后才能将光标移至当前光标所在的瓷砖,然后再选择该瓷砖作为目标。
我的想法是为object
创建我自己的SKTileGroupRule或在两者之上创建一个新的SKTileMapNode,它们会自动选择正确的SKTileDefinition来显示正确的箭头纹理。如果玩家绕过弯道将光标移动到所需的图块并检测到周围有障碍物,它还应该自动更正箭头。
所以我的问题是:如何使用给定的规则实现我自己的SKTileGroup。即使您只是想创建一个SKTileGroupRule仅用于绕障碍TileSizes进行绘制或如前所述在绕行时自动校正,也请随时回答。
具有相同逻辑的另一款游戏的图片:
import SpriteKit
class Spielfeld: SKScene {
var x: Int = 0 // columns
var y: Int = 0 // rows
var background: SKTileMapNode = SKTileMapNode()
var
objects: SKTileMapNode = SKTileMapNode()
enum State {
case initial
case selected
case menu
}
var state: State = .initial // Initial state
var selected: Charakter!
var menu: Menu = Menu(0)
var up: SKSpriteNode = SKSpriteNode()
var down: SKSpriteNode = SKSpriteNode()
var left: SKSpriteNode = SKSpriteNode()
var right: SKSpriteNode = SKSpriteNode()
var buttonA: SKSpriteNode = SKSpriteNode()
var buttonB: SKSpriteNode = SKSpriteNode()
let cursor: SKSpriteNode = SKSpriteNode(imageNamed: "Cursor1Blue")
var cursor_x: Int = 0
var cursor_y: Int = 0
let charInfo: SKNode = SKNode()
let charInfoBG: SKSpriteNode = SKSpriteNode(imageNamed: "CharInfo")
let charInfoLabel: SKLabelNode = SKLabelNode()
var reach: [SKSpriteNode] = []
let ike: Ike = Ike()
let boyd: Boyd = Boyd()
override func sceneDidLoad() {
background = self.childNode(withName: "Background") as! SKTileMapNode
objects = self.childNode(withName: "Objects") as! SKTileMapNode
calibrateMap()
addController()
addCursor()
ike.position = objects.centerOfTile(atColumn: 0, row: 1)
ike.x = 0
ike.y = 1
objects.addChild(ike)
boyd.position = objects.centerOfTile(atColumn: 6, row: 3)
boyd.x = 6
boyd.y = 3
boyd.team = 2
objects.addChild(boyd)
initCharInfo()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch:UITouch = touches.first! as UITouch
let positionInScene = touch.location(in: self)
let touchedNode = self.atPoint(positionInScene)
print(touchedNode.name!)
if(touchedNode.name == "Objects") {
let map = touchedNode as! (SKTileMapNode)
let positionInMap = touch.location(in: map)
} else if(isCursor(touchedNode.name!)) {
switch state {
case .initial, .selected:
moveCursor(button: touchedNode.name!)
if let char = atCursor() {
print(char.name!)
changeCursorColor(team: char.team)
charInfoLabel.text = char.getInfo()
charInfo.isHidden = false
} else {
changeCursorColor(team: 0)
charInfo.isHidden = true
}
case .menu:
switch touchedNode.name! {
case "Up":
menu.moveUp()
case "Down":
menu.moveDown()
default:
break
}
}
} else if(touchedNode.name == "ButtonA") {
print("Button A pressed")
buttonAPressed()
} else if(touchedNode.name == "ButtonB") {
print("Button B pressed")
buttonBPressed()
}
}
func calibrateMap() {
background.position.x += (background.mapSize.width/2 - 32)
background.position.y += (background.mapSize.width/2 - 5 * 32)
objects.position.x += (background.mapSize.width/2 - 32)
objects.position.y += (background.mapSize.width/2 - 5 * 32)
}
func addController() {
up = self.childNode(withName: "Up") as! SKSpriteNode
down = self.childNode(withName: "Down") as! SKSpriteNode
left = self.childNode(withName: "Left") as! SKSpriteNode
right = self.childNode(withName: "Right") as! SKSpriteNode
buttonA = self.childNode(withName: "ButtonA") as! SKSpriteNode
buttonB = self.childNode(withName: "ButtonB") as! SKSpriteNode
}
func addCursor() {
cursor_x = 0
cursor_y = 1
cursor.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
cursor.zPosition = 2
cursor.name = "Cursor"
self.addChild(cursor)
var cursorTextures: [SKTexture] = Array(repeating: SKTexture(), count: 3)
cursorTextures[0] = SKTexture(imageNamed: "Cursor1Blue")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2Blue")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3Blue")
var cursorAnimation = SKAction.animate(with: cursorTextures, timePerFrame: 0.5)
cursorAnimation = SKAction.repeatForever(cursorAnimation)
cursor.run(cursorAnimation, withKey: "CursorAnimation")
}
func isCursor(_ name: String) -> Bool {
if(name == "Up" || name == "Down" || name == "Left" || name == "Right") {
return true
} else {
return false
}
}
func moveCursor(button: String) {
if(button == "Up" && cursor_y != y-1) {
cursor_y += 1
background.position.y -= 64
objects.position.y -= 64
} else if(button == "Down" && cursor_y != 0) {
cursor_y -= 1
background.position.y += 64
objects.position.y += 64
} else if(button == "Left" && cursor_x != 0) {
cursor_x -= 1
background.position.x += 64
objects.position.x += 64
} else if(button == "Right" && cursor_x != x-1) {
cursor_x += 1
background.position.x -= 64
objects.position.x -= 64
}
}
func atCursor() -> Charakter? {
let char = self.atPoint(cursor.position) as? Charakter
return char
}
func changeCursorColor(team: Int) {
cursor.removeAction(forKey: "CursorAnimation")
var cursorTextures: [SKTexture] = Array(repeating: SKTexture(), count: 3)
switch team {
case 0:
cursorTextures[0] = SKTexture(imageNamed: "Cursor1White")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2White")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3White")
case 1:
cursorTextures[0] = SKTexture(imageNamed: "Cursor1Blue")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2Blue")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3Blue")
case 2:
cursorTextures[0] = SKTexture(imageNamed: "Cursor1Red")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2Red")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3Red")
case 3:
cursorTextures[0] = SKTexture(imageNamed: "Cursor1Green")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2Green")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3Green")
case 4:
cursorTextures[0] = SKTexture(imageNamed: "Cursor1Yellow")
cursorTextures[1] = SKTexture(imageNamed: "Cursor2Yellow")
cursorTextures[2] = SKTexture(imageNamed: "Cursor3Yellow")
default:
print("Team doesnt exist!")
}
var cursorAnimation = SKAction.animate(with: cursorTextures, timePerFrame: 0.5)
cursorAnimation = SKAction.repeatForever(cursorAnimation)
cursor.run(cursorAnimation, withKey: "CursorAnimation")
}
func buttonAPressed() {
switch state {
case .initial:
if let char = atCursor() {
selected = char
state = .selected
showReach(char)
}
case .selected:
if selected.inReach(x: cursor_x, y: cursor_y) {
if let _ = atCursor() {
} else {
let isTree = objects.tileDefinition(atColumn: cursor_x, row: cursor_y)?.userData?["isTree"] as? Bool
if(isTree == true) {
print("tree!")
} else {
state = .menu
menu = Menu(3)
menu.position = CGPoint(x: self.size.width/2 + 128, y: self.size.height/2)
self.addChild(menu)
}
}
}
case .menu:
switch menu.getSelectedOption() {
case.warten:
selected.move(to: background.centerOfTile(atColumn: cursor_x, row: cursor_y))
selected.x = cursor_x
selected.y = cursor_y
state = .initial
background.removeChildren(in: reach)
reach = []
self.removeChildren(in: [menu])
default: break
}
}
}
func buttonBPressed() {
switch state {
case .selected:
state = .initial
background.removeChildren(in: reach)
reach = []
case .menu:
state = .selected
self.removeChildren(in: [menu])
default:
break
}
}
func initCharInfo() {
charInfoBG.name = "CharInfoBG"
charInfoBG.anchorPoint = CGPoint(x: 0, y: 1)
charInfoBG.zPosition = 3
charInfo.addChild(charInfoBG)
charInfoLabel.name = "CharInfoLabel"
charInfoLabel.text = ike.getInfo()
charInfoLabel.horizontalAlignmentMode = .left
charInfoLabel.fontName = "Papyrus"
charInfoLabel.fontColor = .black
charInfoLabel.fontSize = 22
charInfoLabel.position = CGPoint(x: 23, y: -33)
charInfoLabel.zPosition = 4
charInfo.addChild(charInfoLabel)
charInfo.name = "CharInfo"
charInfo.position = CGPoint(x: 0, y: 375)
self.addChild(charInfo)
}
func showReach(_ char: Charakter) {
background.removeChildren(in: reach)
reach = []
let node: SKSpriteNode = SKSpriteNode(color: .blue, size: CGSize(width: 64, height: 64))
node.zPosition = 2
node.alpha = 0.25
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y)
reach.last?.name = "Reichweite"
background.addChild(reach.last!)
for i in 1...char.bew {
if(char.x+i <= x-1) {
let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y)
reach.last?.name = "Reichweite"
background.addChild(reach.last!)
}
}
if(char.x-i >= 0) {
let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
if(char.y+i <= y-1) {
let isTree = objects.tileDefinition(atColumn: char.x, row: char.y+i)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y+i)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
if(char.y-i >= 0) {
let isTree = objects.tileDefinition(atColumn: char.x, row: char.y-i)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x, row: char.y-i)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
for j in 0...char.bew-i {
if(j == 0) {
continue
}
if(char.x+i <= x-1) {
if(char.y+j <= y-1) {
let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y+j)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y+j)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
if(char.y-j >= 0) {
let isTree = objects.tileDefinition(atColumn: char.x+i, row: char.y-j)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x+i, row: char.y-j)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
}
if(char.x-i >= 0) {
if(char.y-j >= 0) {
let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y-j)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y-j)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
if(char.y+j <= y-1) {
let isTree = objects.tileDefinition(atColumn: char.x-i, row: char.y+j)?.userData?["isTree"] as? Bool
if (isTree == false || isTree == nil) {
reach.append(node.copy() as! SKSpriteNode)
reach.last!.position = background.centerOfTile(atColumn: char.x-i, row: char.y+j)
background.addChild(reach.last!)
reach.last?.name = "Reichweite"
}
}
}
}
}
}
}