Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- import random
- from pygame.sprite import Group, Sprite
- # Simple state
- class State:
- def __init__(self, engine):
- self.engine = engine
- def on_draw(self, surface):
- pass
- def on_event(self, event):
- pass
- def on_update(self, delta, ticks):
- pass
- # Simple display and state manager
- class DisplayEngine:
- def __init__(self, caption, width, height, flags=0):
- pygame.display.set_caption(caption)
- self.surface = pygame.display.set_mode((width, height), flags)
- self.rect = self.surface.get_rect()
- self.clock = pygame.time.Clock()
- self.running = False
- self.delta = 0
- self.fps = 60
- self.state = State(self)
- self.on_quit = self.quit
- @property
- def width(self):
- return self.rect.width
- @property
- def height(self):
- return self.rect.height
- @property
- def size(self):
- return self.rect.size
- def main_loop(self):
- self.running = True
- while self.running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- self.on_quit()
- else:
- self.state.on_event(event)
- ticks = pygame.time.get_ticks()
- self.state.on_draw(self.surface)
- self.state.on_update(self.delta, ticks)
- pygame.display.flip()
- self.delta = self.clock.tick(self.fps)
- def quit(self):
- self.running = False
- def rnd(start, end):
- return random.randint(start, end) - int(end * 0.5)
- class Ball(Sprite):
- velocity = 0.1
- radius = 7
- def __init__(self, image, position):
- Sprite.__init__(self)
- self.image = image
- self.rect = self.image.get_rect(center=position)
- self.center = pygame.Vector2(self.rect.center)
- self.vector = pygame.Vector2(rnd(0, 21), rnd(0, 21))
- while self.vector == pygame.Vector2():
- self.vector = pygame.Vector2(rnd(0, 21), rnd(0, 21))
- self.vector.normalize_ip()
- def update(self, delta, group):
- self.center += self.vector * delta * Ball.velocity
- self.rect.center = self.center
- for item in group:
- if item != self:
- if isinstance(item, Ball):
- if item.center.distance_to(self.center) < Ball.radius + 1:
- self.vector.reflect_ip(item.vector)
- else:
- if item.rect.colliderect(self.rect):
- self.vector.reflect_ip(item.vector)
- class Wall(Sprite):
- def __init__(self, image, position, vector):
- Sprite.__init__(self)
- self.image = image
- self.rect = image.get_rect(topleft=position)
- self.vector = vector
- class BounceBall(State):
- def __init__(self, engine):
- State.__init__(self, engine)
- self.ball_tick = 2000
- self.ball_timer = self.ball_tick * 2
- self.max_balls = 20
- self.all_sprites = Group()
- self.balls_group = Group()
- self.create_images()
- rect = engine.rect
- self.add_wall("wallh", (0, 0), (0, -1))
- self.add_wall("wallh", (0, rect.h - 10), (0, 1))
- self.add_wall("wallv", (0, 0), (1, 0))
- self.add_wall("wallv", (rect.w - 10, 0), (-1, 0))
- self.add_ball()
- def create_images(self):
- self.images = {}
- size = Ball.radius * 2
- surface = pygame.Surface((size, size), pygame.SRCALPHA)
- surface.fill((0, 0, 0, 0))
- pos = Ball.radius, Ball.radius,
- pygame.draw.circle(surface, pygame.Color("gray40"), pos, Ball.radius)
- self.images['ball'] = surface
- surface = pygame.Surface((self.engine.rect.width, 10))
- surface.fill(pygame.Color("beige"))
- self.images["wallh"] = surface
- surface = pygame.Surface((10, self.engine.rect.height))
- surface.fill(pygame.Color("beige"))
- self.images["wallv"] = surface
- def add_wall(self, name, position, vector):
- wall = Wall(self.images[name], position, vector)
- self.all_sprites.add(wall)
- def add_ball(self):
- ball = Ball(self.images['ball'], self.engine.rect.center)
- self.all_sprites.add(ball)
- self.balls_group.add(ball)
- def on_draw(self, surface):
- surface.fill(pygame.Color('black'))
- self.all_sprites.draw(surface)
- def on_update(self, delta, ticks):
- self.balls_group.update(delta, self.all_sprites)
- if len(self.balls_group) < self.max_balls:
- if ticks > self.ball_timer:
- self.ball_timer = ticks + self.ball_tick
- self.add_ball()
- def main():
- pygame.init()
- engine = DisplayEngine("Bouncing Balls", 800, 600)
- state = BounceBall(engine)
- engine.state = state
- engine.main_loop()
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement