Mercurial > sypikslang
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
--- /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