import tkinter as tk, math class UltraImpossibleGame: def init(self, root): self.root = root self.root.title("The Impossible Game") self.w, self.h, self.sidebarw, self.gravity, self.jumpforce, self.basespeed, self.groundy = 700, 400, 160, 1.5, -16, 8.5, 280 self.vy, self.isjumping, self.angle, self.active, self.loopid, self.score, self.attempt = 0, False, 0, True, None, 0, 1 self.speed = self.basespeed if not hasattr(self, 'topscores'): self.topscores = [0] * 10 self.blocks, self.spikes = [], [] self.tracklayout = [(400, 's'), (650, 's'), (900, 'b'), (930, 'b'), (1150, 's'), (1350, 'b'), (1500, 's'), (2000, 's'), (2030, 's'), (2300, 'b'), (2330, 'b'), (2450, 's'), (2700, 'b'), (2730, 'u'), (3000, 's'), (3030, 's'), (3300, 'b'), (3330, 'b'), (3360, 'b'), (3550, 's'), (3800, 'b'), (3950, 's'), (3980, 's'), (4200, 'b'), (4230, 'b'), (4350, 's'), (4600, 'b'), (4630, 'b'), (4750, 'b'), (4780, 'b'), (4900, 's'), (4930, 's'), (4960, 's'), (5200, 'b'), (5230, 'u'), (5260, 'b'), (5500, 's'), (5700, 'b'), (5730, 'b'), (5760, 'u'), (6000, 's'), (6030, 's'), (6300, 'b'), (6330, 'b'), (6450, 's'), (6480, 's'), (6800, 'b'), (6830, 'b'), (6860, 'b'), (6890, 'u'), (7100, 's'), (7500, 's'), (7530, 's'), (7560, 's'), (7850, 'b'), (7880, 'u'), (7910, 'b'), (7940, 'u'), (8200, 's'), (8400, 'b'), (8430, 'b'), (8550, 's'), (8580, 's'), (8800, 'b'), (8830, 'u'), (9100, 's'), (9130, 's'), (9160, 's'), (9400, 'b'), (9430, 'b'), (9460, 'b'), (9600, 'u'), (9900, 's'), (10200, 'b'), (10230, 'u'), (10500, 's'), (10530, 's'), (11000, 'b'), (11030, 'b'), (11060, 'b'), (11090, 'b'), (11120, 'u')] self.canvas = tk.Canvas(root, width=self.w + self.sidebarw, height=self.h, bg="#001122", highlightthickness=0) self.canvas.pack() self.setup() self.tick() def setup(self): self.scoretxt = self.canvas.createtext(20, 30, text="PROGRESS: 0%", fill="#fff", font=("Arial", 12, "bold"), anchor="w") self.attempttxt = self.canvas.createtext(self.w - 20, 30, text=f"ATTEMPT {self.attempt}", fill="#fff", font=("Arial", 12, "bold"), anchor="e") self.canvas.createline(0, self.groundy, self.w, self.groundy, fill="#fff", width=3) self.canvas.createrectangle(self.w, 0, self.w + self.sidebarw, self.h, fill="#000b14", outline="#00ffff", width=2) self.canvas.createtext(self.w + 15, 30, text="TOP 10 RUNS", fill="#00ffff", font=("Arial", 11, "bold"), anchor="w") for i, val in enumerate(self.topscores): color = "#ffaa00" if i==0 else "#00ffaa" if i<3 else "#8c9ea3" self.canvas.createtext(self.w + 15, 65 + (i * 28), text=f"{i+1}. {val}%", fill=color, font=("Courier New", 11, "bold"), anchor="w") self.psize = 30 self.px, self.py = 120, self.groundy - self.psize self.playerid = self.canvas.createpolygon(0, 0, 0, 0, 0, 0, 0, 0, fill="#ff4400", outline="#fff", width=2) for x, t in self.tracklayout: if t == 's': self.spikes.append(self.canvas.createpolygon(x, self.groundy, x+15, self.groundy-30, x+30, self.groundy, fill="#fff", outline="#001122")) elif t == 'b': self.blocks.append(self.canvas.createrectangle(x, self.groundy-30, x+30, self.groundy, fill="#002244", outline="#00ffff", width=2)) elif t == 'u': self.blocks.append(self.canvas.createrectangle(x, self.groundy-30, x+30, self.groundy, fill="#002244", outline="#00ffff", width=2)) self.spikes.append(self.canvas.createpolygon(x, self.groundy-30, x+15, self.groundy-60, x+30, self.groundy-30, fill="#fff", outline="#001122")) self.root.bind("<space>", lambda e: self.jump()) self.root.bind("<Up>", lambda e: self.jump()) def jump(self): if not self.isjumping and self.active: self.vy, self.isjumping = self.jumpforce, True def tick(self): if not self.active: return self.vy += self.gravity self.py += self.vy self.score += self.speed self.speed = self.basespeed + (self.score / 3500) self.percentage = min(100, int((self.score / 11500) * 100)) self.canvas.itemconfig(self.scoretxt, text=f"PROGRESS: {self.percentage}%") if self.percentage >= 100: self.active = False self.canvas.createtext(self.w//2, 200, text="THE IMPOSSIBLE CLEARED!", fill="#00ffaa", font=("Arial", 22, "bold")) return self.angle = (self.angle + 9.0) % 360 if self.isjumping else round(self.angle / 90) * 90 if self.py >= self.groundy - self.psize: self.py, self.vy, self.isjumping = self.groundy - self.psize, 0, False cx, cy, r = self.px + 15, self.py + 15, math.radians(self.angle) cosa, sina, h = math.cos(r), math.sin(r), 15 pts = [] for lx, ly in [(-h,-h), (h,-h), (h,h), (-h,h)]: pts.extend([cx + (lx * cosa - ly * sina), cy + (lx * sina + ly * cosa)]) self.canvas.coords(self.playerid, *pts) for s in self.spikes: self.canvas.move(s, -self.speed, 0) for b in self.blocks: self.canvas.move(b, -self.speed, 0) px1, py1, px2, py2 = self.px, self.py, self.px + 30, self.py + 30 onplat = False for b in self.blocks: bbox = self.canvas.bbox(b) if bbox: bx1, by1, bx2, by2 = bbox if px2 > bx1 + 3 and px1 < bx2 - 3: if py2 >= by1 and py2 <= by1 + 12 and self.vy >= 0: self.py, self.vy, self.isjumping, onplat = by1 - 30, 0, False, True elif py2 > by1 + 8 and px2 >= bx1 and px1 < bx1: return self.die() if not onplat and self.py < self.groundy - 30 and self.vy == 0: self.isjumping = True for s in self.spikes: c = self.canvas.coords(s) if c and len(c) >= 6 and px2 > c[0] + 4 and px1 < c[4] - 4: pm = (px1 + px2) / 2 ratio = (pm - c[0]) / (c[2] - c[0]) if pm <= c[2] else (c[4] - pm) / (c[4] - c[2]) if py2 > (c[1] - (ratio * (c[1] - c[3]))) + 4: return self.die() self.loopid = self.root.after(16, self.tick) def die(self): self.active = False if self.loopid: self.root.aftercancel(self.loopid) self.topscores.append(self.percentage) self.topscores = sorted(list(set(self.topscores)), reverse=True)[:10] while len(self.topscores) < 10: self.topscores.append(0) self.canvas.createtext(self.w//2, 170, text="TRY AGAIN", fill="#ff4400", font=("Arial", 28, "bold")) self.canvas.createtext(self.w//2, 215, text=f"Reached: {self.percentage}%", fill="#fff", font=("Arial", 14)) self.root.after(850, self.reset) def reset(self): self.canvas.delete("all") self.spikes.clear() self.blocks.clear() self.vy, self.angle, self.score, self.speed, self.isjumping, self.active, self.attempt = 0, 0, 0, self.base_speed, False, True, self.attempt + 1 self.setup() self.tick() if name == "main": win = tk.Tk() UltraImpossibleGame(win) win.mainloop()
Bình luận