Pyxel에서 창고 차례 게임 만들기 (후편)

처음에



이 문서는 Pyxel에서 창고 차례 게임 만들기 (전편)에서 계속됩니다. 이전 기사의 끝에 말씀 드렸듯이 이번에는 상자를 구현합니다.

상자 구현



상자에도 수업을 만드세요. 「좌표」와「이 상자는 움직일까, 움직이지 않는가」(←나중에 사용한다)를 나타내는 클래스 변수를 만듭니다. 그리고 상자는 많이 늘어날지도 모르기 때문에 목록에 클래스를 저장합니다.

box.py
#追加
class Box:
    def __init__(self,x,y):
        #座標
        self.x=x
        self.y=y
        #この箱は動くか、動かないか(←後で使う)
        self.move=0

class App:
    #追加
    #初期座標が16,16と40,16の箱が完成する
    box=[Box(16,16),Box(40,16)]

    #画面描画
    def draw(self):
        #追加
        #箱の描画
        #boxリストの要素数分だけループする
        for box in self.box:
            pyxel.blt(box.x,box.y,0,8,16,8,8,0)

실행 결과


다음은 상자를 누르도록 합시다. 우선 진행 방향에 상자가 있는지를 확인할 필요가 있습니다만, 상자는 벽과 달리 타일 맵상에 배치하고 있지 않기 때문에 타일 맵의 데이터를 취득해 판단한다고 합니다. 방법을 할 수 없습니다. 그래서 플레이어도 상자도 8 도트 단위로 움직인다는 것을 살려, 플레이어의 좌표를 진행 방향으로 8 도트 진행한 것과 상자의 좌표가 일치하면 상자를 누른다(상자가 움직인다)라는 처리로 합니다.
··· 지금도 벽입니다만 벽도 8 도트 단위로 배치하고 있으므로 타일 맵으로부터 데이터를 취득해 판단할 필요도 없네요.... 뭐 그건, 이것이 이것이라고 하는 것으로.
for box in self.box:
    #進行方向に箱があればクラス変数moveをTrueにする
    if (self.player.x+self.move_x*8==box.x) and (self.player.y+self.move_y*8==box.y):
        box.move=1
    #ないならFalseにする
    else
        box.move=0

창고 차례의 룰로서 「한 번에 누르는 상자는 하나만」이라고 하는 것이 있어, 방금전의 처리만으로는 그 룰을 무시해 버리고, 한층 더 벽을 향해 밀어도 상자가 이동해 버리므로 그것 를 막습니다. 클래스 변수의 move가 False가 될 뿐만 아니라 플레이어도 이동하지 않도록 move_count를 0으로 해야 합니다.
for box_2 in self.box:
    #プレイヤーが押そうとした箱の移動方向に箱がある
    if (box.x+self.move_x*8==box_2.x) and\
       (box.y+self.move_y*8==box_2.y) or\
       #もしくはプレイヤーが押そうとした箱の移動方向に壁がある(タイルマップからデータを取得して判断)
       #なら箱もプレイヤーも移動しない
       (pyxel.tilemap(0).get(math.floor(box.x/7)+self.move_x,math.floor(box.y/7)+self.move_y)>=65):
        box.move=0
        self.move_count=0
        break

이러한 것을 전부 연결하면 이렇게 됩니다.

box.py
class App:
    #移動関数
    def move(self,x,y):
            #追加
            for box in self.box:
                #進行方向に箱があればクラス変数moveをTrueにする
                if (self.player.x+self.move_x*8==box.x) and (self.player.y+self.move_y*8==box.y):
                    box.move=1
                    for box_2 in self.box:
                           #プレイヤーが押そうとした箱の移動方向に箱がある、もしくはプレイヤーが押そうとした箱の移動方向に壁がある(タイルマップからデータを取得して判断)なら箱もプレイヤーも移動しない
                            if (box.x+self.move_x*8==box_2.x) and (box.y+self.move_y*8==box_2.y)\
                            or (pyxel.tilemap(0).get(math.floor(box.x/7)+self.move_x,math.floor(box.y/7)+self.move_y)>=65):
                                box.move=0
                                self.move_count=0
                                break
                #箱を押していない時
                else:
                    box.move=0

    #ゲーム管理
    def update(self):
        #ここら辺は以前と同じ
        #カウントが8以上で移動する
        if self.move_count>0:
            self.move_count-=1
            self.player.x+=self.move_x
            self.player.y+=self.move_y
        #ここに追加
            for box in self.box:
                if box.move:
                    box.x+=self.move_x
                    box.y+=self.move_y  

실행 결과


마무리



목표 지점 (파란색 상자) 위에 상자를 놓으면 상자의 색상을 변경합니다 (정확하게는 이미지 표시를 바꿉니다). 벽과 마찬가지로 타일 맵에서 데이터를 가져와 목표 지점에 배치했는지 확인합니다. 그리고 모든 상자가 목표 지점에 놓이면 게임을 종료합니다.

box.py
    #画面描画
    def draw(self):
        #追加 一部命令は前回書いたものと同じなので注意
        self.clear_count=0
        #箱の描画 ゴール地点に置かれた箱は画像が変化する
        for box in self.box:
            if pyxel.tilemap(0).get(round(box.x/8),round(box.y/8))==33:
                pyxel.blt(box.x,box.y,0,8,16,8,8,0)
                self.clear_count+=1
            else:
                pyxel.blt(box.x,box.y,0,0,16,8,8,0)

        #全ての箱をゴール地点に置くとゲームクリア
        if self.clear_count==len(self.box):
            pyxel.rect(11,32,52,36,15)
            pyxel.text(11,32,"GAME CLEAR!",pyxel.frame_count % 16)


실행 결과

클리어해도 게임은 멈추지 않습니다



창고 차례 게임의 최소한은 완성되었습니다. 그러나 실제 게임은 더 다양한 스테이지가 있고, 그 스테이지를 만들어 호출하는 것도 간단하게 해보고 싶네요. 파이썬은 파일을 읽을 수있는 것일지라도 어쩌면 이것으로 스테이지를 만들 수 있을지도?

※일부 기사를 수정했습니다. 시라 카뮤 씨 감사합니다!
Pyxel 공식 매뉴얼

좋은 웹페이지 즐겨찾기