今回は落下オブジェクトの周囲回転機能と2タイプオブジェクトの追加。
後は積み上げ機能と消去させる接触グループの調査に対象消去(連鎖)の機能。
消去アニメーション追加。
連鎖が面倒いな。
( 投稿した後にコードの一部が消える。プレビューは正常なのに投稿すると一部が消える…。面倒い。)
【ContentView.swift】
import SwiftUI
import SpriteKit
struct ContentView: View {
var currentScene = MySKScene()
init(){
currentScene.scaleMode = .resizeFill
currentScene.backgroundColor = .yellow
}
var body: some View {
VStack {
SpriteView(scene: currentScene)
.frame(width: currentScene.sceneWidth(), height: currentScene.sceneHeight())
HStack {
Button("⬅️"){
currentScene.moveLeft()
}
Button("🔄"){
currentScene.rotation()
}
Button("➡️"){
currentScene.moveRight()
}
}
}
}
}
【MyTextures.swift】
import SwiftUI
import SpriteKit
class MyTextures {
private var _imageTextures:[SKTexture] = []
func imageTextures(type:Int) -> [SKTexture] {
switch (type) {
case 1:
if let uii = UIImage(systemName: "arrowshape.up.circle" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.forward.circle" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.down.circle" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.backward.circle" ) {
_imageTextures.append(SKTexture(image: uii))
}
case 2:
if let uii = UIImage(systemName: "arrowshape.up.circle.fill" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.forward.circle.fill" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.down.circle.fill" ) {
_imageTextures.append(SKTexture(image: uii))
}
if let uii = UIImage(systemName: "arrowshape.backward.circle.fill" ) {
_imageTextures.append(SKTexture(image: uii))
}
default: break
//
}
return _imageTextures
}
}
【MySKScene.swift】
import SwiftUI
import SpriteKit
class MySKScene: SKScene {
var gameObj0: GameObject = GameObject(x:4,y:0,type:1)
var gameObj1: GameObject = GameObject(x:5,y:0,type:2)
var imageSize:CGFloat = 32.0
// 10x15の2次元配列を0で初期化。グループNOを格納する2次元配列。grid[gridMaxX][gridMaxY]
let gridMaxX = 10
let gridMaxY = 15
var grid = Array(repeating:
Array(repeating: GameObject(x: 0, y: 0, type: 0), count: 15), count: 10)
var lastUpdateTime : TimeInterval = 0
// シーンがViewに表示されたときに実行する処理をdidMoveメソッド内に書きます
override func didMove(to view: SKView) {
setGameObj(obj: gameObj0)
setGameObj(obj: gameObj1)
}
//一定時間毎の処理
override func update(_ currentTime: TimeInterval) {
if (lastUpdateTime == 0) {
lastUpdateTime = currentTime
}
if (lastUpdateTime + 1.0 <= currentTime) {
downPosition()
lastUpdateTime = currentTime
}
}
}
extension MySKScene {
func sceneWidth()-> CGFloat {
return imageSize * CGFloat(gridMaxX)
}
func sceneHeight()-> CGFloat {
return imageSize * CGFloat(gridMaxY)
}
func setGameObj(obj:GameObject) {
if obj.image != nil {
obj.image.removeFromParent()
}
obj.image = SKSpriteNode()
obj.image.size = CGSize(width: self.imageSize, height: self.imageSize)
obj.image.position = getPosition(x: Double(obj.posX), y: Double(obj.posY))
self.addChild(obj.image)
obj.image.run(.repeatForever(
.animate(with: MyTextures().imageTextures(type: obj.type), timePerFrame: 0.3)
))
}
func removeGameObj(obj:GameObject){
obj.image.removeFromParent()
}
func moveLeft() { // 落下オブジェクトの左移動
if (gameObj0.posX - 1) >= 0 && (gameObj1.posX - 1) >= 0 {
gameObj0.posX -= 1
gameObj0.image.position = getPosition(x: Double(gameObj0.posX), y: Double(gameObj0.posY))
gameObj1.posX -= 1
gameObj1.image.position = getPosition(x: Double(gameObj1.posX), y: Double(gameObj1.posY))
}
}
func moveRight() { // 落下オブジェクトの右移動
if (gameObj0.posX + 1) < gridMaxX && (gameObj1.posX + 1) < gridMaxX {
gameObj0.posX += 1
gameObj0.image.position = getPosition(x: Double(gameObj0.posX), y: Double(gameObj0.posY))
gameObj1.posX += 1
gameObj1.image.position = getPosition(x: Double(gameObj1.posX), y: Double(gameObj1.posY))
}
}
func downPosition() { // 落下オブジェクトの下移動
gameObj0.posY += 1
if gameObj0.posY >= gridMaxY {
gameObj0.posY = 0 // 仮、上に戻している
}
gameObj0.image.position = getPosition(x: Double(gameObj0.posX), y: Double(gameObj0.posY))
gameObj1.posY += 1
if gameObj1.posY >= gridMaxY {
gameObj1.posY = 0 // 仮、上に戻している
}
gameObj1.image.position = getPosition(x: Double(gameObj1.posX), y: Double(gameObj1.posY))
}
func rotation(){
if rotationCheck() {return}
if gameObj0.posY == gameObj1.posY {
gameObj1.posY += (gameObj0.posX < gameObj1.posX ? 1: -1)
gameObj1.posX = gameObj0.posX
} else if gameObj0.posX == gameObj1.posX {
gameObj1.posX += (gameObj0.posY < gameObj1.posY ? -1: 1)
gameObj1.posY = gameObj0.posY
}
gameObj1.image.position = getPosition(x: Double(gameObj1.posX), y: Double(gameObj1.posY))
}
private func rotationCheck()-> Bool {
if gameObj0.posY == 0 &&
gameObj1.posY == 0 &&
gameObj0.posX > gameObj1.posX
{return true}
if gameObj0.posY == gridMaxY-1 &&
gameObj1.posY == gridMaxY-1 &&
gameObj0.posX < gameObj1.posX
{return true}
if gameObj0.posX == 0 &&
gameObj1.posX == 0 &&
gameObj0.posY < gameObj1.posY
{return true}
if gameObj0.posX == gridMaxX-1 &&
gameObj1.posX == gridMaxX-1 &&
gameObj0.posY > gameObj1.posY
{return true}
return false
}
func clearGrid(){ // 2次元配列のクリア
for i in 0..< gridMaxX {
for j in 0..< gridMaxY {
grid[i][j].clear()
}
}
}
func getPosition(x:Double, y:Double) -> CGPoint {
// 2次元配列の位置(x,y)からSpriteViewの位置に変換する
return CGPoint(x:32.0 * x + 16.0, y:480.0 - 32.0 * y - 16.0)
}
}
class GameObject {
var image: SKSpriteNode!
var type: Int = 0
private var _imageGridPositionX = 0 // 落下するオブジェクトのマス目位置
var posX: Int {
get {return _imageGridPositionX}
set { _imageGridPositionX = newValue}
}
private var _imageGridPositionY = 0
var posY: Int {
get {return _imageGridPositionY}
set { _imageGridPositionY = newValue}
}
init(){
_imageGridPositionX = 0
_imageGridPositionY = 0
self.type = 0
}
init(x:Int,y:Int,type:Int){
setProperties(x:x,y:y,type:type)
}
func setProperties(x:Int,y:Int,type:Int){
_imageGridPositionX = x
_imageGridPositionY = y
self.type = type
}
func clear(){
image.removeFromParent()
image = nil
_imageGridPositionX = 0
_imageGridPositionY = 0
type = 0
}
}
goo blog 作成者が、このコード消去に対応するには、
<"半角空白" の部分周辺が消える場合がある所の
”<” を全角にするか、"<"の後に半角空白を2個入れる。
表示テキストをHTML文法に変換する時に間違いが起こるのでしょうね。
単純にコードのコピペで済ませたい…。