Laser Pinball
From Tmplab
"""A very basic flipper game.
"""
__version__ = "$Id:$"
__docformat__ = "reStructuredText"
import random
import pygame
from pygame.locals import *
from pygame.color import *
import os
import pymunk
from pymunk import Vec2d
def to_pygame(p):
"""Small hack to convert pymunk to pygame coordinates"""
return int(p.x), int(-p.y+600)
# Sound
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
screen = pygame.display.set_mode((600, 600))
clock = pygame.time.Clock()
running = True
print(os.path.join('snd','bumper.ogg'))
try:
# pygame.mixer.music.load(os.path.join('data', 'music.ogg'))#load music
snd_bump = pygame.mixer.Sound(os.path.join('snd','bumper.ogg')) #load sound
except:
raise UserWarning, "could not load or play soundfiles in 'data' folder :-("
### Physics stuff
# To be tinkered with :)
space = pymunk.Space(50)
# To be tinkered with (second only):)
space.gravity = (0.0, -1850.0)
# Define collision callback function, will be called when X touches Y
def bumper_collision(space, arbiter):
snd_bump = pygame.mixer.Sound(os.path.join('snd','bumper.ogg')) #load sound
snd_bump.play()
return True
COLLTYPE_BALL = 1
COLLTYPE_BUMPER = 2
# Setup the collision callback function
space.add_collision_handler(COLLTYPE_BALL, COLLTYPE_BUMPER, bumper_collision, None, None, None)
## Balls
balls = []
### walls
static_body = pymunk.Body()
static_lines = [
# Main Box
pymunk.Segment(static_body, (50, 50.0), (0.0, 600.0), 1.0)
,pymunk.Segment(static_body, (550.0, 50.0), (600.0, 600.0), 1.0)
,pymunk.Segment(static_body, (0.0, 600.0), (300.0, 580.0), 1.0)
,pymunk.Segment(static_body, (300.0, 580.0), (600.0, 600.0), 1.0)
,pymunk.Segment(static_body, (50.0, 50.0), (300.0, 0.0), 1.0)
,pymunk.Segment(static_body, (300.0, 0.0), (550.0, 50.0), 1.0)
# Upper triangle
,pymunk.Segment(static_body, (300.0, 400.0), (220.0, 500.0), 1.0)
,pymunk.Segment(static_body, (300.0, 400.0), (380.0, 500.0), 1.0)
# Lower triangle
,pymunk.Segment(static_body, (300.0, 300.0), (240.0, 360.0), 1.0)
,pymunk.Segment(static_body, (300.0, 300.0), (360.0, 360.0), 1.0)
]
for line in static_lines:
line.elasticity = 0.05
line.group = 1
space.add(static_lines)
# "bumpers"
for p in [
(300,10), # Central
(50,50),(550,50), # Lower
(15,300),(585,300), # Middle
(300,440), # Upper triangle
(300,340), # Lower triangle
]:
body = pymunk.Body()
body.position = p
shape = pymunk.Circle(body, 20)
shape.elasticity = 2
shape.collision_type = COLLTYPE_BUMPER
space.add(shape)
balls.append(shape)
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN and event.key == K_ESCAPE:
running = False
elif event.type == KEYDOWN and event.key == K_p:
pygame.image.save(screen, "flipper.png")
elif event.type == KEYDOWN and event.key == K_b:
# The ball physics
mass = 500
radius = 10
inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0))
body = pymunk.Body(mass, inertia)
# The ball initial position
rand_x = random.randint(1,5)
if (rand_x % 2) :
x = 300 - rand_x
else :
x = 300 + rand_x;
body.position = x, 550
# Draw ball
shape = pymunk.Circle(body, radius, (0,0))
shape.elasticity = 1
shape.collision_type = COLLTYPE_BALL
space.add(body, shape)
balls.append(shape)
### Clear screen
screen.fill(THECOLORS["white"])
### Draw stuff
for ball in balls:
p = to_pygame(ball.body.position)
pygame.draw.circle(screen, THECOLORS["blue"], p, int(ball.radius), 2)
for line in static_lines:
body = line.body
pv1 = body.position + line.a.rotated(body.angle)
pv2 = body.position + line.b.rotated(body.angle)
p1 = to_pygame(pv1)
p2 = to_pygame(pv2)
pygame.draw.lines(screen, THECOLORS["lightgray"], False, [p1,p2])
### Update physics
dt = 1.0/60.0/5.
for x in range(5):
space.step(dt)
### Flip screen
pygame.display.flip()
clock.tick(50)
pygame.display.set_caption("fps: " + str(clock.get_fps()))
