import SpriteKit
import GameplayKit
extension SKPhysicsBody {
func ideal() -> SKPhysicsBody {
//摩擦係数の値で 1 に近いほど摩擦が多くなります0.0から1.0の間
self.friction = 0
self.linearDamping = 0 //粘性//体にかかる流体または空気の摩擦力
self.angularDamping = 0 //体の回転速度を遅くする特性 0.0から1.0の間の値
self.restitution = 0.98 //反発率
self.isDynamic = true //動かせる性質
self.allowsRotation = false //角力とインパルスの影響デフォルト値はtrue
// 重力を無視する 重力の影響を受けない
//circleA.physicsBody?.affectedByGravity = false
self.affectedByGravity = true
return self
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
backgroundColor = .blue
self.physicsWorld.contactDelegate = self
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.gravity = CGVector(dx: 0, dy: -2)
let circleA = SKShapeNode(circleOfRadius: 50)//circleOfRadiusで円の半径
circleA.position = CGPoint(x:self.frame.midX, y:self.frame.midY + 230)
circleA.fillColor = UIColor.red
circleA.lineWidth = 4.0
circleA.strokeColor = UIColor.lightGray
self.addChild(circleA)
circleA.physicsBody = SKPhysicsBody(circleOfRadius: circleA.frame.width/2).ideal()
//物体Aのカテゴリ0と物体Bの衝突が等しくなければAはBを通過する。それ以外は衝突する
//Aカテゴリ
circleA.physicsBody?.categoryBitMask = 0x1 << 0
//通過する(衝突される側のcategoryBitMaskとcollisionBitMaskを0にする)
circleA.physicsBody?.collisionBitMask = 0x1 << 0
let circleB = SKShapeNode(circleOfRadius: 25)//circleOfRadiusで円の半径
circleB.position = CGPoint(x:self.frame.midX, y:self.frame.midY + 110)
circleB.fillColor = UIColor.yellow
circleB.lineWidth = 4.0
circleB.strokeColor = UIColor.lightGray
self.addChild(circleB)
circleB.physicsBody = SKPhysicsBody(circleOfRadius: circleB.frame.width/2).ideal()
circleB.physicsBody?.categoryBitMask = 0x1 << 1
circleB.physicsBody?.collisionBitMask = 0x1 << 1
// 四角形を作成
let squareB = SKShapeNode(rectOf: CGSize(width:100, height:100),cornerRadius: 5)
// 四角形の配置位置を指定
squareB.position = CGPoint(x:self.frame.midX, y:self.frame.midY - 200)
// 四角形の色を指定
squareB.fillColor = .green
squareB.lineWidth = 0.0
// シーンに追加
self.addChild(squareB)
squareB.physicsBody = SKPhysicsBody(rectangleOf: squareB.frame.size).ideal()
//Bカテゴリ
squareB.physicsBody?.categoryBitMask = 0x1 << 0 + 0x1 << 1
//通過する(衝突される側のcategoryBitMaskとcollisionBitMaskを1にする)
squareB.physicsBody?.collisionBitMask = 0x1 << 0 + 0x1 << 1
//後から指定したsquareBが上に表示される
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
}
}
Physics2
GameScene
import SpriteKit
import GameplayKit
extension SKPhysicsBody {
func ideal() -> SKPhysicsBody {
//摩擦係数の値で 1 に近いほど摩擦が多くなります0.0から1.0の間
self.friction = 0
self.linearDamping = 0 //粘性//体にかかる流体または空気の摩擦力
self.angularDamping = 0 //体の回転速度を遅くする特性 0.0から1.0の間の値
self.restitution = 0.98 //反発率
self.isDynamic = true //動かせる性質
self.allowsRotation = false //角力とインパルスの影響デフォルト値はtrue
// 重力を無視する 重力の影響を受けない
//circleA.physicsBody?.affectedByGravity = false
self.affectedByGravity = true
return self
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
backgroundColor = .blue
self.physicsWorld.contactDelegate = self
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
physicsWorld.gravity = CGVector(dx: 0, dy: -2)
let circleA = SKShapeNode(circleOfRadius: 50)//circleOfRadiusで円の半径
circleA.position = CGPoint(x:self.frame.midX, y:self.frame.midY + 230)
circleA.fillColor = UIColor.red
circleA.lineWidth = 4.0
circleA.strokeColor = UIColor.lightGray
self.addChild(circleA)
circleA.physicsBody = SKPhysicsBody(circleOfRadius: circleA.frame.width/2).ideal()
//Aカテゴリ
circleA.physicsBody?.categoryBitMask = 0x1 << 0
//通過する(衝突される側のcategoryBitMaskとcollisionBitMaskを0にする)
circleA.physicsBody?.collisionBitMask = 0x1 << 0
//物体Aのカテゴリ0と物体Bの衝突が等しくなければAはBを通過する。それ以外は衝突する
// 四角形を作成
let squareB = SKShapeNode(rectOf: CGSize(width:100, height:100),cornerRadius: 5)
// 四角形の配置位置を指定
squareB.position = CGPoint(x:self.frame.midX, y:self.frame.midY - 200)
// 四角形の色を指定
squareB.fillColor = .green
squareB.lineWidth = 0.0
// シーンに追加
self.addChild(squareB)
squareB.physicsBody = SKPhysicsBody(rectangleOf: squareB.frame.size).ideal()
//Bカテゴリ
squareB.physicsBody?.categoryBitMask = 0x1 << 1
//通過する(衝突される側のcategoryBitMaskとcollisionBitMaskを1にする)
squareB.physicsBody?.collisionBitMask = 0x1 << 1
//後から指定したsquareBが上に表示される
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
}
}
Physics1
GameScene
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
backgroundColor = .blue
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
let ball = SKShapeNode(circleOfRadius: 40) //circleOfRadiusで円の半径
ball.position = CGPoint(x:self.frame.midX, y:self.frame.midY+200)
ball.fillColor = UIColor.red
ball.lineWidth = 0.0
ball.strokeColor = UIColor.red
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
self.addChild(ball)
//ボールの飛んでいく方向
ball.physicsBody?.applyImpulse(CGVector(dx: 40, dy: 40))
ball.physicsBody?.restitution = 1
ball.physicsBody?.friction = 0
ball.physicsBody?.linearDamping = 0
let label = SKLabelNode(fontNamed: "HelveticaNeue-Light")
label.text = "Hello World!"
label.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
label.fontSize = 40
label.fontColor = SKColor.white
self.addChild(label)
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
}
}
LocalWebView
WebViewTest.swift
import SwiftUI
import WebKit //WebKitをインポート
struct WebViewTest: UIViewRepresentable {
// var url: String = "https://google.com" //表示するWEBページのURLを指定
func makeUIView(context: Context) -> WKWebView{
return WKWebView()
}
func updateUIView(_ uiView: UIViewType, context: Context) {
guard let path: String = Bundle.main.path(forResource: "index", ofType: "html") else { return }
let localHTMLUrl = URL(fileURLWithPath: path, isDirectory: false)
uiView.loadFileURL(localHTMLUrl, allowingReadAccessTo: localHTMLUrl)
}
}
///////////////////////////
ContentView.swift
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: WebViewTest()) {
Text("Show web page")
}
}
// WebViewTest()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
//////////////////////////////
index.html
Breakout
表示するフォントのサイズを引数で指定します。
標準で使える定義済フォントサイズには次のようなものがあります。
GameScene
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let kBlockWidth : CGFloat = 55.0
let kBlockHeight : CGFloat = 25.0
let kBlockRows : Int = 8
let kBlockColumns : Int = 7
var kBlockRecoverTime = 10.0
let ballCategoryName = "ball"
let paddleCategoryName = "paddle"
let blockCategoryName = "block"
let ballCategory:UInt32 = 0x1 << 0
let bottomCategory:UInt32 = 0x1 << 1
let blockCategory:UInt32 = 0x1 << 2
let paddleCategory:UInt32 = 0x1 << 3
var label = SKLabelNode(fontNamed: "HelveticaNeue-Light")
var score = 0
let paddle = SKShapeNode(rectOf: CGSize(width:110, height:25),cornerRadius: 2)
override func didMove(to view: SKView) {
backgroundColor = .white
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
let ball = SKShapeNode(circleOfRadius: 12)//circleOfRadiusで円の半径
ball.position = CGPoint(x:self.frame.midX, y:self.frame.midY-100)
ball.fillColor = UIColor.red
ball.lineWidth = 0.0
ball.strokeColor = UIColor.red
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
self.addChild(ball)
//ボールの飛んでいく方向
ball.physicsBody?.friction = 0
ball.physicsBody?.restitution = 1
ball.physicsBody?.linearDamping = 0
ball.physicsBody?.allowsRotation = false
ball.physicsBody?.applyImpulse(CGVector(dx: 5, dy: 5))
// 四角形を作成
paddle.position = CGPoint(x:self.frame.midX, y:self.frame.midY-360)
paddle.name = paddleCategoryName
paddle.fillColor = .green
paddle.lineWidth = 0.0
paddle.physicsBody = SKPhysicsBody(rectangleOf: paddle.frame.size)
paddle.physicsBody?.restitution = 0.1
paddle.physicsBody?.friction = 0.2
paddle.physicsBody?.linearDamping = 0
paddle.physicsBody?.isDynamic = false
self.addChild(paddle)
let totalBlocksWidth = kBlockWidth * CGFloat(kBlockColumns)
let xOffset = (frame.width - totalBlocksWidth) / 2
let yOffset = frame.height * 0.6
for i in 0.., with event: UIEvent?) {
// for touch in touches
// {
// let toucLocation = touch.location(in: self)
// border.position.x = toucLocation.x
// }
}
//パドル
override func touchesMoved(_ touches: Set, with event: UIEvent?) {
for touch in touches
{
let toucLocation = touch.location(in: self)
paddle.position.x = toucLocation.x
}
}
func didBegin(_ contact: SKPhysicsContact) {
var firstBody = SKPhysicsBody()
var secondBody = SKPhysicsBody()
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
firstBody = contact.bodyA
secondBody = contact.bodyB
}else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.categoryBitMask == ballCategory && secondBody.categoryBitMask == bottomCategory{
// let changeSceneAction = SKAction.run(changeScene)
// self.run(changeSceneAction)
let gameOverScene = GameOverScene(size: self.frame.size)
self.view?.presentScene(gameOverScene)
}
if firstBody.categoryBitMask == ballCategory && secondBody.categoryBitMask == blockCategory{
secondBody.node?.removeFromParent()
score += 1
label.text = "\(score)"
if score >= 12 {
let gameOverScene = GameClearScene(size: self.frame.size)
self.view?.presentScene(gameOverScene)
}
}
}
/*
func changeScene(){
let sceneToMoveTo = GameOverScene(size: self.frame.size)
sceneToMoveTo.scaleMode = self.scaleMode
let myTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMoveTo, transition: myTransition)
}
*/
}
///////////////////////////////////
GameOverScene.swift
import SpriteKit
class GameOverScene: SKScene {
override func didMove(to view: SKView) {
backgroundColor = .blue
let gameOverLabel = SKLabelNode(fontNamed: "Avenir-Black")
gameOverLabel.fontSize = 46
gameOverLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
gameOverLabel.text = "GAME OVER!"
self.addChild(gameOverLabel)
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
let breakOutGameScene = GameScene(size: self.size)
self.view?.presentScene(breakOutGameScene)
}
}
/////////////////////////////
GameClearScene.swift
import SpriteKit
class GameClearScene: SKScene {
override func didMove(to view: SKView) {
backgroundColor = .green
let gameOverLabel = SKLabelNode(fontNamed: "Avenir-Black")
gameOverLabel.fontSize = 46
gameOverLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
gameOverLabel.text = "GAME CLEAR!"
self.addChild(gameOverLabel)
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
let breakOutGameScene = GameScene(size: self.size)
self.view?.presentScene(breakOutGameScene)
}
}
Button
GameScene
import SpriteKit
import GameplayKit
class GameScene: SKScene {
let label = SKLabelNode(fontNamed: "HelveticaNeue-Light")
let button = SKSpriteNode(imageNamed: "blue2.png")
override func didMove(to view: SKView) {
physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
self.backgroundColor = .green
label.text = "Hello World!"
label.position = CGPoint(x: self.frame.midX, y: self.frame.midY + 10)
label.fontSize = 20
label.fontColor = SKColor.white
self.addChild(label)
button.position = CGPoint(x: size.width/2, y: size.height/2+120)
button.zPosition = 1
button.name = "button"
button.setScale(0.4)
self.addChild(button)
button.run(SKAction.scale(to: 0.5, duration: 0.3))
button.alpha = 1
}
override func touchesEnded(_ touches: Set, with event: UIEvent?) {
button.alpha = 1
button.setScale(0.5)
}
override func touchesBegan(_ touches: Set, with event: UIEvent?){
for touch in touches {
let location = touch.location(in: self)
let touchedNode = atPoint(location)
if touchedNode.name == "button" {
button.alpha = 0.5
button.setScale(0.6)
if label.fontSize < 50 {
label.fontSize += 2
}
else{
label.fontSize = 20
}
}
}
}
}
//////////////////////////
ContentView.swift
import SwiftUI
import SpriteKit
struct ContentView: View {
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
var scene: SKScene {
let scene = GameScene()
scene.size = CGSize(width: screenWidth, height: screenHeight)
scene.scaleMode = .fill
return scene
}
var body: some View {
SpriteView(scene: scene)
.frame(width: screenWidth, height: screenHeight)
.ignoresSafeArea()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
//////////////////////////
ButtonApp.swift
import SwiftUI
@main
struct ButtonApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}