from ball_cup.pgfw.GameChild import GameChild

class Levels(GameChild, list):

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        self.load()

    def load(self):
        for line in file(self.get_resource("levels", "path")):
            fields = line.split()
            args = map(int, fields[:-1]) + [float(fields[-1])]
            self.append(Level(*args))


class Level:

    def __init__(self, *args):
        self.ball_width, self.cup_width, self.cup_speed = args

    def __repr__(self):
        return "{0} {1} {2}".format(self.ball_width, self.cup_width,
                                    self.cup_speed)
from random import randint, choice
from math import sqrt, ceil

from pygame import Surface
from pygame.draw import circle

from ball_cup.pgfw.Sprite import Sprite

class Cup(Sprite):

    up, down = -1, 1

    def __init__(self, parent):
        Sprite.__init__(self, parent)
        self.display_surface = self.get_display_surface()
        self.load_configuration()
        self.reset()

    def load_configuration(self):
        config = self.get_configuration("cup")
        self.color = config["color"]
        self.margin_vertical = config["margin-vertical"]
        self.margin_right = config["margin-right"]

    def reset(self):
        level = self.parent.get_current_level()
        self.halted = False
        self.reset_frame(level.cup_width)
        self.speed = level.cup_speed
        self.set_padding()
        self.set_bounds()
        self.place_in_bounds()
        self.indent()
        self.reset_direction()

    def reset_frame(self, width):
        self.clear_frames()
        frame = Surface((width, width))
        frame.fill(self.color)
        self.add_frame(frame)

    def set_padding(self):
        self.padding = int(ceil(self.get_radius() - self.get_half()))

    def get_radius(self):
        return sqrt(2 * self.get_half() ** 2)

    def get_half(self):
        return self.rect.w / 2.0

    def set_bounds(self):
        display_height = self.display_surface.get_height()
        margin = self.margin_vertical
        self.bounds = margin, display_height - margin

    def place_in_bounds(self):
        upper, lower = self.bounds
        half = self.rect.h / 2
        adjusted = upper + half, lower - half
        self.rect.centery = randint(*adjusted)

    def indent(self):
        self.rect.right = self.display_surface.get_rect().right - \
                          self.margin_right

    def reset_direction(self):
        self.direction = choice([self.up, self.down])

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

    def halt(self):
        self.halted = True

    def update(self):
        if not self.halted:
            self.shift()
        Sprite.update(self)

    def shift(self):
        self.move(dy=self.speed * self.direction)
        overflow = self.collide_with_bounds()
        if overflow is not None:
            self.change_direction()
            self.move(dy=overflow * 2 * self.direction)

    def collide_with_bounds(self):
        rect = self.rect
        upper, lower = self.bounds
        if rect.top <= upper:
            return upper - rect.top
        elif rect.bottom >= lower:
            return rect.bottom - lower

    def change_direction(self):
        direction = self.direction
        if direction == self.up:
            direction = self.down
        else:
            direction = self.up
        self.direction = direction
from pygame import Surface, Rect

from ball_cup.pgfw.Sprite import Sprite
from ball_cup.field.ball.Charge import Charge

class Ball(Sprite):

    forward, backward = 1, -1

    def __init__(self, parent):
        Sprite.__init__(self, parent)
        self.display_surface = self.get_display_surface()
        self.charge = Charge(self)
        self.load_configuration()
        self.set_minimum_size()
        self.reset()

    def load_configuration(self):
        config = self.get_configuration("ball")
        self.color = config["color"]
        self.margin = config["margin"]
        self.base_deceleration = config["base-deceleration"]
        self.base_velocity_range = config["base-velocity-range"]

    def set_minimum_size(self):
        levels = self.parent.levels
        minimum = levels[0].ball_width
        for level in levels[1:]:
            if level.ball_width < minimum:
                minimum = level.ball_width
        self.minimum_size = minimum

    def reset(self):
        self.traveling = False
        self.sent = False
        self.direction = self.forward
        level = self.parent.get_current_level()
        self.reset_frame(level.ball_width)
        self.place()
        self.set_motion_parameters()
        self.charge.reset()

    def set_motion_parameters(self):
        base = self.base_velocity_range
        ratio = self.rect.w / float(self.minimum_size)
        self.velocity_range = ratio * base[0], ratio * base[1]
        self.deceleration = ratio * self.base_deceleration

    def reset_frame(self, width):
        self.clear_frames()
        frame = Surface((width, width))
        frame.fill(self.color)
        self.add_frame(frame)

    def place(self):
        rect = self.rect
        relative = self.display_surface.get_rect()
        rect.centery = relative.centery
        rect.left = relative.left + self.margin

    def send(self):
        self.set_velocity()
        self.traveling = True

    def set_velocity(self):
        strength = self.charge.strength
        lower, upper = self.velocity_range
        self.velocity = strength * (upper - lower) + lower

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

    def update(self):
        if not self.traveling and not self.sent:
            self.charge.update()
        elif self.traveling:
            self.shift()
            self.get_current_frame().fill(self.color)
            self.collide_with_cup()
        Sprite.update(self)

    def shift(self):
        self.move(self.velocity * self.direction)
        if self.rect.right >= self.display_surface.get_rect().right:
            self.direction = self.backward
            self.move(self.display_surface.get_rect().right - self.rect.right)
        if self.rect.right < 0:
            self.velocity = 0
        self.decelerate()
        if self.velocity <= 1:
            self.traveling = False
            self.parent.cup.halt()
            self.sent = True
            self.parent.evaluate()

    def decelerate(self):
        self.velocity = max(0, self.velocity - self.deceleration)

    def collide_with_cup(self):
        rect = self.rect
        relative = self.parent.cup.rect
        if rect.colliderect(relative):
            clip = rect.clip(relative)
            section = Rect((clip.x - rect.x, clip.y - rect.y), clip.size)
            self.get_current_frame().fill((255, 255, 255), section)
3.147.42.197
3.147.42.197
3.147.42.197
 
June 6, 2016