from random import random, choice

from pygame import Color, Rect
from pygame.font import Font

from ball_cup.pgfw.Animation import Animation

class Result(Animation):

    def __init__(self, parent):
        Animation.__init__(self, parent)
        self.display_surface = self.get_display_surface()
        self.background_color = self.parent.color
        self.load_configuration()
        self.set_font()
        self.reset()
        self.register(self.render, self.framerate)

    def load_configuration(self):
        config = self.get_configuration("result")
        self.success_text = config["success-text"]
        self.miss_text = config["miss-text"]
        self.success_colors = self.build_color_list(config["success-colors"])
        self.miss_color = Color(config["miss-color"] + "FF")
        self.font_size = config["font-size"]
        self.margin = config["margin"]
        self.framerate = config["framerate"]
        self.main_color_probability = config["main-color-probability"]
        self.font_path = self.get_resource("result", "font-path")

    def build_color_list(self, colors):
        return [Color(color + "FF") for color in colors]

    def set_font(self):
        self.font = Font(self.font_path, self.font_size)

    def reset(self):
        self.halt(self.render)
        self.deactivate()
        self.rect = Rect(0, 0, 0, 0)

    def deactivate(self):
        self.active = False

    def render(self):
        color = self.color
        if self.text != self.miss_text:
            color = self.get_color()
        surface = self.font.render(self.text, True, color,
                                   self.background_color)
        rect = surface.get_rect()
        relative = self.display_surface.get_rect()
        rect.centerx = relative.centerx
        rect.bottom = relative.bottom - self.margin
        self.surface = surface
        self.rect = rect

    def get_color(self):
        color = self.color
        if random() > self.main_color_probability:
            colors = self.success_colors[:]
            colors.remove(self.color)
            color = choice(colors)
        return color

    def activate(self):
        self.active = True
        self.set_text()
        self.play(self.render)

    def set_text(self):
        proximity = self.parent.proximity
        if proximity is None:
            self.text = self.miss_text
            self.color = self.miss_color
        else:
            text = self.success_text
            count = len(text)
            index = min(count - 1, int(proximity * count))
            self.text = text[index]
            self.color = self.success_colors[index]

    def update(self):
        Animation.update(self)
        if self.active:
            self.draw()

    def clear(self):
        self.parent.clear(self.rect)

    def draw(self):
        self.display_surface.blit(self.surface, self.rect)
from math import sqrt

from pygame import Surface
from pygame.draw import circle
from pygame.locals import *

from ball_cup.pgfw.Animation import Animation
from ball_cup.field.Levels import Levels
from ball_cup.field.Cup import Cup
from ball_cup.field.ball.Ball import Ball
from ball_cup.field.Result import Result
from ball_cup.field.scoreboard.Scoreboard import Scoreboard

class Field(Animation):

    def __init__(self, parent):
        Animation.__init__(self, parent)
        self.delegate = self.get_delegate()
        self.display_surface = self.get_screen()
        self.level_index = 0
        self.waiting_for_key_up = False
        self.ended = False
        self.load_configuration()
        self.set_background()
        self.set_children()
        self.set_max_distance()
        self.draw()
        self.subscribe(self.respond)
        self.subscribe(self.skip, KEYDOWN)
        self.register(self.activate_result, self.submit_result,
                      self.show_game_over)

    def load_configuration(self):
        config = self.get_configuration("field")
        self.color = config["color"]
        self.result_delay = config["result-delay"]
        self.submit_delay = config["submit-delay"]
        self.game_over_delay = config["game-over-delay"]

    def set_background(self):
        background = Surface(self.display_surface.get_size())
        background.fill(self.color)
        self.background = background

    def set_children(self):
        self.levels = Levels(self)
        self.cup = Cup(self)
        self.ball = Ball(self)
        self.result = Result(self)
        self.scoreboard = Scoreboard(self)

    def set_max_distance(self):
        cup_w, cup_h = self.cup.rect.size
        ball_w, ball_h = self.ball.rect.size
        limit = cup_w / 2.0 + ball_w / 2.0 - 1, \
                cup_h / 2.0 + ball_h / 2.0 - 1
        self.max_distance = sqrt(limit[0] ** 2 + limit[1] ** 2)

    def draw(self):
        self.clear(self.display_surface.get_rect())

    def respond(self, event):
        compare = self.delegate.compare
        if compare(event, "reset-game"):
            self.reset()
        if compare(event, "left", cancel=True):
            if self.waiting_for_key_up:
                if self.ended:
                    self.reset()
                else:
                    self.advance_level()

    def reset(self):
        self.advance_level(0)
        self.scoreboard.reset()

    def advance_level(self, index=None):
        if index is None:
            index = self.level_index + 1
        if index >= len(self.levels):
            self.reset()
            return
        self.ended = False
        self.waiting_for_key_up = False
        self.level_index = index
        self.halt(self.activate_result)
        self.halt(self.submit_result)
        self.clear_children()
        self.cup.reset()
        self.ball.reset()
        self.result.reset()
        self.set_max_distance()

    def skip(self, event):
        if self.check_command_line("sk"):
            if event.key == K_UP:
                self.advance_level()
                self.halt()
            elif event.key == K_DOWN:
                self.advance_level(self.level_index - 1)
                self.halt()
            elif event.key == K_RIGHT:
                self.advance_level(self.level_index)
                self.halt()

    def get_current_level(self):
        return self.levels[self.level_index]

    def evaluate(self):
        proximity = None
        cr = self.cup.rect
        br = self.ball.rect
        if br.colliderect(cr):
            target = cr.left + cr.w / 2.0, cr.top + cr.h / 2.0
            position = br.left + br.w / 2.0, br.top + br.h / 2.0
            distance = sqrt((position[0] - target[0]) ** 2 + \
                            (position[1] - target[1]) ** 2)
            proximity = 1 - (distance / self.max_distance)
            self.play(self.submit_result, delay=self.submit_delay,
                      play_once=True)
        else:
            self.play(self.show_game_over, delay=self.game_over_delay,
                      play_once=True)
        self.proximity = proximity
        self.play(self.activate_result, delay=self.result_delay, play_once=True)

    def activate_result(self):
        self.result.activate()
        if self.proximity is None:
            self.scoreboard.reset()

    def submit_result(self):
        self.scoreboard.refresh()
        self.waiting_for_key_up = True

    def show_game_over(self):
        self.ended = True
        self.waiting_for_key_up = True

    def update(self):
        self.clear_children()
        Animation.update(self)
        self.cup.update()
        self.ball.update()
        self.result.update()
        self.scoreboard.update()

    def clear_children(self):
        self.cup.clear()
        self.ball.clear()
        self.result.clear()
        self.scoreboard.clear()

    def clear(self, rect):
        self.display_surface.blit(self.background, rect, rect)
216.73.216.52
216.73.216.52
216.73.216.52
 
August 12, 2013

I've been researching tartan/plaid recently for decoration in my updated version of Ball & Cup, now called Send. I want to create the atmosphere of a sports event, so I plan on drawing tartan patterns at the vertical edges of the screen as backgrounds for areas where spectator ants generate based on player performance. I figured I would make my own patterns, but after browsing tartans available in the official register, I decided to use existing ones instead.

I made a list of the tartans that had what I thought were interesting titles and chose 30 to base the game's levels on. I sequenced them, using their titles to form a loose narrative related to the concept of sending. Here are three tartans in the sequence (levels 6, 7 and 8) generated by an algorithm I inferred by looking at examples that reads a tartan specification and draws its pattern using a simple dithering technique to blend the color stripes.


Acadia


Eve


Spice Apple

It would be wasting an opportunity if I didn't animate the tartans, so I'm thinking about animations for them. One effect I want to try is making them look like water washing over the area where the ants are spectating. I've also recorded some music for the game. Here are the loops for the game over and high scores screens.

Game Over

High Scores