アップルの無償プログラミング学習ツール「Swiftプログラミング」でいっしょに遊ぼう 第5回
アップルの無償プログラミング学習ツール「Swift Playgrounds」アクションゲーム作り(仕上編)
2020年10月11日 09時00分更新
ステップ4:ゲームに手を加えて、よりおもしろく遊べるようにする
もぐら叩きと言いながら、これまではバスケットボールの絵文字を動かして叩く、ボール叩きになっていました。キャラがボールだと盛り上がらないという面もあるかもしれませんが、それだけでなく、穴の中を上下するキャラが1種類だけというのは、ゲームとしての面白みに欠ける要因になるかもしれません。そこでここではキャラを2種類にして、一方を叩くと得点が加算され、もう片方では減点されるようにしてみます。絵柄として紛らわしいキャラを選べば、その紛らわしさによってゲームの難易度も高くなります。
この例では、一般的なスマイリーの2種類の絵文字をキャラとして使ってみましょう。1つは、口が笑っているもの。もう1つは口がへの字で、困ったような顔をしているものです。目はほとんど変わらないので、口の部分が穴から出てくるまで区別がつきにくくなっています。もちろん前者を叩けば得点はプラス、後者ではマイナスとします。プログラムの改造手順は以下のようになります。
・穴を叩いたら減点するインベント処理はやめる
・もぐらのイベント処理に得点の加算と減算の2通りの処理を加える
・タイマーの中でランダムにもぐらのキャラを変更する処理を加える
・ここまでのプログラムを動かして動作を確認する
プログラムの最初の方で、穴に見立てて7個配置しているオレンジ色の円ですが、これまではonTouchDown {}のイベント処理で、タップしたりクリックしたりすると、それまでに稼いだ得点から10点を減点していました。今回は、それをやめます。穴をタップしたときではなく、間違ったキャラをタップしたときに減点するようにするためです。
それに対して、やはり最初の方で7個配置していた「もぐら」ですが、とりあえず最初は口が笑ったスマイリーで初期化します。ただし、onTouchDown {}のイベント処理内では、キャラの絵文字の種類によって、得点を10点増やすか、逆に10点減らすかを判断して実行しています。ここまででは、もぐらのキャラは笑ったスマイリーでしかあり得ないのですが、後でタイマー処理の中で、乱数を使ってキャラの絵文字を切り替えるのです。
そのキャラの絵文字の切り替えは、タイマーによるループの中で、もぐらの絵文字を含むTextのy座標の値が0以下になった際に実行します。これまでは、もぐらTextの速度をランダムに設定していただけですが、それに続いてキャラの絵文字も設定するわけです。まず例によってarc4random_uniform()で乱数を発生させますが、そこでは10を指定して、0〜9のいずれかの整数を得ます。
ここでは、それが3より大きかった場合には笑ったスマイリー、そうでなければ困った顔のスマイリーに設定しています。これで、笑ったスマイリーと困ったスマイリーが、だいたい6:4の割合で出てくることになります。この比率は好みで調整してください。
これでゲームの改造は完了です。書き加えなければならない部分も案外少なく、思ったより簡単だったでしょう。最後に動かして動作を確認してください。
最後に改造済のプログラム全体を示しておきます。前回と今回のゲーム作りを参考にして、ぜひオリジナルのゲーム制作に挑戦してみてください。
import Foundation
import PlaygroundSupport
Canvas.shared.color = #colorLiteral(red: 0.466666668653488,
;green: 0.764705896377563, blue: 0.266666680574417, alpha: 1.0)
let locations = [
[-8.0, 16.0], [8.0, 16.0],
[-16.0, 0.0], [0.0, 0.0], [16.0, 0.0],
[-8.0, -16.0], [8.0, -16.0]
]
var score = 0
var time = 30
var frames = 20
var status = "running"
let scoreDisp = Text(string: "残り\(time)秒 - 得点:\(score)", fontSize: 30.0, fontName: "Menlo-Bold", color: Color.white)
scoreDisp.center = Point(x: 0.0, y: 35.0)
var moles = [Text]()
var mVels = [Double]()
for i in 0 ..< locations.count {
mVels.append(Double(0.0))
}
for loc in locations {
let hole = Circle(radius: 4.0)
hole.color = #colorLiteral(red: 0.960784316062927,
;green: 0.705882370471954, blue: 0.200000002980232, alpha: 1.0)
hole.center = Point(x: loc[0], y: loc[1] + 4.0)
}
for loc in locations {
let mole = Text(string: "🙂")
mole.fontSize = 50.0
mole.center = Point(x: loc[0], y: loc[1])
mole.onTouchDown {
if mole.string == "🙂" {
score += 10
} else {
score -= 10
}
scoreDisp.string = "残り\(time)秒 - 得点:\(score)"
animate {
mole.center.y = loc[1]
}
}
moles.append(mole)
}
for loc in locations {
let cover = Rectangle(width: 8.0, height: 8.0)
cover.color = #colorLiteral(red: 0.466666668653488,
;green: 0.764705896377563, blue: 0.266666680574417, alpha: 1.0)
cover.center = Point(x: loc[0], y: loc[1])
}
let overDisp = Text(string: "Game Over")
overDisp.color = #colorLiteral(red: 0.572549045085907,
;green: 0.0, blue: 0.23137255012989, alpha: 1.0)
overDisp.fontSize = 0.1
overDisp.dropShadow = Shadow()
var overCount = 20
let timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true,
block: {_ in
if status == "running" {
var i = 0
for mole in moles {
var y = mole.center.y - locations[i][1]
if y <= 0.0 {
mVels[i] = Double(arc4random_uniform(40)) / 100.0 + 0.1
if arc4random_uniform(10) > 3 {
mole.string = "🙂"
} else {
mole.string = "🙁"
}
} else if y > 6.5 {
mVels[i] *= -1.0
}
mole.center.y += mVels[i]
i += 1
}
frames -= 1
if frames == 0 {
time -= 1
if time == 0 {
status = "gameover"
for i in 0 ..< moles.count {
moles[i].center.y = locations[i][1]
}
}
scoreDisp.string = "残り\(time)秒 - 得点:\(score)"
frames = 20
}
} else if status == "gameover" {
overDisp.fontSize += 3.0
overCount -= 1
if overCount == 0 {
PlaygroundPage.current.finishExecution()
}
} })
この連載の記事
-
第4回
Apple
アップルの無償プログラミング学習ツール「Swift Playgrounds」アクションゲーム作り(準備編) -
第3回
Apple
アップルの無償プログラミング学習ツール「Swift Playgrounds」アニメーションを動かそう -
第2回
Apple
アップルの無償プログラミング学習ツール「Swift Playgrounds」簡単なお絵描きアプリを作ろう -
第1回
Apple
アップル無償プログラミングツール「Swift Playgrounds」を試そう - この連載の一覧へ