見出し画像

[初心者向け]Pythonista3のsceneでゲーム作成〜ノード移動〜

こんにちは。

普段プログラミングを趣味として自分なりに楽しんでやっています。
その中で学んだ事などを備忘録として残し、僕の思いも少し付け足してnoteにまとめています。

今回はPythonista3のsceneでノードを移動させるやり方を見ていきたいと思います。

前回までで「sceneの基本」と「図形描画」と「ノード」について説明してきました!

そして今回は長いですが、いよいよノードオブジェクトを移動させるので、楽しんでいただけたらいいなと思います!
是非参考にして楽しんで下さい!

コードは、実践的なモノというより理解してもらう事に重きを置いて書いているのでご理解下さい。

今回は座標を変化させていくので、まずは座標の基本的なところを見ておきましょう。

座標の基本

直線・平面・空間における点の位置を、規準の点・直線との距離や角度など、またはその組合せによって示した数値。

らしいです。
今回は2次元の座標を扱うのでそれの説明を簡単にします。

2次元でモノの位置を決めるのはx座標とy座標の2つです。
x座標は横方向の位置を司り、y座標は縦方向の位置を司ります。

パソコンや携帯の画面でも考え方は同じです。
座標の単位は基本的に『ピクセル(pixel)』です。

ただ、ゲームやGUIなどを作成する時に使用するライブラリやゲームエンジンなどによってはy座標の下向きが増加上向きが減少などの場合もあるので、注意してください。

ノードオブジェクトを作成して表示する

まず初めにsceneの雛型を用意します。
雛型についての詳細は[初心者向け]Pythonista3のsceneでゲーム作成〜基礎〜 で説明しています。

[sceneの雛型]

from scene import *

class MyScene(Scene):
       
	def setup(self):
		self.background_color = 'black'
   
	def update(self):
		pass
		

run(MyScene())

とりあえずここからSpriteNodeでボールを描画するところまでいきましょう。
setupメソッドの中に以下のコードを書きます↓

#①
self.x = 100
self.y = 100
#②
self.ball = SpriteNode('pzl:BallBlue', position=(self.x, self.y))
#③
self.add_child(self.ball)

#①
後でボールのx座標とy座標を変化させる予定なのでその為に、数値の100を属性self.xとself.yに割り当てています。

#②
SpriteNodeをインスタンス化して属性self.ballに割り当てています。
SpriteNodeの第一引数にテクスチャを指定して、positionにタプルでself.xとself.yを指定しています。

テクスチャは、エディタ上の右下の+ボタンを押す→Puzzle Game Art→『BallBlue』を選択しました。

#③
add_child()を使って、②で作ったself.ballをself(MyScene自身)に子ノードとして追加しています。

これで黒い背景で青色のボールが描画されると思うので一度右上の▷ボタンを押して実行してみましょう!

こんな感じで表示されたと思います。
次は、いよいよボールを移動させてみましょう!

描画されているボールを移動させる

ここからボールを移動させていく処理を追加する為にupdateメソッドにコードを追加していきます。

このupdateメソッドはデフォルトでは『1秒間に60回(60フレーム)』呼び出されます。

という事は『60枚の紙でできたパラパラ漫画が1秒間で終わる』というようなイメージができますね。

パラパラ漫画は1枚ごとに描いている絵の位置を少しずつずらしていくと、パラパラめくった時に絵が動いているかのような演出が出来るので、それと同じ事をプログラムで書いて実現させます。

そして、プログラムで実現させる為にSceneクラスに元々定義されているupdateメソッドをオーバーライドする事で、自分用のupdateメソッドを作成していく事が出来ます。

基本的にプログラムを実行している間は、この1秒間に60回のペースでupdateメソッドが呼ばれ続ける事になります。

とりあえず一旦ボールのx座標を変化させてみて動かしてみましょう!

updateメソッドのpassを消して、updateの中に以下のコードを書いてみてください↓

#①
self.x+=1
#②
self.ball.position = (self.x, self.y)

#①
self.xに1足した値を再度self.xに割り当てています。

#②
self.ball.positionのx座標とy座標の値をタプルで再設定しています。

イメージとしては以下のようになります↓

これでボールが右方向に動くはずなので右上の▷ボタンを押して実行して見てください!

このように右方向に動いたと思います!
ですがそのまま実行しているとすぐにボールが画面の外に消えてしまいますね。

次はボールが右端に行った時に跳ね返るようにしましょう!

if文で記述が長くなると少し見にくくなるのと、スピードを定義しておく必要があるので一旦setupのところで、self.add_child(self.ball)の手前に3行だけコードを追加します。

def setup(self):
		self.background_color = 'black'
		self.x = 100
		self.y = 100
		self.ball = SpriteNode('pzl:BallBlue', position=(self.x, self.y))
              #①
		self.ball_w = self.ball.size.width
		self.ball_h = self.ball.size.height
        self.x_speed = 1

		self.add_child(self.ball)

#①
・self.ball_wにself.ball.size.width(ボールの幅)を割り当てています。
・self.ball_hにself.ball.size.height(ボールの高さ)を割り当てています。
・ボールを動かす為にスピードが必要なので、self.x_speedに数値1を割り当てています。

とりあえず幅とスピードだけでよかったんですが、後の事も考えて高さもついでに書いておきました。

次にupdateのところのコードを書いていきます。
さっきupdateに書いた以下のコードを一度消します↓

self.x+=1
self.ball.position = (self.x, self.y)

そして新たにupdateのところに以下のコードを書いてください↓

#①
self.x += self.x_speed
#②
self.ball.position = (self.x, self.y)
#③
if (self.x + self.w / 2) > self.size.width:
	self.x_speed *= -1

#①
self.xにself.x_speedを追加しています。

#②
ボールのポジションに再度self.xとself.yを割り当てています。

#③
if文で条件をつけてボールを跳ね返らせます。

もし、ボールのx座標の数値ボールの幅割る2した数値を足した値が、画面の幅よりも大きくなったら〕[スピードに-1を掛ける

これでボールが右端に到達すると跳ね返って左方向に進むはずなので、一度右上の▷ボタンを押して実行してみましょう!

ボールが跳ね返りましたね!
でもボールが跳ね返ってから左端まで行くとボールが消えてしまうので、消えないように処理を加えましょう。
elif文で以下のコードを追加してください↓

#①
elif (self.x - self.w / 2) < 0:
	self.x_speed *= -1

#①
elif分で条件をつけてボールを跳ね返らせます。

それ以外でもし、ボールのx座標の数値からボールの幅割る2した数値を引いた値が、0よりも小さくなったら〕[スピードに-1を掛ける

これでボールが画面外に消える事なく跳ね返り続けると思います、一度右上の▷ボタンを押して実行してみましょう!

ちゃんとボールが跳ね返り続けると思います!

次に同じように縦方向の動きと跳ね返りを追加したいと思います。

やり方は横方向の時と同じです、縦方向になっただけなので全体コード書いて追加した部分を簡単に説明します。

from scene import *

class MyScene(Scene):
	def setup(self):
		self.background_color = 'black'
		self.x = 100
		self.y = 100
		self.ball = SpriteNode('pzl:BallBlue', position=(self.x, self.y))
		self.w = self.ball.size.width
		self.h = self.ball.size.height
		self.x_speed = 1
              #①
		self.y_speed = 1
		self.add_child(self.ball)
		
		
	def update(self):
		self.x += self.x_speed
              #②
		self.y += self.y_speed
		self.ball.position = (self.x, self.y)
		if (self.x + self.w / 2) > self.size.width:
			self.x_speed *= -1
		elif (self.x - self.w / 2) < 0:
			self.x_speed *= -1
              #③
		elif (self.y + self.h / 2) > self.size.height:
			self.y_speed *= -1
		elif (self.y - self.h / 2) < 0:
			self.y_speed *= -1

run(MyScene())

#①
self.y_speed = 1 を追加。

#②
self.y += self.y_speed を追加。

#③
elif文で縦方向の跳ね返りの為の分岐処理を書いています。

これでボールが画面内をずっと跳ね返り続けるプログラムが完成しました!
右上の▷ボタンを押して実行してみましょう!

ちゃんと跳ね返ってますね!
ノードを移動させるプログラムの完成です!

次回は[初心者向け]Pythonista3のsceneでゲーム作成〜当たり判定〜です!

まとめ的なやつ

少し長かったですがsceneで『モノを移動させる』方法がある程度分かっていただけたと思います。

普通でしたらボールはボールでクラスを定義して、それをメインのプログラムでインスタンス化して、ボールクラスで作成した属性やメソッドで移動などの処理をさせるのが良いと思います。

今回は説明という事でこのようなやり方にしました。

ノードを移動させるにはノードの座標を属性として持っておいてそれをupdateメソッド内で変化させてからpositionに再割り当てする事で動くんでしたね。

スピードの属性を新たに作って、ノードが壁に当たるとスピードに-1を掛ける事でボールの向きが反転するので跳ね返らせる事が出来ましたね。

今回説明した内容は、ゲームなどを作る際によく使うようなやり方だと思うので是非参考にして、あなただけのゲームを制作する時に活かしてください!

長くなりましたが、最後まで読んでいただきありがとうございました!
では、またお会いしましょう!

この記事が気に入ったらサポートをしてみませんか?