В настоящее время я работаю над новой игрой, в которой у меня есть SKTileMapNode с именем background
в качестве игровой площадки, на которой персонажи могут переходить от плитки к плитке. В дополнение к этому у меня есть еще один SKTileMapNode с именем objects
, который отображается поверх background
(в направлении z), где у меня есть различные препятствия для движения персонажей, таких как деревья или камни. My Scene содержит курсор и игровой контроллер с кнопками вверх, вниз, влево, вправо, A и B.
Я уже реализовал в логике, где я могу переместить курсор поверх символа и выбрать его. После выбора я могу выбрать плитку для перемещения выбранного персонажа, если нет препятствий. Все до этого момента работает как надо.
Теперь я хочу реализовать способ, позволяющий игроку видеть стрелку после выбора персонажа, который отображает плитки, по которым персонаж должен пройти, чтобы добраться до плитки, на которой находится курсор, прежде чем выбрать эту плитку в качестве места назначения. .
У меня была идея создать собственный SKTileGroupRule для object
или новый SKTileMapNode поверх обоих, который автоматически выбирает правильное SKTileDefinition для отображения текстуры стрелки вправо. Также следует автоматически исправить стрелку, если игрок переместил курсор в обход желаемой плитки и обнаружил препятствия для рисования.
Поэтому мой вопрос: как я могу реализовать свою собственную SKTileGroup с этими данными правилами. Пожалуйста, не стесняйтесь отвечать, даже если у вас есть только идея создать SKTileGroupRule только для рисования вокруг препятствий TileDefinitions или автозамены на обходах, как упоминалось ранее.
Картинка другой игры с той же логикой:
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"
}
}
}
}
}
}
}