changeset 37:9c4bf1f15431

gui stuff
author Rizmari Versfeld <rizziepit@gmail.com>
date Sun, 06 May 2012 22:05:40 +0200
parents 2754c453b39b
children 7e18a67995f6
files data/images/button_down.png data/images/button_normal.png gamelib/gui.py gamelib/gui_base.py gamelib/main.py
diffstat 5 files changed, 261 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
Binary file data/images/button_down.png has changed
Binary file data/images/button_normal.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/gui.py	Sun May 06 22:05:40 2012 +0200
@@ -0,0 +1,31 @@
+import os
+
+import pygame
+from pygame.sprite import Sprite
+
+from gamelib import data
+from gamelib.gui_base import *
+
+
+class ImageDrawable(Drawable):
+  
+  def __init__(self, rect, image):
+    super(ImageDrawable, self).__init__(rect)
+    self.image = image
+    
+  def draw(self, surface):
+    surface.blit(self.image, (self.rect[0], self.rect[1]))
+    
+
+class MainMenuButton(TextButton):
+  WIDTH = 128
+  HEIGHT = 64
+  BACKGROUND_IMAGE_NORMAL = pygame.image.load(data.filepath('images/button_normal.png'))
+  BACKGROUND_IMAGE_DOWN = pygame.image.load(data.filepath('images/button_down.png'))
+  
+  def __init__(self, pos, text):
+    rect = (0, 0, self.WIDTH, self.HEIGHT)
+    drawable_normal = ImageDrawable(rect, self.BACKGROUND_IMAGE_NORMAL)
+    drawable_down = ImageDrawable(rect, self.BACKGROUND_IMAGE_DOWN)
+    super(MainMenuButton, self).__init__((pos[0],pos[1], self.WIDTH, self.HEIGHT), drawable_normal, drawable_down, text)
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/gui_base.py	Sun May 06 22:05:40 2012 +0200
@@ -0,0 +1,171 @@
+import pygame
+from pygame.locals import *
+from pygame import Surface, Rect, Color
+from pygame.font import Font
+
+from gamelib import data
+
+
+# different font sizes
+pygame.font.init()
+font_small = Font(data.filepath('fonts/DejaVuSans.ttf'), 10)
+font_medium = Font(data.filepath('fonts/DejaVuSans.ttf'), 14)
+font_large = Font(data.filepath('fonts/DejaVuSans.ttf'), 18)
+
+
+class Drawable(object):
+  
+  def __init__(self, rect):
+    if isinstance(rect, Rect):
+      self.rect = rect
+    else:
+      self.rect = Rect(rect[0],rect[1],rect[2],rect[3])
+    
+  def draw(self, surface):
+    pass
+  
+  
+class Clickable(object):
+  
+  def on_mouse_down(self, pos):
+    pass
+  
+  def on_mouse_up(self, pos):
+    pass
+  
+  def on_mouse_move(self, pos):
+    pass
+  
+  def on_mouse_cancel(self):
+    pass
+  
+  def on_click(self):
+    pass
+ 
+
+class ContainerView(Drawable):
+  
+  def __init__(self):
+    self.children = []
+    
+  def add_child(self, child):
+    self.children.append(child)
+    
+  def remove_child(self, child):
+    self.children.remove(child)
+    
+  def get_child_by_pos(self, pos):
+    for child in self.children:
+      if child.rect.collidepoint(pos):
+	if isinstance(child, ContainerView):
+	  # calculates position relative to child
+	  return child.get_child_by_pos((pos[0] - child.rect[0], pos[1] - child.rect[1]))
+	else:
+	  return child
+  
+  def draw_children(self, surface):
+    for child in self.children:
+      child.draw(surface)
+    
+  
+class Window(Clickable, ContainerView):
+  
+  def __init__(self, screen):
+    super(Window, self).__init__()
+    self.surface = Surface((screen.get_width(), screen.get_height()))
+    self.background_colour = None
+    self.background_image = None
+    self.pressed_child = None
+    
+  def on_mouse_down(self, pos):
+    child = self.get_child_by_pos(pos)
+    if isinstance(child, Clickable):
+       # calculates position relative to child
+      child.on_mouse_down((pos[0] - child.rect[0], pos[1] - child.rect[1]))
+      self.pressed_child = child
+      
+  def on_mouse_up(self, pos):
+    if self.pressed_child:
+      child = self.pressed_child
+      child.on_mouse_up((pos[0] - child.rect[0], pos[1] - child.rect[1]));
+      self.pressed_child = None
+      
+  def on_mouse_move(self, pos):
+    if self.pressed_child and self.pressed_child != self.get_child_by_pos(pos):
+      self.pressed_child.on_mouse_cancel()
+      self.pressed_child = None
+    
+  def draw(self, screen):
+    if self.background_colour:
+      self.surface.fill(self.background_colour)
+    if self.background_image:
+      self.surface.blit(self.background_image, (0,0))
+    self.draw_children(self.surface)
+    screen.blit(self.surface, (0,0))
+    
+
+class StateDrawable(Drawable):
+  
+  def __init__(self, rect):
+    super(StateDrawable, self).__init__(rect)
+    self.state = -1
+    self.states = {}
+    self.drawables = []
+    self.surface = Surface((self.rect[2], self.rect[3]))
+    
+  def draw(self, surface):
+    if self.state != -1 and self.drawables[self.state]:
+      self.drawables[self.state].draw(surface)
+      
+  def add_state(self, state_name, drawable):
+    self.states[state_name] = len(self.drawables)
+    self.drawables.append(drawable)
+    
+  def set_state(self, state_name):
+    self.state = self.states[state_name]
+    
+    
+class Button(Clickable, StateDrawable):
+  
+  def __init__(self, rect, normal_drawable, down_drawable):
+    super(Button, self).__init__(rect)
+    self.add_state('NORMAL', normal_drawable)
+    self.add_state('DOWN', down_drawable)
+    self.set_state('NORMAL')
+    
+  def on_mouse_down(self, pos):
+    self.set_state('DOWN')
+  
+  def on_mouse_up(self, pos):
+    self.set_state('NORMAL')
+    self.on_click()   
+  
+  def on_mouse_cancel(self):
+    self.set_state('NORMAL')
+    
+    
+class TextButton(Button):
+
+  def __init__(self, rect, normal_drawable, down_drawable, text):
+    super(TextButton, self).__init__(rect, normal_drawable, down_drawable)
+    self.surface = Surface((rect[2],rect[3]))
+    self.text = text
+    font_large.set_bold(True)
+    self.text_surface = font_large.render(self.text, True, (128,128,128,128))
+    shadow = font_large.render(self.text, True, (0,0,0,255))
+    font_large.set_bold(False)
+    self.text_surface.blit(shadow, (-2, -2))
+    size = font_large.size(self.text)
+    self.text_offset = ((rect[2]-size[0])/2, (rect[3]-size[1])/2)
+    
+  def draw(self, surface):
+    self.surface.fill((0,0,0,0))
+    super(TextButton, self).draw(self.surface)
+    self.surface.blit(self.text_surface, self.text_offset)
+    surface.blit(self.surface, self.rect)
+
+    
+    
+  
+  
+  
\ No newline at end of file
--- a/gamelib/main.py	Sun May 06 21:56:21 2012 +0200
+++ b/gamelib/main.py	Sun May 06 22:05:40 2012 +0200
@@ -5,10 +5,66 @@
 Feel free to put all your game code here, or in other modules in this "gamelib"
 package.
 '''
+import pygame
+from pygame.locals import *
+from pygame.event import *
+from pygame.time import Clock
+from pygame import Surface
 
-import data
+from gamelib import data
+
+from gamelib.gui_base import *
+from gamelib.gui import *
 
 
+pygame.init()
+
+FPS = 30
+
+GAME_IS_RUNNING = True
+
+WINDOW_STACK = []
+
+# input variables
+MOUSE_DOWN = False
+  
+  
 def main():
-    print "Hello from your game's main()"
-    print data.load('sample.txt').read()
+  #print data.load('sample.txt').read()
+  clock = Clock()
+  screen = pygame.display.set_mode((800, 600))
+  window = Window(screen)
+  window.background_colour = (0,0,0)
+  button1 = MainMenuButton(((800-128)/2, 200), 'Start')
+  window.add_child(button1)
+  WINDOW_STACK.append(window)
+  while GAME_IS_RUNNING:
+    process_input()
+    draw(screen)
+    clock.tick(FPS)    
+
+    
+def draw(screen):
+  for view in WINDOW_STACK:
+    view.draw(screen)
+  pygame.display.flip()
+   
+   
+def process_input():
+  global MOUSE_DOWN
+  global GAME_IS_RUNNING
+  for event in pygame.event.get():
+    if MOUSE_DOWN:
+      if event.type == MOUSEBUTTONUP:
+	MOUSE_DOWN = False
+	WINDOW_STACK[len(WINDOW_STACK)-1].on_mouse_up(event.pos)
+      elif event.type == MOUSEMOTION:
+	WINDOW_STACK[len(WINDOW_STACK)-1].on_mouse_move(event.pos)
+    elif not MOUSE_DOWN and event.type == MOUSEBUTTONDOWN:
+      MOUSE_DOWN = True
+      WINDOW_STACK[len(WINDOW_STACK)-1].on_mouse_down(event.pos)
+    elif event.type == QUIT:
+      GAME_IS_RUNNING = False
+      
+    
+    
\ No newline at end of file