SaveText.Ru

BrickBreaker
  1. import tkinter as tk
  2. import random
  3. import math
  4. import copy
  5.  
  6. class Game(tk.Canvas):
  7.     textDisplayed = false
  8.     linesNb = 20
  9.     seconds = 0
  10.     barHeight = 20
  11.     barSpeed = 10
  12.  
  13.     ballSpeed = 7
  14.  
  15.     bricks = []
  16.     bricksWidth = 50
  17.     bricksHeight = 20
  18.     bricksNbByLine = 16
  19.     bricksColors = {
  20.         "r": "#e74c3c",
  21.         "g": "#2ecc71",
  22.         "b": "#3498db",
  23.         "t": "#1abc9c",
  24.         "p": "#9b59b6",
  25.         "y": "#f1c40f",
  26.         "o": "#e67e22",
  27.     }
  28.  
  29.     screenHeight = 500
  30.     screenWidth = bricksWidth * bricksNbByLine
  31.  
  32.     score = 0
  33.  
  34.     def __init__(self, root):
  35.         tk.Canvas.__init__(self, root, bg="#ffffff", bd=0, highlightthickness=0, relief="ridge", width=self.screenWidth,
  36.                            height=self.screenHeight)
  37.         self.pack()
  38.         self.timeContainer = self.create_text(self.screenWidth / 2, self.screenHeight * 4 / 5, text="00:00:00",
  39.                                               fill="#cccccc", font=("Arial", 30), justify="center")
  40.         self.shield = self.create_rectangle(0, 0, 0, 0, width=0)
  41.         self.bar = self.create_rectangle(0, 0, 0, 0, fill="#7f8c8d", width=0)
  42.         self.ball = self.create_oval(0, 0, 0, 0, width=0)
  43.         self.ballNext = self.create_oval(0, 0, 0, 0, width=0, state="hidden")
  44.         self.level(1)
  45.         self.nextFrame()
  46.         global scoreLabel
  47.         scoreLabel = tk.Label(root, text="Score: 0")
  48.         scoreLabel.pack()
  49.  
  50.     def reset(self):
  51.         self.barWidth = 100
  52.         self.ballRadius = 7
  53.         self.coords(self.shield, (0, self.screenHeight - 5, self.screenWidth, self.screenHeight))
  54.         self.itemconfig(self.shield, fill=self.bricksColors["b"], state="hidden")
  55.         self.coords(self.bar, ((self.screenWidth - self.barWidth) / 2, self.screenHeight - self.barHeight,
  56.                                (self.screenWidth + self.barWidth) / 2, self.screenHeight))
  57.         self.coords(self.ball, (
  58.         self.screenWidth / 2 - self.ballRadius, self.screenHeight - self.barHeight - 2 * self.ballRadius,
  59.         self.screenWidth / 2 + self.ballRadius, self.screenHeight - self.barHeight))
  60.         self.itemconfig(self.ball, fill="#2c3e50")
  61.         self.coords(self.ballNext, tk._flatten(self.coords(self.ball)))
  62.         self.effects = {
  63.             "ballFire": [0, 0],
  64.             "barTall": [0, 0],
  65.             "ballTall": [0, 0],
  66.             "shield": [0, -1],
  67.         }
  68.         self.effectsPrev = copy.deepcopy(self.effects)
  69.         self.ballThrown = false
  70.         self.keyPressed = [false, false]
  71.         self.losed = false
  72.         self.won = false
  73.         self.ballAngle = math.radians(90)
  74.         for brick in self.bricks:
  75.             self.delete(brick)
  76.             del brick
  77.  
  78.     def level(self, level):
  79.         self.reset()
  80.         self.levelNum = level
  81.         self.bricks = []
  82.         try:
  83.             file = open(str(level) + ".txt")
  84.             content = list(file.read().replace("n", ""))[:(self.bricksNbByLine * self.linesNb)]
  85.             file.close()
  86.             for i, el in enumerate(content):
  87.                 col = i % self.bricksNbByLine
  88.                 line = i // self.bricksNbByLine
  89.                 if el != ".":
  90.                     self.bricks.append(self.create_rectangle(col * self.bricksWidth, line * self.bricksHeight,
  91.                                                              (col + 1) * self.bricksWidth,
  92.                                                              (line + 1) * self.bricksHeight, fill=self.bricksColors[el],
  93.                                                              width=2, outline="#ffffff"))
  94.  
  95.         except ioerror:
  96.             self.displayText("GAME ENDED INn" + "%02d mn %02d sec %02d" % (
  97.             int(self.seconds) // 60, int(self.seconds) % 60, (self.seconds * 100) % 100), hide=false)
  98.             return
  99.         self.displayText("LEVELn" + str(self.levelNum))
  100.  
  101.     def nextFrame(self):
  102.         if self.ballThrown and not (self.textDisplayed):
  103.             self.moveBall()
  104.  
  105.         if not (self.textDisplayed):
  106.             self.updateTime()
  107.  
  108.         self.updateEffects()
  109.  
  110.         if self.keyPressed[0]:
  111.             self.moveBar(-game.barSpeed)
  112.         elif self.keyPressed[1]:
  113.             self.moveBar(game.barSpeed)
  114.  
  115.         if not (self.textDisplayed):
  116.             if self.won:
  117.                 self.displayText("YOU WIN!", callback=lambda: self.level(self.levelNum + 1))
  118.             elif self.losed:
  119.                 self.displayText("YOU LOSE!", callback=lambda: self.level(self.levelNum))
  120.  
  121.         self.after(int(1000 / 60), self.nextFrame)
  122.  
  123.     def moveBar(self, x):
  124.         barCoords = self.coords(self.bar)
  125.         if barCoords[0] < 10 and x < 0:
  126.             x = -barCoords[0]
  127.         elif barCoords[2] > self.screenWidth - 10 and x > 0:
  128.             x = self.screenWidth - barCoords[2]
  129.  
  130.         self.move(self.bar, x, 0)
  131.         if not (self.ballThrown):
  132.             self.move(self.ball, x, 0)
  133.  
  134.     def moveBall(self):
  135.         self.move(self.ballNext, self.ballSpeed * math.cos(self.ballAngle), -self.ballSpeed * math.sin(self.ballAngle))
  136.         ballNextCoords = self.coords(self.ballNext)
  137.  
  138.         i = 0
  139.         while i < len(self.bricks):
  140.             collision = self.collision(self.ball, self.bricks[i])
  141.             collisionNext = self.collision(self.ballNext, self.bricks[i])
  142.             if not collisionNext:
  143.                 self.score += 1
  144.                 scoreLabel.configure(text=("Score: " + str(self.score)))
  145.                 brickColor = self.itemcget(self.bricks[i], "fill")
  146.                 if brickColor == self.bricksColors["g"]:
  147.                     self.effects["barTall"][0] = 1
  148.                     self.effects["barTall"][1] = 240
  149.                 elif brickColor == self.bricksColors["b"]:
  150.                     self.effects["shield"][0] = 1
  151.                 elif brickColor == self.bricksColors["p"]:
  152.                     self.effects["ballFire"][0] += 1
  153.                     self.effects["ballFire"][1] = 240
  154.                 elif brickColor == self.bricksColors["t"]:
  155.                     self.effects["ballTall"][0] = 1
  156.                     self.effects["ballTall"][1] = 240
  157.  
  158.                 if not (self.effects["ballFire"][0]):
  159.                     if collision == 1 or collision == 3:
  160.                         self.ballAngle = math.radians(180) - self.ballAngle
  161.                     if collision == 2 or collision == 4:
  162.                         self.ballAngle = -self.ballAngle
  163.  
  164.                 if brickColor == self.bricksColors["r"]:
  165.                     self.itemconfig(self.bricks[i], fill=self.bricksColors["o"])
  166.                 elif brickColor == self.bricksColors["o"]:
  167.                     self.itemconfig(self.bricks[i], fill=self.bricksColors["y"])
  168.                 else:
  169.                     self.delete(self.bricks[i])
  170.                     del self.bricks[i]
  171.             i += 1
  172.  
  173.         self.won = len(self.bricks) == 0
  174.  
  175.         if ballNextCoords[0] < 0 or ballNextCoords[2] > self.screenWidth:
  176.             self.ballAngle = math.radians(180) - self.ballAngle
  177.         elif ballNextCoords[1] < 0:
  178.             self.ballAngle = -self.ballAngle
  179.         elif not (self.collision(self.ballNext, self.bar)):
  180.             ballCenter = self.coords(self.ball)[0] + self.ballRadius
  181.             barCenter = self.coords(self.bar)[0] + self.barWidth / 2
  182.             angleX = ballCenter - barCenter
  183.             angleOrigin = (-self.ballAngle) % (3.14159 * 2)
  184.             angleComputed = math.radians(-70 / (self.barWidth / 2) * angleX + 90)
  185.             self.ballAngle = (1 - (abs(angleX) / (self.barWidth / 2)) ** 0.25) * angleOrigin + (
  186.                         (abs(angleX) / (self.barWidth / 2)) ** 0.25) * angleComputed
  187.         elif not (self.collision(self.ballNext, self.shield)):
  188.             if self.effects["shield"][0]:
  189.                 self.ballAngle = -self.ballAngle
  190.                 self.effects["shield"][0] = 0
  191.             else:
  192.                 self.losed = true
  193.  
  194.         self.move(self.ball, self.ballSpeed * math.cos(self.ballAngle), -self.ballSpeed * math.sin(self.ballAngle))
  195.         self.coords(self.ballNext, tk._flatten(self.coords(self.ball)))
  196.  
  197.     def updateEffects(self):
  198.         for key in self.effects.keys():
  199.             if self.effects[key][1] > 0:
  200.                 self.effects[key][1] -= 1
  201.             if self.effects[key][1] == 0:
  202.                 self.effects[key][0] = 0
  203.  
  204.         if self.effects["ballFire"][0]:
  205.             self.itemconfig(self.ball, fill=self.bricksColors["p"])
  206.         else:
  207.             self.itemconfig(self.ball, fill="#2c3e50")
  208.  
  209.         if self.effects["barTall"][0] != self.effectsPrev["barTall"][0]:
  210.             diff = self.effects["barTall"][0] - self.effectsPrev["barTall"][0]
  211.             self.barWidth += diff * 60
  212.             coords = self.coords(self.bar)
  213.             self.coords(self.bar, tk._flatten((coords[0] - diff * 30, coords[1], coords[2] + diff * 30, coords[3])))
  214.         if self.effects["ballTall"][0] != self.effectsPrev["ballTall"][0]:
  215.             diff = self.effects["ballTall"][0] - self.effectsPrev["ballTall"][0]
  216.             self.ballRadius += diff * 10
  217.             coords = self.coords(self.ball)
  218.             self.coords(self.ball, tk._flatten(
  219.                 (coords[0] - diff * 10, coords[1] - diff * 10, coords[2] + diff * 10, coords[3] + diff * 10)))
  220.  
  221.         if self.effects["shield"][0]:
  222.             self.itemconfig(self.shield, fill=self.bricksColors["b"], state="normal")
  223.         else:
  224.             self.itemconfig(self.shield, state="hidden")
  225.  
  226.         self.effectsPrev = copy.deepcopy(self.effects)
  227.  
  228.     def updateTime(self):
  229.         self.seconds += 1 / 60
  230.         self.itemconfig(self.timeContainer, text="%02d:%02d:%02d" % (
  231.         int(self.seconds) // 60, int(self.seconds) % 60, (self.seconds * 100) % 100))
  232.  
  233.     def displayText(self, text, hide=true, callback=none):
  234.         self.textDisplayed = true
  235.         self.textContainer = self.create_rectangle(0, 0, self.screenWidth, self.screenHeight, fill="#ffffff", width=0,
  236.                                                    stipple="gray50")
  237.         self.text = self.create_text(self.screenWidth / 2, self.screenHeight / 2, text=text, font=("Arial", 25),
  238.                                      justify="center")
  239.         if hide:
  240.             self.after(3000, self.hideText)
  241.         if callback != none:
  242.             self.after(3000, callback)
  243.  
  244.     def hideText(self):
  245.         self.textDisplayed = false
  246.         self.delete(self.textContainer)
  247.         self.delete(self.text)
  248.  
  249.     def collision(self, el1, el2):
  250.         collisionCounter = 0
  251.  
  252.         objectCoords = self.coords(el1)
  253.         obstacleCoords = self.coords(el2)
  254.  
  255.         if objectCoords[2] < obstacleCoords[0] + 5:
  256.             collisionCounter = 1
  257.         if objectCoords[3] < obstacleCoords[1] + 5:
  258.             collisionCounter = 2
  259.         if objectCoords[0] > obstacleCoords[2] - 5:
  260.             collisionCounter = 3
  261.         if objectCoords[1] > obstacleCoords[3] - 5:
  262.             collisionCounter = 4
  263.  
  264.         return collisionCounter
  265.  
  266.  
  267. def eventsPress(event):
  268.     global game, hasEvent
  269.  
  270.     if event.keysym == "Left":
  271.         game.keyPressed[0] = 1
  272.     elif event.keysym == "Right":
  273.         game.keyPressed[1] = 1
  274.     elif event.keysym == "space" and not (game.textDisplayed):
  275.         game.ballThrown = true
  276.  
  277.  
  278. def eventsRelease(event):
  279.     global game, hasEvent
  280.  
  281.     if event.keysym == "Left":
  282.         game.keyPressed[0] = 0
  283.     elif event.keysym == "Right":
  284.         game.keyPressed[1] = 0
  285.  
  286. root = tk.Tk()
  287. root.title("Brick Breaker")
  288. root.resizable(0, 0)
  289. root.bind("<Key>", eventsPress)
  290. root.bind("<KeyRelease>", eventsRelease)
  291.  
  292. game = Game(root)
  293. root.mainloop()

Share with your friends:

Print