【pyxel 1.5】pyxelで3D迷路を作ってみる(4)
前回はマップに印をつける機能と、見た目の改善で泡のエフェクトを表示させる機能を作りました。今回はスタートとゴールを設定して、より迷路に近づけていきたいと思います。
前回までの進行具合は以下のnoteをご参照ください。
▲スタート地点はオレンジで表示。到達するとコンソールに「Start position」と表示されるようにしています。
▲ゴールは黄色で表示。到達するとコンソールに「Goal position」と表示されます。
▲マップデータはこんな感じ。スタートとゴールのタイルを新規作成して、配置しています。このタイルの種類を判別して、画面表示の色を変えます。
コード部分を書いていきます。
コード全体が長くなってきたので書くのは変更箇所のみで、なるべく簡潔になるように取り上げます。
今回のメインは「スタートとゴールを判別して壁の色を変える」という点です。そして「壁の色」は2パターンあって、「自分の左右」と「正面の行き止まり」で違った処理をしています。
▲スタート地点でいうと1枚目は自分の左にオレンジの壁があり、2枚目は正面にあります。
まずは、「自分の左右の壁の場合」から書いていきます。
#Draw wall 1------------------------------------------------------------------
if self.wall[0][0] == (1, 0):
pyxel.line(0, 0, 50, 29, 6)
pyxel.line(0, 0, 0, 150, 6)
pyxel.line(0, 150, 50, 121, 6)
pyxel.line(50, 29, 50, 121, 6)
elif self.wall[0][0] == (1, 1):
pyxel.line(0, 0, 50, 29, 9)
pyxel.line(0, 0, 0, 150, 9)
pyxel.line(0, 150, 50, 121, 9)
pyxel.line(50, 29, 50, 121, 9)
elif self.wall[0][0] == (2, 1):
pyxel.line(0, 0, 50, 29, 10)
pyxel.line(0, 0, 0, 150, 10)
pyxel.line(0, 150, 50, 121, 10)
pyxel.line(50, 29, 50, 121, 10)
else:
pyxel.line(0, 29, 50, 29, 6)
pyxel.line(0, 121, 50, 121, 6)
if self.wall[0][1] == (1, 0):
pyxel.line(256, 0, 205, 29, 6)
pyxel.line(256, 150, 205, 121, 6)
pyxel.line(255, 0, 255, 150, 6)
pyxel.line(205, 29, 205, 121, 6)
elif self.wall[0][1] == (1, 1):
pyxel.line(256, 0, 205, 29, 9)
pyxel.line(256, 150, 205, 121, 9)
pyxel.line(255, 0, 255, 150, 9)
pyxel.line(205, 29, 205, 121, 9)
elif self.wall[0][1] == (2, 1):
pyxel.line(256, 0, 205, 29, 10)
pyxel.line(256, 150, 205, 121, 10)
pyxel.line(255, 0, 255, 150, 10)
pyxel.line(205, 29, 205, 121, 10)
else:
pyxel.line(256, 29, 205, 29, 6)
pyxel.line(256, 121, 205, 121, 6)
#-----------------------------------------------------------------------------
▲奥行きが4マスあるので、実際はこれに似たコードが4回出てくるわけですが、抜粋しています。
もともとself.wallには自分の左右4マス前までのタイルの情報が入っているので、これを利用します。(1, 0)は壁、(1, 1)はスタート、(2, 1)はゴールです。処理はほとんど同じですが、pyxel.lineの最後の引数であるカラーコードが違っています。
これで左右の壁は色分けできました。
続いて正面の壁に進みます。
まず、正面の壁は「自分の何マス先に壁があるか」しかデータを持たせていなかったので、ここを直します。init部分での変数定義を以下のように変更。
self.dead_end = 0
↓
self.dead_end = [0, (0, 0)]
▲行き止まりに関する変数のself.dead_endをリスト型にしました。1つ目が何マス先かを格納するところ、2つ目のタプルは壁のタイルの種類です。
変数の修正が終わったので、実際に値を入れる部分も直します。
if self.pos_angle == 1:
for i1 in range(4):
if self.pos[1] - i1 < 0:
break
for i2 in range(2):
p1 = self.pos[1] - (1 * i1)
p2 = self.pos[0] - 1 + (2 * i2)
self.wall[i1][i2] = self.maze[p1][p2]
if self.maze[p1][self.pos[0]] in self.wall_list:
if self.dead_end[0] == 0:
self.dead_end[0] = i1
self.dead_end[1] = self.maze[p1][self.pos[0]]
if self.dead_end[0] > i1:
self.dead_end[0] = i1
self.dead_end[1] = self.maze[p1][self.pos[0]]
elif self.maze[p1][self.pos[0]] == (0, 1):
self.floor[i1] = 1
▲自分の周りの壁を設定する部分です。向いている方向によって処理が変わるので、実際には似たコードが4回出てきます。
正面の壁を設定しているのは以下の部分。
if self.maze[p1][self.pos[0]] in self.wall_list:
if self.dead_end[0] == 0:
self.dead_end[0] = i1
self.dead_end[1] = self.maze[p1][self.pos[0]]
if self.dead_end[0] > i1:
self.dead_end[0] = i1
self.dead_end[1] = self.maze[p1][self.pos[0]]
self.dead_end[0]に壁が何マス先にあるか、self.dead_end[1]に該当のマスの種類を入れています。
行き止まり描画部分も直します。
#Draw Dead-End----------------------------------------------------------------
#print(self.dead_end[1])
if self.dead_end[0] == 0:
pass
elif self.dead_end[0] == 1:
if self.dead_end[1] == (1, 0):
pyxel.rect(50, 29, 156, 93, 0)
pyxel.rectb(50, 29, 156, 93, 6)
elif self.dead_end[1] == (1, 1):
pyxel.rect(50, 29, 156, 93, 0)
pyxel.rectb(50, 29, 156, 93, 9)
elif self.dead_end[1] == (2, 1):
pyxel.rect(50, 29, 156, 93, 0)
pyxel.rectb(50, 29, 156, 93, 10)
elif self.dead_end[0] == 2:
if self.dead_end[1] == (1, 0):
pyxel.rect(80, 45, 96, 61, 0)
pyxel.rectb(80, 45, 96, 61, 12)
elif self.dead_end[1] == (1, 1):
pyxel.rect(80, 45, 96, 61, 0)
pyxel.rectb(80, 45, 96, 61, 9)
elif self.dead_end[1] == (2, 1):
pyxel.rect(80, 45, 96, 61, 0)
pyxel.rectb(80, 45, 96, 61, 10)
elif self.dead_end[0] == 3:
if self.dead_end[1] == (1, 0):
pyxel.rect(97, 55, 62, 41, 0)
pyxel.rectb(97, 55, 62, 41, 5)
elif self.dead_end[1] == (1, 1):
pyxel.rect(97, 55, 62, 41, 0)
pyxel.rectb(97, 55, 62, 41, 9)
elif self.dead_end[1] == (2, 1):
pyxel.rect(97, 55, 62, 41, 0)
pyxel.rectb(97, 55, 62, 41, 10)
elif self.dead_end[0] == 4:
if self.dead_end[1] == (1, 0):
pyxel.rect(108, 60, 41, 30, 0)
pyxel.rectb(108, 60, 41, 30, 1)
elif self.dead_end[1] == (1, 1):
pyxel.rect(108, 60, 41, 30, 0)
pyxel.rectb(108, 60, 41, 30, 9)
elif self.dead_end[1] == (2, 1):
pyxel.rect(108, 60, 41, 30, 0)
pyxel.rectb(108, 60, 41, 30, 10)
#-----------------------------------------------------------------------------
▲長くなってしまいましたが、内容はシンプルです。self.dead_end[0]とself.dead_end[1]を見ることで、「何マス先にどんな種類の壁があるか」を判定して、色を変えています。
これで、正面の壁の色分けもできました。
ついでに、スタートとゴールに到着したときにわかるようにしておきます。
if self.pos_angle == 1:
if self.maze[self.pos[1] - 1][self.pos[0]] in self.move_permit:
self.pos[1] = self.pos[1] - 1
self.pos_angle = 1
#Tile Check(Start position)
elif self.maze[self.pos[1] - 1][self.pos[0]] == (1, 1):
print("Start position")
#Tile Check(Goal position)
elif self.maze[self.pos[1] - 1][self.pos[0]] == (2, 1):
print("Goal position")
▲プレイヤーの移動部分の一部抜粋です。進む先がスタートかゴールだったらprintでコンソールにメッセージを表示させます。
とりあえずこれでスタートとゴールは判定できました。
あとはいろいろ肉付けをすればゲームっぽくなりそう。ただ迷路を進むだけじゃ面白くないから、アイテムを集めるとか、敵から逃げながらとか、そんな感じを目指します。
コードやpyxresファイル、モジュールファイルはGitHubの方に置いてあります。
今回はここまで。
読んでいただきありがとうございました。
この記事が参加している募集
ここまで読んでいただきありがとうございます!