I'm currently working in my free time collaborating with a friend on their project which is a flappy bird like game. The first task was to rewrite the code in order to make it more scalable and easy to read. I've done some progress but I can't get the moving parts of the game work.
After some research of how to organize the code I've stumbled on in the following thread and it worked for most of the project, an example of how I've structured my code:
The game.py
on the root project runs the game normally just by executing it. The rewritten code is composed of the app.py
, the entities
and screens
folder.
Structure:
.
|-- app.py
|-- entities
| |-- lean.py
| `-- trapper.py
|-- game.py
|-- lean.py
|-- requirements.txt
|-- screens
| `-- game.py
`-- trapper.py
app.py:
import tkinter as tk
from screens import Game_screen
class Main_application(tk.Frame):
'''Creates the application frame
Args:
parent: The root of the application.
'''
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, *kwargs)
self.parent = parent
# <TODO: The rest of the application >
self.game_screen = Game_screen(self)
if __name__ == '__main__':
root = tk.Tk()
Main_application(root).pack(
side = 'top',
fill = 'both',
expand = True
)
root.mainloop()
screens/game.py
import tkinter as tk
from entities import Lean
from entities import Trapper
gravity = 10
height = 600
width = 400
speed = 35 # (0 == faster | 0 > slower)
class Game_screen(tk.Frame):
'''Generates the Game Screen.
Args:
master: The application frame.
'''
def __init__(self, master=None, *args, **kwargs):
# Background creation
self.canvas = tk.Canvas(
master,
width = width,
height = height,
bg ='cyan'
)
self.canvas.pack()
# Player instance
self.trapper = Trapper(
width,
height,
10,
10,
gravity
)
# Obstacle instance
self.lean = Lean(
height,
30,
150,
height
)
self.init = 0
self.speed = speed
self.score = 0
# Player creation
self.trapper_obj = self.canvas.create_oval(
self.trapper.x - self.trapper.size,
self.trapper.y - self.trapper.size,
self.trapper.x + self.trapper.size,
self.trapper.y + self.trapper.size,
fill="yellow",
tags="trapper"
)
master.bind('<Up>', self.comandoUp)
# Obstacle creation
self.lean_obj_top = self.canvas.create_polygon(
self.lean.get_lean_top(),
fill='purple',
tags='lean_top'
)
# Obstacle creation
self.lean_obj_bot = self.canvas.create_polygon(
self.lean.get_lean_bot(),
fill='purple',
tags='lean_bot'
)
# Score
self.canvas.create_text(
(width-60, 20),
text='score: {}'.format(
self.score
)
)
# Start game
if(self.init == 1):
self.trapper.moveUp()
self.trapper.moveDown()
self.lean.move(self.trapper.vHor)
# Side-scroller
if(self.lean.x < -self.lean.l):
self.lean = Lean(height, 30, 150, width)
# Collision
pos_t = self.canvas.bbox(self.trapper_obj)
collision = self.canvas.find_overlapping(
pos_t[0],
pos_t[1],
pos_t[2],
pos_t[3]
)
for x in collision:
tagx = self.canvas.gettags(x)[0]
if tagx == 'lean_top' or tagx == 'lean_bot':
print("Hit the pipe")
quit()
elif tagx == 'mid':
self.score += self.lean.score
if self.lean.score == 1:
print(self.score)
self.lean.score = 0
if self.trapper.y > height:
print("Fell off")
quit()
# Render and moves scenario
self.canvas.after(self.speed)
master.update_idletasks()
master.update()
def comandoUp(self, event):
self.trapper.up = 6
self.init = 1
Most of the elements are displayed on the screen, but they are static and I couldn't find a solution during the whole weekend. If the information provided isn't enough I provide a link to my repository for better understanding.