Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmazzone <mazzone.diego@gmail.com>2010-09-23 17:48:35 (GMT)
committer dmazzone <mazzone.diego@gmail.com>2010-09-23 17:48:35 (GMT)
commitd7cec91757c175b58c4fc4014e4ef098f3137705 (patch)
treef17aaafe4e58d671200f2ec5fe24fde3f4b79406
parent5db2dcdf05b878744356df64fd6948a67994f05e (diff)
Controlador de ventanas.
Diccionario de ventanas: Esto es bastante útil para poder "identificar" las ventanas de alguna manera. Por ejemplo, el controlador de ventanas tiene todas las ventanas y los botones se limitan a decirle al controlador que quieren "abrir" determinada ventana con un determinado "key". El stack de ventanas contiene la pila de ventanas "abiertas" siendo la del tope de la pila la “activa” en ese momento y las anteriores marcarían el PATH a esa ventana. Cuando cerramos la activa, se hace un pop de la pila y la ventana que la "abrió" pasa a estar activa. Agregué una clase que representa un botón cerrar que cierra la ventana activa. Cada vez que la main_window pase a ser "activa" es necesario "repintar" el fondo para que no queden rastros de la última ventana activa. Cambios pequeños: *Cambios en módulo de utilidades.
-rwxr-xr-xSaludame.activity/challenges.py59
-rwxr-xr-xSaludame.activity/game.py145
-rwxr-xr-xSaludame.activity/utilities.py26
-rwxr-xr-xSaludame.activity/window.py15
-rw-r--r--Saludame.activity/windowsController.py51
5 files changed, 180 insertions, 116 deletions
diff --git a/Saludame.activity/challenges.py b/Saludame.activity/challenges.py
index 81becca..3e60b9c 100755
--- a/Saludame.activity/challenges.py
+++ b/Saludame.activity/challenges.py
@@ -20,46 +20,55 @@ class MultipleChoice:
self.frame_rate = frame_rate
self.background = pygame.image.load(I_FRANCIA_PATH).convert()
- self.question = Text(self.rect.left + 10, self.rect.top + 5, "Cual es la capital de Francia?")
+ self.question = Text(self.rect.left + 10, self.rect.top + 5, "Cual es la capital de Francia?", 20)
- self.buttons = []
- self.buttons += [Choice(self.rect, 20, 40, 200, 20, "Buenos Aires")]
- self.buttons += [Choice(self.rect, 20, 70, 200, 20, "Oslo")]
- self.buttons += [Choice(self.rect, 20, 100, 200, 20, "Roma")]
- self.buttons += [Choice(self.rect, 20, 130, 200, 20, "Paris")]
- self.buttons += [Choice(self.rect, 20, 160, 200, 20, "Moscu")]
+ # Boton cerrar
+ self.btn_close = CloseButton(self.rect, 770, 5, 30, 30, "X")
+
+ self.choices = []
+ self.choices += [Choice(self.rect, 20, 40, 200, 20, "Buenos Aires")]
+ self.choices += [Choice(self.rect, 20, 70, 200, 20, "Oslo")]
+ self.choices += [Choice(self.rect, 20, 100, 200, 20, "Roma")]
+ self.choices += [Choice(self.rect, 20, 130, 200, 20, "Paris")]
+ self.choices += [Choice(self.rect, 20, 160, 200, 20, "Moscu")]
- self.btn_view_answer = ViewAnswer(self.rect, 20, 200, 200, 20, "Me doy por vencido! :(...", self.buttons[3])
- self.buttons += [self.btn_view_answer]
+ self.btn_view_answer = ViewAnswer(self.rect, 20, 200, 200, 20, "Me doy por vencido! :(...", self.choices[3])
+ self.choices += [self.btn_view_answer]
def draw(self, screen):
screen.fill((150, 150, 255), self.rect)
screen.blit(self.background, (self.rect.right - 230, self.rect.top + 30))
self.question.draw(screen)
+ self.btn_close.draw(screen)
self.btn_view_answer.draw(screen)
- for button in self.buttons:
+ for button in self.choices:
button.draw(screen)
return [self.rect]
- def handle_mouse_down(self, (x, y)):
+ def handle_mouse_down(self, (x, y), windows_controller):
global FIN_MC
- for button in self.buttons: # Hardcodeado para probar, despues lo dejo generico
- if (button.contains_point(x, y) and not FIN_MC):
- fin = button.on_mouse_click() # Fin representa el usuario ya contesto bien o se dio por vencido
- if(fin):
- FIN_MC = fin
- self.buttons = [self.buttons[3], self.buttons[5]]
- break # No tiene sentido seguir iterando sobre los botones si ya sabemos cual apreto
+
+ if (self.btn_close.contains_point(x, y)):
+ self.btn_close.on_mouse_clik(windows_controller)
+
+ else:
+ for choice in self.choices:
+ if (choice.contains_point(x, y) and not FIN_MC):
+ fin = choice.on_mouse_click() # Fin representa el usuario ya contesto bien o se dio por vencido
+ if(fin):
+ FIN_MC = fin
+ self.choices = [self.choices[3], self.choices[5]]
+ break # No tiene sentido seguir iterando sobre los botones si ya sabemos cual apreto
def handle_mouse_over(self, (x, y)):
- for button in self.buttons:
- if (button.contains_point(x, y)):
- if(not button.over):
- button.on_mouse_over()
- button.over = True
+ for choice in self.choices:
+ if (choice.contains_point(x, y)):
+ if(not choice.over):
+ choice.on_mouse_over()
+ choice.over = True
else:
- button.over = False
- button.on_mouse_out()
+ choice.over = False
+ choice.on_mouse_out()
def get_windows(self):
return [self]
diff --git a/Saludame.activity/game.py b/Saludame.activity/game.py
index 90ad70b..7f0eb67 100755
--- a/Saludame.activity/game.py
+++ b/Saludame.activity/game.py
@@ -4,6 +4,7 @@ import pygame
import logging
from gettext import gettext as _
+from windowsController import *
import window
import challenges
@@ -16,84 +17,84 @@ Variables globales
MAX_FPS = 18 # Max frames per second
SLEEP_TIMEOUT = 30 # Seconds until the PauseScreen if no events show up
-def main(fromSugar):
- """Main function of the game.
+class Main():
+ def __init__(self):
+ self.windows_controller = WindowsController()
- This function initializes the game and enters the PyGame main loop.
- """
-
- if fromSugar:
- import gtk
-
- # Optimizes sound quality and buffer for quick loading
- pygame.mixer.pre_init(22050, -16, 8, 256)
-
- # Inits PyGame module
- pygame.init()
-
- target_size = (1200, 780)
-
- if not fromSugar:
- screen = pygame.display.set_mode(target_size)
-
- screen = pygame.display.get_surface()
- assert screen, "No screen"
-
- pygame.display.update()
-
- # This clock is used to keep the game at the desired FPS.
- clock = pygame.time.Clock()
-
- # Stack de ventanas para el control de venta activa
- windows_stack = []
-
- # Challenges Window
- windows_stack.append(challenges.MultipleChoice(pygame.Rect((200, 150), (800, 400)), 1))
- # Main Window
- windows_stack.append(window.MainWindow(clock))
-
- frames = 0
-
- # Main loop
- update = True # The first time the screen need to be updated
- running = True
- while running:
+ def main(self, fromSugar):
+ """Main function of the game.
+
+ This function initializes the game and enters the PyGame main loop.
+ """
if fromSugar:
- # Pump GTK messages.
- while gtk.events_pending():
- gtk.main_iteration()
-
- # Waits for events, if none the game pauses:
- # http://wiki.laptop.org/go/Game_development_HOWTO#Reducing_CPU_Load
- milliseconds = clock.tick(MAX_FPS) # waits if the game is running faster than MAX_FPS
+ import gtk
+
+ # Optimizes sound quality and buffer for quick loading
+ pygame.mixer.pre_init(22050, -16, 8, 256)
- events = pygame.event.get()
+ # Inits PyGame module
+ pygame.init()
- if events:
- for event in events:
- if event.type == pygame.QUIT:
- running = False
- elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
- running = False
- elif event.type == pygame.MOUSEBUTTONDOWN:
- windows_stack[-1].handle_mouse_down(pygame.mouse.get_pos()) # Solo le pasamos los eventos a la ventana activa
-
- windows_stack[-1].handle_mouse_over(pygame.mouse.get_pos()) # Solo le pasamos los eventos a la ventana activa
+ target_size = (1200, 780)
- changes = []
- for win in windows_stack[-1].get_windows(): # Solo actualizamos la ventana activa
- if frames % win.frame_rate == 0:
- changes.extend(win.draw(screen))
-
- if changes:
- pygame.display.update(changes)
- update = False
-
- frames += 1
+ if not fromSugar:
+ screen = pygame.display.set_mode(target_size)
+
+ screen = pygame.display.get_surface()
+ assert screen, "No screen"
+
+ pygame.display.update()
+
+ # This clock is used to keep the game at the desired FPS.
+ clock = pygame.time.Clock()
- # Una vez que sale del loop manda la senal de quit para que cierre la ventana
- pygame.quit()
+ # Challenges Window
+ challenges_window = challenges.MultipleChoice(pygame.Rect((200, 150), (800, 400)), 1)
+ self.windows_controller.add_new_window(challenges_window, "challenges")
+ # Main Window
+ main_window = (window.MainWindow(clock))
+ self.windows_controller.add_new_window(main_window, "main")
+
+ # Activamos ventana principal
+ self.windows_controller.set_active_window("main")
+
+ frames = 0
+
+ # Main loop
+ update = True # The first time the screen need to be updated
+ running = True
+ while running:
+
+ if fromSugar:
+ # Pump GTK messages.
+ while gtk.events_pending():
+ gtk.main_iteration()
+
+ # Waits for events, if none the game pauses:
+ # http://wiki.laptop.org/go/Game_development_HOWTO#Reducing_CPU_Load
+ milliseconds = clock.tick(MAX_FPS) # waits if the game is running faster than MAX_FPS
+
+ events = pygame.event.get()
+
+ if events:
+ for event in events:
+ if event.type == pygame.QUIT:
+ running = False
+ elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
+ running = False
+ elif event.type == pygame.MOUSEBUTTONDOWN:
+ self.windows_controller.handle_mouse_down(pygame.mouse.get_pos())
+
+ self.windows_controller.handle_mouse_over(pygame.mouse.get_pos())
+
+ self.windows_controller.update(frames, screen)
+
+ frames += 1
+
+ # Una vez que sale del loop manda la senal de quit para que cierre la ventana
+ pygame.quit()
+main = Main()
if __name__ == "__main__":
- main(False)
+ main.main(False)
diff --git a/Saludame.activity/utilities.py b/Saludame.activity/utilities.py
index ec1f24c..29d0a27 100755
--- a/Saludame.activity/utilities.py
+++ b/Saludame.activity/utilities.py
@@ -5,15 +5,14 @@
import pygame
class Text:
- def __init__(self, x, y, text):
- self.font = pygame.font.SysFont(None, 16)
+ def __init__(self, x, y, text, size):
+ self.font = pygame.font.SysFont(None, size)
self.ren = self.font.render(text, 1, (0, 0, 100))
self.x = x
self.y = y
def draw(self, screen):
- screen.blit(self.ren, (self.x, self.y))
-
+ screen.blit(self.ren, (self.x, self.y))
class Button:
@@ -25,17 +24,17 @@ class Button:
self.text = text
self.font = pygame.font.SysFont(None, 16)
- self.ren = self.font.render(text, 1, (0, 0, 100))
- self.background_color = (255, 0, 0)
+ self.background_color = (255,0,0)
self.over = False
def contains_point(self, x, y):
return self.rect.collidepoint(x, y)
- def draw(self, screen):
- screen.fill(self.background_color, self.rect)
- screen.blit(self.ren, (self.rect.left + 5, self.rect.top + 5))
+ def draw(self, surface):
+ ren = self.font.render(self.text, 1, (0, 0, 100))
+ surface.fill(self.background_color, self.rect)
+ surface.blit(ren, (self.rect.left + 5, self.rect.top + 5))
def set_background_color(self, color):
self.background_color = color
@@ -50,3 +49,12 @@ class Button:
def on_mouse_out(self):
None
+
+class CloseButton(Button):
+ def __init__(self, rect, x, y, w, h, text):
+ Button.__init__(self, rect, x, y, w, h, text)
+ self.font = pygame.font.SysFont(None, 30) # Modificamos atributo heredado
+ self.background_color = (150, 150, 255) # Modificamos atributo heredado
+
+ def on_mouse_clik(self, windows_controller):
+ windows_controller.close_active_window()
diff --git a/Saludame.activity/window.py b/Saludame.activity/window.py
index 99b9c25..aad9aaa 100755
--- a/Saludame.activity/window.py
+++ b/Saludame.activity/window.py
@@ -135,7 +135,8 @@ class KidWindow(Window):
class MainWindow():
- def __init__(self, clock):
+ def __init__(self, clock):
+ self.name = "main"
self.clock = clock
self.windows = [] # Lista de ventanas que 'componen' la ventana principal
self.windows.append(BlinkWindow(pygame.Rect((700, 0), (500, 140)), 5, pygame.Color("red")))
@@ -146,15 +147,9 @@ class MainWindow():
self.windows.append(menucreator.load_menu())
self.windows.append(animation.FPS(pygame.Rect((650, 80), (50, 20)), 15, self.clock))
- def draw(self):
- changes = []
- for win in self.windows:
- changes += win.draw()
- return changes
-
-
- def handle_mouse_down(self, (x, y)):
- None
+ def handle_mouse_down(self, (x, y), windows_controller):
+ # Temporal para probar el manejo de ventanas entre 'challenges' y 'main'
+ windows_controller.set_active_window("challenges")
def handle_mouse_over(self, (x, y)):
None
diff --git a/Saludame.activity/windowsController.py b/Saludame.activity/windowsController.py
new file mode 100644
index 0000000..3657022
--- /dev/null
+++ b/Saludame.activity/windowsController.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+
+import pygame
+
+"""
+Clase encargada del control de ventanas
+"""
+class WindowsController:
+ def __init__(self):
+ self.windows = {} # Diccionario de ventanas. Aca se encuentran todas las ventanas del programa
+ self.windows_stack = [] # Stack de ventanas para el control de venta activa. Aca se enceuntra el stack de ventanas abiertas
+ self.reload_main = True
+
+ def close_active_window(self):
+ # Solo puede ser llamado por la ventana activa e implica
+ # hacer un pop del stack
+ self.windows_stack.pop()
+ if (self.windows_stack[-1].name == "main"):
+ self.reload_main = True
+
+ def set_active_window(self, window_key):
+ self.windows_stack.append(self.windows[window_key])
+
+ def add_new_window(self, window, window_key):
+ self.windows[window_key] = window
+
+ def handle_mouse_down(self, (x, y)):
+ self.windows_stack[-1].handle_mouse_down((x, y), self)
+ # Se pasa el controlador a si mismo por si el evento es cerrar la ventana
+
+ def handle_mouse_over(self, (x, y)):
+ self.windows_stack[-1].handle_mouse_over((x, y))
+
+ def update(self, frames, screen):
+ """
+ Cada vez que "volvamos" a la ventana principal es necesario
+ repintar el fondo para que no queden rastros de la ventana anterior
+ """
+ if (self.reload_main):
+ screen.fill((0, 0, 0))
+ pygame.display.flip() # Actualizamos el screen para hacer visibles los efectos
+ self.reload_main = False
+
+ changes = []
+ # Una ventana puede estar compuesta de varias ventanas a un mismo nivel
+ for win in self.windows_stack[-1].get_windows():
+ if frames % win.frame_rate == 0:
+ changes.extend(win.draw(screen))
+
+ if changes:
+ pygame.display.update(changes)