メインコンテンツへスキップ
見出し画像

【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の方に置いてあります。

    今回はここまで。
    読んでいただきありがとうございました。

    この記事が参加している募集

     
     
    出版社のしがない社内SE。 ここでは主に趣味のプログラミングやゲーム制作について書いています。作ったゲームは https://koidemizu.github.io/ で公開しているのでよかったら遊んでください。 ゲーム大好きインドア派。

    あなたへのおすすめ