Friday, July 10, 2009

Python - an attempt at pyglet




Pyglet is a cross platform game developement api. Sort of like pygame. The screenshot shows the 'game' in action. I borrowed some code from the pyglet site. This is really just a first attempt at learning pyglet. Make sure to install pyglet before you try and run the example! Below is the main portion of the code, or the link to the full source:


# nice and simple first attempt at pyglet

from pyglet import window
from pyglet import clock
from pyglet import font
import pyglet
import random
import helper # (borrowed from example pygletspace program)
# it just loads images


class TheBounceWindow(window.Window):
def __init__(self, *args, **kwargs):
window.Window.__init__(self, *args, **kwargs)
self.set_mouse_visible(False)
self.init_sprites()
def init_sprites(self):
self.balls = []
self.ball_image = "ball.png" #helper.load_image("ball.png")
self.inactive_ball_image = "aball.png"
self.me_image = "me.png" # this is the player
self.me_ouch = "me.png" # player is hit image
self.me = Player( self.me_image, self.me_ouch, self.height, self.width)
def main_loop(self):
#fps indicator
ft = font.load('Arial', 28)
# text object to display the ft
fps_text = font.Text(ft, y=10)
# some stuff
clock.set_fps_limit(25)
while not self.has_exit:
self.dispatch_events()
self.clear()
self.update()
self.draw()
clock.tick()
fps_text.text = ("fps: %d") % (clock.get_fps())
fps_text.text += (" objects tracked: %s") %(str(len(self.balls)))
fps_text.draw()
self.flip()
#detect collisions
hits = self.me.collide_once(self.balls)
if hits != None:
#hits is the actual sprite that made contact
# should do something with it!
# do here
self.me.hits_i_can_take -= 1
self.me.playOuch()
#print "contact!"
def update(self):
for sprite in self.balls:
sprite.update()
self.me.update()
def draw(self):
for sprite in self.balls:
sprite.draw()
self.me.draw()

"""******************************************
Event Handlers
*********************************************"""
def on_mouse_motion(self, x, y, dx, dy):
self.me.setPoints(x,y)
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
self.me.setPoints(x,y)
def on_mouse_press(self, x, y, button, modifiers):
#print "click: %s, %s" %(str(x), str(y))
#print "button pressed: %s" %(str(button))
self.me.setPoints(x,y)

if (button == 1):
b = Ball(self.ball_image, self.inactive_ball_image, self.height, self.width)
b.setPoints(x,y)
self.balls.append(b)

if (button == 2):
for count in xrange(0,5):
b = Ball(self.ball_image, self.inactive_ball_image, self.height, self.width)
b.setPoints(x,y)
self.balls.append(b)


if (button == 4):
for count in xrange(0,10):
b = Ball(self.ball_image, self.inactive_ball_image, self.height, self.width)
b.setPoints(x,y)
self.balls.append(b)




class Sprite(object):

def __get_left(self):
return self.x
left = property(__get_left)

def __get_right(self):
return self.x + self.image.width
right = property(__get_right)

def __get_top(self):
return self.y + self.image.height
top = property(__get_top)

def __get_bottom(self):
return self.y
bottom = property(__get_bottom)

def __init__(self, image_file, inactive_image_file=None, image_data=None, **kwargs):

#init standard variables
self.image_file = image_file
if (image_data is None):
self.image = helper.load_image(image_file)
else:
self.image = image_data

# inactive image
if (inactive_image_file is None):
# then we don't want one
# just use the regular image
self.inactive_image = self.image
else:
self.inactive_image = helper.load_image(inactive_image_file)
self.x = 10
self.y = 10
self.contact = False
self.active = False
self.dead = False
#Update the dict if they sent in any keywords
self.__dict__.update(kwargs)

def draw(self):
if self.active:
self.image.blit(self.x, self.y)
else:
self.inactive_image.blit(self.x, self.y)

def update(self):
pass

def intersect(self, sprite):
"""Do the two sprites intersect?
@param sprite - Sprite - The Sprite to test
"""
return not ((self.left > sprite.right)
or (self.right <>
or (self.top <>
or (self.bottom > sprite.top))

def collide(self, sprite_list):
"""Determing ther are collisions with this
sprite and the list of sprites
@param sprite_list - A list of sprites
@returns list - List of collisions"""

lst_return = []
for sprite in sprite_list:
if (self.intersect(sprite)):
lst_return.append(sprite)
return lst_return

def collide_once(self, sprite_list):
"""Determine if there is at least one
collision between this sprite and the list
@param sprite_list - A list of sprites
@returns - None - No Collision, or the first
sprite to collide
"""
for sprite in sprite_list:
if (self.intersect(sprite) and sprite.active == True):
sprite.active = False
self.active = False
return sprite
return None


class Ball(Sprite):
def __init__(self, image_data, inactive_image_data, top, right, **kwargs):
self.initial_x_direction = (int(random.random() *10) + 1) %2
self.initial_y_direction = (int(random.random() *10) + 1) %2
if self.initial_x_direction == 1:
self.initial_x_direction = -1
else:
self.initial_x_direction = 1
if self.initial_y_direction == 1:
self.initial_y_direction = -1
else:
self.initial_y_direction = 1
self.y_velocity = (int(random.random() * 10) + 1) * self.initial_x_direction
self.x_velocity = (int(random.random() * 10) + 1) * self.initial_y_direction
# preload sound:
self.sound = pyglet.resource.media('shot.wav', streaming=False)
self.hit_sides = False

#self.velocity = 1
self.screen_top = top
self.screen_right = right
Sprite.__init__(self, image_data,inactive_image_file=inactive_image_data, **kwargs)
def update(self):
#print "%s %s" %(self.top, self.bottom)
if self.top > self.screen_top or self.bottom <>
self.hit_sides = True
self.active = True
self.y_velocity *= -1
if self.right > self.screen_right or self.left <>
self.hit_sides = True
self.active= True
self.x_velocity *= -1
self.y += self.y_velocity
self.x += self.x_velocity
if self.hit_sides:
self.sound.play()
self.hit_sides = False
def setPoints(self, x, y):
self.x = x
self.y = y
class Player(Sprite):
def __init__(self, image_data, image_contact, top, right, **kwargs):

self.screen_top = top
self.screen_right = right
Sprite.__init__(self, image_data, **kwargs)
self.hits_i_can_take = 10
self.sound = pyglet.resource.media('ouch.wav', streaming=False)
self.font = font.load('Arial',28)
self.kill_text = font.Text(self.font, x=20, y=40)
def draw(self):
Sprite.draw(self)
self.kill_text.text = ("Lives : %d") %(self.hits_i_can_take)
self.kill_text.draw()
def playOuch(self):
self.sound.play()
def setPoints(self, x, y):
self.x = x
self.y = y
if __name__ == '__main__':
bball = TheBounceWindow()
bball.main_loop()

No comments:

Post a Comment