import arcade, arcade.gui, time, random, os, json from plyer import notification class Game(arcade.gui.UIView): def __init__(self, pypresence_client): super().__init__() self.pypresence_client = pypresence_client self.pypresence_client.update(state="Playing Flappy Bird inside notifications!") self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1))) self.info_label = self.anchor.add(arcade.gui.UILabel("Use space to jump\nYou can see the game inside notifications.", font_size=24, multiline=True), anchor_x="center", anchor_y="center") self.running = True self.should_jump = False self.last_update_time = time.perf_counter() with open("settings.json", "r") as file: self.settings = json.load(file) self.pipes = [] self.bird_position = [0, int(self.settings.get("notification_rows", 20) / 2)] self.cycles = 0 if not os.path.exists("data.json"): self.data = {} else: with open("data.json", "r") as file: self.data = json.load(file) if not "flappy_bird" in self.data: self.data["flappy_bird"] = {"high_score": 0} self.high_score = self.data["flappy_bird"]["high_score"] self.score = 0 def create_pipe_part(self, size, pipe_type): if pipe_type == "bottom": bottom = 0 else: bottom = self.settings.get("notification_rows", 20) - size left = self.settings.get("notification_cols", 25) for pipe_y in range(bottom, bottom + size): self.pipes.append([left, pipe_y]) def create_pipe(self): gap_size = self.settings.get("notification_rows", 20) // 5 gap_start = random.randint(1, self.settings.get("notification_rows", 20) - gap_size - 1) bottom_height = gap_start self.create_pipe_part(bottom_height, "bottom") top_height = self.settings.get("notification_rows", 20) - (gap_start + gap_size) self.create_pipe_part(top_height, "top") def on_update(self, delta_time): if self.running and time.perf_counter() - self.last_update_time >= self.settings.get("notification_timeout", 0.4): self.pipes = [[pipe_x - 1, pipe_y] for pipe_x, pipe_y in self.pipes if pipe_x - 1 >= 0] if self.should_jump: jumped = True self.bird_position[1] -= 3 self.should_jump = False else: jumped = False self.bird_position[1] += 2 if self.bird_position in self.pipes or self.bird_position[1] >= self.settings.get("notification_rows", 20) or self.bird_position[1] <= 0: self.info_label.text = "Game Over.\nPress r to restart" self.running = False notification.notify( title="Flappy Bird inside notifications", message='Game Over!' ) return for pipe in self.pipes: if pipe[0] == self.bird_position[0]: self.score += 1 break self.last_update_time = time.perf_counter() text = "" for y in range(self.settings.get("notification_rows", 20)): for x in range(self.settings.get("notification_cols", 25)): if [x, y] in self.pipes: text += "|" elif [x, y] == self.bird_position: text += "^" if jumped else "^" else: text += "_" text += "\n" if self.score > self.high_score: self.high_score = self.score notification.notify( title=f"Flappy Bird | Score: {self.score} High Score: {self.high_score}", message=text ) if self.cycles == 15: self.cycles = 0 self.create_pipe() self.cycles += 1 def on_show_view(self): super().on_show_view() self.create_pipe() def on_key_press(self, symbol, modifiers): if symbol == arcade.key.ESCAPE: self.data["flappy_bird"]["high_score"] = self.high_score with open("data.json", "w") as file: file.write(json.dumps(self.data, indent=4)) from menus.main import Main self.window.show_view(Main(self.pypresence_client)) elif symbol == arcade.key.SPACE: self.should_jump = True elif symbol == arcade.key.R and not self.running: self.info_label.text = "Press keys inside this window to interact with the game\nYou can see the game inside notifications" self.pipes.clear() self.create_pipe() self.last_update_time = time.perf_counter() self.bird_position = [0, int(self.settings.get("notification_rows", 20) / 2)] self.cycles = 0 self.should_jump = False self.running = True