pyxelでFlappy Birdのようなゲームを作る

2020年4月27日月曜日

python

t f B! P L

flappybird

  • 鳥が飛んでる
  • キーを押すとちょっと浮く
  • 右から土管が流れてくる
  • 土管は真ん中が通れるように上下から生えている
  • 鳥が土管に当たったり落下すると死ぬ

ぐらいのふわっとした記憶で作る

使うもの

pip install pyxelなどして用意する

鳥と土管の絵を用意する

pyxeleditorを起動して絵を書く

鳥と土管です

書く

``

import pyxel
import random


class Flappy:
    def __init__(self):
        self.x = 30
        self.y = 30
        self.width = 8
        self.height = 8
        self.velocity = 0.0
        self.state = 'down'

    def update(self):
        if pyxel.btnp(pyxel.KEY_SPACE):
            self.velocity = -4
        else:
            self.velocity += 0.5
        if self.velocity < 0:
            self.state = 'up'
        else:
            self.state = 'down'
        self.y += self.velocity

    def draw(self):
        if self.state == 'down':
            pyxel.blt(self.x, self.y, 0, 0, 0, 8, 8, 0)
        else:
            pyxel.blt(self.x, self.y, 0, 8, 0, 8, 8, 0)


class Pipe():
    def __init__(self, up, down):
        self.x = 160
        self.width = 16
        self.up = up
        self.down = down
        self.speed = 2

    def update(self):
        self.x -= self.speed

    def draw(self):
        # 下側
        pyxel.blt(self.x, self.down, 0, 0, 16, 16, 8, 0)
        for i in range(self.down+8, 120, 8):
            pyxel.blt(self.x, i, 0, 0, 24, 16, 8, 0)

        # 上側
        pyxel.blt(self.x, self.up-8, 0, 16, 24, 16, 8, 0)
        for i in range(self.up-16, -1, -8):
            pyxel.blt(self.x, i, 0, 16, 16, 16, 8, 0)


class App:
    def __init__(self):
        pyxel.init(160, 120)
        pyxel.load('my_resource.pyxres')
        self.flappy = Flappy()
        self.pipes = []
        self.count = 0
        self.score = 0
        self.initialize()
        pyxel.run(self.update, self.draw)

    def initialize(self):
        self.flappy.y = 30
        self.flappy.velocity = 0
        self.flappy.state = 'down'
        self.pipes.clear()
        self.score = 0
        self.count = 0

    def update(self):
        if self.flappy.state == 'dead':
            if pyxel.btnp(pyxel.KEY_Q):
                self.initialize()
            return

        if self.count % 30 == 0:
            up, down = self.get_updown()
            self.pipes.append(Pipe(up, down))

        self.flappy.update()
        for pipe in self.pipes:
            pipe.update()
            # 衝突
            if self.collide(self.flappy, pipe):
                self.flappy.state = 'dead'
            # 左に行った土管を削除
            if pipe.x + pipe.width < 0:
                self.pipes.remove(pipe)
            if pipe.x+8 == self.flappy.x+4:
                self.score += 1

        # 落下
        if self.flappy.y + 8 > 120:
            self.flappy.state = 'dead'

        self.count += 1

    def draw(self):
        pyxel.cls(6)
        self.flappy.draw()
        for pipe in self.pipes:
            pipe.draw()
        if self.flappy.state == 'dead':
            pyxel.text(50, 40, 'PRESS Q to restart', 7)
        # pyxel.text(60, 0, '{}'.format(len(self.pipes)), 7)
        pyxel.text(20, 0, '{}'.format(self.score), 7)

    def collide(self, flappy, pipe):
        if (pipe.x < flappy.x + flappy.width and
                flappy.x < pipe.x + pipe.width):
            if flappy.y < pipe.up or pipe.down < flappy.y + flappy.height:
                return True
        return False

    def get_updown(self):
        up = random.randint(16, 80)
        up -= up % 8
        return up, up + 40


App()

遊ぶ

シンプルでいいゲームですね

QooQ