The Bird
class inherits from Image
class, a Clock.schedule_interval
will call the update
method of the bird class (method for the continuous fall). It also has on_touch_down
that sets the height of the bird higher than before (discontinuously). There is also a short time image changing effect (Bird facing up after a mouse press, then facing down again after a short time, by the self.fall
increment). I was very careful to not put equation of physics equation, so I only use increments for the motion of the bird.
flappy_down = "flappy_down.png"
flappy_up = "flappy_up.png"
class Bird(Image):
acceleration = NumericProperty(-10/10)
velocity = NumericProperty(0)
def __init__(self):
super().__init__(source = flappy_down)
self.height_frac = 0.5
self.fall = 0
def on_touch_down(self, touch):
self.height_frac += 0.15
self.source = flappy_up
self.fall = 0
def update(self, dt):
self.fall += 1
self.height_frac += -1/100
print(self.height_frac)
self.pos_hint = {'x': 0.5, 'y': self.height_frac}
if self.source != flappy_down and self.fall == 15:
self.source = flappy_down
import random
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.properties import NumericProperty
from kivy.clock import Clock
from kivy.graphics import Rectangle, Color
import random
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.properties import NumericProperty
from kivy.clock import Clock
from kivy.graphics import Rectangle, Color
flappy_down = "/home/asus/Arief_tempo/Tutor_JKT/Python_Tutor/FlappyKivy-master/images/flappy.png"
flappy_up = "/home/asus/Arief_tempo/Tutor_JKT/Python_Tutor/FlappyKivy-master/images/flappyup.png"
class ResetBtn(Button):
def __init__(self):
super().__init__(text = "Reset", halign = "center", valign = "center")
def on_release(self):
super().on_release()
self.parent.reset()
class Bird(Image):
acceleration = NumericProperty(-10/10)
velocity = NumericProperty(0)
def __init__(self):
super().__init__(source = flappy_down)
self.height_frac = 0.5
self.fall = 0
def on_touch_down(self, touch):
self.height_frac += 0.15
self.source = flappy_up
self.fall = 0
def update(self, dt):
self.fall += 1
self.height_frac += -1/100
print(self.height_frac)
self.pos_hint = {'x': 0.5, 'y': self.height_frac}
if self.source != flappy_down and self.fall == 15:
self.source = flappy_down
class Game(FloatLayout):
def __init__(self):
super().__init__()
self.kiwi = Bird()
self.resetbtn = ResetBtn()
self.label = Label(text = "", halign = 'center', valign = 'center', font_size = 100)
self.add_widget(self.kiwi)
self.add_widget(self.resetbtn)
self.add_widget(self.label)
self.kiwi.size_hint = (50/Window.size[0], 50/Window.size[1])
self.kiwi.pos_hint = {'x': 0.5, 'y': 0.5}
self.resetbtn.size_hint = (0.25, 0.1)
self.resetbtn.pos_hint = {'x': 0.05, 'y': 0.85}
self.label.size_hint = (0.5, 0.2)
self.label.pos_hint = {'x': 0.25, 'y': 0.75}
self.walls = []
self.current_wall = None
self.add_random_wall()
def add_wall(self, pos, size, color):
self.rect = Rectangle(pos=pos, size=size)
self.color = Color(*color)
self.canvas.add(self.color)
self.canvas.add(self.rect)
self.walls.append(self.rect)
self.current_wall = self.rect
def add_random_wall(self):
height = random.uniform(100, 400)
pos_y = random.uniform(0, Window.size[1]-400)
self.add_wall((745, pos_y), (50, height), (1, 0.3, 0, 1))
def update(self, dt):
for i in self.walls:
i.pos = (i.pos[0]-100*dt, i.pos[1])
self.walls = [i for i in self.walls if i.pos[0] >= -50]
if self.walls[-1].pos[0] <= 0.5*Window.size[0] - 70:
self.add_random_wall()
print(len(self.walls))
kiwi_windowpos = [self.kiwi.pos_hint['x']*Window.size[0], \
self.kiwi.pos_hint['y']*Window.size[1]]
print(kiwi_windowpos)
if ((self.current_wall.pos[0] <=(kiwi_windowpos[0] + 25) <= self.current_wall.pos[0] + 50) \
and (self.current_wall.pos[1] <=(kiwi_windowpos[1] + 25) <= self.current_wall.pos[1] + self.current_wall.size[1])) \
or (kiwi_windowpos[1] + 25 <= 0) or (kiwi_windowpos[1] + 25 >= Window.size[1]):
self.label.text = "Game Over"
Clock.unschedule(self.kiwi_update)
Clock.unschedule(self.wall_update)
def reset(self):
self.clear_widgets()
for i in self.walls:
del i
del self.current_wall
self.canvas.clear()
Clock.unschedule(self.kiwi_update)
Clock.unschedule(self.wall_update)
self.kiwi = Bird()
self.resetbtn = ResetBtn()
self.label = Label(text = "", halign = 'center', valign = 'center', font_size = 100)
self.add_widget(self.kiwi)
self.add_widget(self.resetbtn)
self.add_widget(self.label)
self.kiwi.size_hint = (50/Window.size[0], 50/Window.size[1])
self.kiwi.pos_hint = {'x': 0.5, 'y': 0.5}
self.resetbtn.size_hint = (0.25, 0.1)
self.resetbtn.pos_hint = {'x': 0.05, 'y': 0.85}
self.label.size_hint = (0.5, 0.2)
self.label.pos_hint = {'x': 0.25, 'y': 0.75}
self.walls = []
self.current_wall = None
self.add_random_wall()
self.kiwi_update = Clock.schedule_interval(self.kiwi.update, 0.01)
self.wall_update = Clock.schedule_interval(self.update, 0.01)
class FlApp(App):
def build(self):
g= Game()
g.kiwi_update = Clock.schedule_interval(g.kiwi.update, 0.01)
g.wall_update = Clock.schedule_interval(g.update, 0.01)
return g
if __name__ == "__main__":
FlApp().run()