#!/bin/python3 from pygame import Surface, draw, Rect, key, image, transform from pygame.locals import K_SPACE, K_LEFT, K_RIGHT from engine.game import Game from engine.scene import Scene from engine.entity import Entity from engine.components.collide_rect import CollideRect from engine.components.sprite import Sprite from engine.servers.graphics import GraphicsServer from engine.scene_manager import SceneManager W = 400 H = 600 def clamp(val, a, b): return min(max(a, val), b) class Level(Entity): def __init__(self): super().__init__('level') def load(self): surf = Surface((W, H)) surf.fill((0, 40, 0)) GraphicsServer().resize((W, H)) self.add(Sprite(surf, 0)) class PlatForm(Entity): W = 60 H = 20 def __init__(self): super().__init__('platform') self.x = PlatForm.W//2 - 30 self.y = H - PlatForm.H self.script = PlatForm.update def load(self): surf = Surface((PlatForm.W, PlatForm.H)) surf.fill((0, 255, 138)) self.add(Sprite(surf, 2)) self.phys = self.add(CollideRect( Rect(self.x, self.y, PlatForm.W, PlatForm.H), static=False, solid=True)) def update(self): inputs = key.get_pressed() self.phys.vx = 0 if inputs[K_LEFT] and self.x > 0: self.phys.vx = -4 if (inputs[K_RIGHT] and self.x + PlatForm.W < W): self.phys.vx = 4 if inputs[K_SPACE]: ball = SceneManager().scene.entities['ball'] if ball.attached: ball.attached = False ball.phys.vy = -Ball.SPEED class Block(Entity): SIZE = 20 surf = Surface((SIZE, SIZE)) surf.fill((20, 136, 165)) draw.rect(surf, (20, 65, 75), Rect(1, 1, SIZE-2, SIZE-2)) def __init__(self, x, y): super().__init__(self.__repr__()) self.x = x self.y = y def load(self): self.add(Sprite(Block.surf, 1)) self.add(CollideRect( Rect(self.x, self.y, self.SIZE, self.SIZE), solid=True, cb=self.cb)) def cb(self, c): self.unregister() class Ball(Entity): SPEED = 5 SIZE = 20 surf = Surface((SIZE, SIZE)) surf.fill((0, 160, 255)) def __init__(self, x, y): super().__init__('ball') self.script = Ball.update self.x = x self.y = y self.attached = True self.last_col = 0 def load(self): self.add(Sprite(Ball.surf, 3)) self.phys = self.add(CollideRect( Rect(self.x, self.y, Ball.SIZE, Ball.SIZE), static=False, cb=self.cb, friction=1)) def cb(self, c): if c.parent.name == 'platform': plat_center = c.parent.x + PlatForm.W//2 center = self.x + Ball.SIZE//2 self.phys.vx = (center - plat_center) // 8 if Game.cur_tick == self.last_col: return self.last_col = Game.cur_tick def update(self): if self.attached: plat = SceneManager().scene.entities['platform'] self.x = plat.x + PlatForm.W//2 - Ball.SIZE//2 if self.x < 0 or self.x > W - Ball.SIZE: self.phys.vx = -self.phys.vx if self.y + Ball.SIZE < 0 or self.y > H: print('Perdu !') exit(0) self.phys.vx = clamp(self.phys.vx, -5, 5) class BreakOut(Scene): def load(self): self.add(Level()) p = self.add(PlatForm()) self.add(Ball(p.x + PlatForm.W//2 - Ball.SIZE//2, p.y - Ball.SIZE)) for y in range(0, 10*Block.SIZE, Block.SIZE): for x in range(0, W, Block.SIZE): self.add(Block(x, y)) super().load() Game(BreakOut()).run()