June 7, 2018♦
from pygame import Color, Surface, draw, PixelArray
from xenographic_wall.pgfw.GameChild import GameChild
class Ring(GameChild, Surface):
transparent_color = Color("magenta")
def __init__(self, parent, index):
GameChild.__init__(self, parent)
self.index = index
self.init_surface()
self.draw_circle()
def init_surface(self):
config = self.get_configuration("scope")
ring_count = config["ring-count"]
width = config["diameter"] / ring_count * (ring_count - self.index)
Surface.__init__(self, (width, width))
color = self.transparent_color
self.fill(color)
self.set_colorkey(color)
rect = self.get_rect()
rect.center = self.parent.center
self.rect = rect
def draw_circle(self):
radius = self.get_width() / 2
draw.circle(self, self.get_neutral_color(), (radius, radius), radius)
def get_neutral_color(self):
return Color(self.get_configuration("scope", "neutral-color"))
def set_color(self, color):
pixels = PixelArray(self)
center = self.get_rect().center
current = pixels[center[0]][center[1]]
pixels.replace(current, color)
del pixels
def get_alpha(self):
return self.alpha
def set_alpha(self, alpha):
self.alpha = alpha
Surface.set_alpha(self, int(alpha))
def update(self):
self.draw()
def draw(self):
self.parent.parent.parent.blit(self, self.rect)
from xenographic_wall.pgfw.GameChild import GameChild
from xenographic_wall.creatures.Creature import Creature
class Creatures(GameChild, list):
def __init__(self, parent):
GameChild.__init__(self, parent)
def reset(self):
list.__init__(self, [])
self.populate()
for creature in self:
creature.reset()
def populate(self):
self.append(Creature(self, 3, 1))
self.append(Creature(self, 3, 2))
self.append(Creature(self, 3, 3))
self.append(Creature(self, 3, 4))
self.append(Creature(self, 3, 5))
self.append(Creature(self, 3, 6))
def update(self):
for creature in self:
creature.update()
from re import search
from os import listdir
from os.path import join, basename
from glob import glob
from time import time
from random import randrange
from math import atan, sin, cos, sqrt, copysign
from pygame import Surface, image, Color
from xenographic_wall.pgfw.GameChild import GameChild
class Creature(GameChild, Surface):
transparent_color = Color("magenta")
def __init__(self, parent, genus_id, species_id):
GameChild.__init__(self, parent)
self.genus_id = genus_id
self.species_id = species_id
self.current_frame_index = 0
self.last_advance = 0
self.load_frames()
self.read_stats()
self.init_surface()
self.reset()
def load_frames(self):
frames = []
root = self.build_species_dir()
for path in sorted(glob(join(root, "*.png"))):
frames.append(Frame(self, path))
self.frames = frames
self.rect = frames[0].get_rect()
def build_species_dir(self):
root = self.get_resource("creature", "root")
genus_dir = glob(join(root, "{0}*".format(self.genus_id)))[0]
return glob(join(genus_dir, "{0}*".format(self.species_id)))[0]
def read_stats(self):
path = join(self.build_species_dir(),
self.get_configuration("creature", "stat-file"))
duration, food, speed = file(path).read().split()
self.eat_duration = int(duration)
self.food = int(food)
self.speed = float(speed)
def init_surface(self):
Surface.__init__(self, self.frames[0].get_size())
self.set_colorkey(self.transparent_color)
def reset(self):
self.place()
self.finish_eating()
self.update_nearest_mushroom()
def finish_eating(self):
self.eat_start_time = None
def update_nearest_mushroom(self):
mushrooms = self.get_mushrooms()
food = self.food
available = mushrooms[food]
nearest = None
for mushroom in available:
if not mushroom.eaten:
distance = self.get_distance_to_mushroom(mushroom)
if not nearest or distance < nearest_distance:
nearest = mushroom
nearest_distance = distance
if not nearest:
nearest = mushrooms.add_mushroom(food)
self.nearest_mushroom = nearest
self.set_path()
def get_mushrooms(self):
return self.parent.parent.mushrooms
def get_distance_to_mushroom(self, mushroom):
start = self.rect.center
end = mushroom.rect.center
return sqrt((end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2)
def set_path(self):
speed = self.speed
start = self.rect.center
end = self.nearest_mushroom.rect.center
x_distance = end[0] - start[0]
y_distance = end[1] - start[1]
if not x_distance and not y_distance:
dx, dy = 0, 0
elif not x_distance:
dx, dy = 0, speed
elif not y_distance:
dx, dy = speed, 0
else:
angle = atan(float(x_distance) / y_distance)
dx = sin(angle) * speed
dy = cos(angle) * speed
self.dx = abs(dx) * copysign(1, x_distance)
self.dy = abs(dy) * copysign(1, y_distance)
self.x_travelled = 0
self.y_travelled = 0
self.path_start = start
def place(self):
area = self.parent.parent.get_rect()
self.rect.topleft = randrange(area.w), randrange(area.h)
def update(self):
self.clear()
self.advance_frame()
self.confirm_nearest_mushroom()
self.eat_mushroom()
self.continue_eating()
self.move()
self.draw()
def clear(self):
self.fill(self.transparent_color)
def advance_frame(self):
current_time = time()
duration = (current_time - self.last_advance) * 100
if duration > self.get_current_frame().duration:
index = self.current_frame_index + 1
if index >= len(self.frames):
index = 0
self.last_advance = current_time
self.current_frame_index = index
def get_current_frame(self):
return self.frames[self.current_frame_index]
def confirm_nearest_mushroom(self):
if not self.is_eating() and self.nearest_mushroom.eaten:
self.update_nearest_mushroom()
def eat_mushroom(self):
location = self.nearest_mushroom.rect
if not self.is_eating() and self.rect.colliderect(location):
self.eat_start_time = time()
self.nearest_mushroom.eat()
def is_eating(self):
return self.eat_start_time is not None
def continue_eating(self):
if self.is_eating():
duration = (time() - self.eat_start_time) * 1000
nearest = self.nearest_mushroom
limit = self.eat_duration
if duration > limit:
self.get_mushrooms().replace_mushroom(nearest)
self.update_nearest_mushroom()
self.finish_eating()
elif duration >= limit / 2 and not nearest.bitten:
nearest.bite()
def move(self):
if not self.is_eating():
rect = self.rect
destination = self.nearest_mushroom
remaining = self.get_distance_to_mushroom(destination)
if remaining < self.speed:
rect.center = destination.center
else:
self.x_travelled += self.dx
self.y_travelled += self.dy
start = self.path_start
rect.centerx = start[0] + self.x_travelled
rect.centery = start[1] + self.y_travelled
self.contain()
def contain(self):
rect = self.rect
area = self.parent.parent.get_rect()
if rect.bottom > area.bottom:
rect.bottom = area.bottom
elif rect.top < area.top:
rect.top = area.top
if rect.right > area.right:
rect.right = area.right
elif rect.left < area.left:
rect.left = area.left
def draw(self):
self.blit(self.get_current_frame().image, (0, 0))
self.parent.parent.blit(self, self.rect)
class Frame(GameChild):
def __init__(self, parent, path):
GameChild.__init__(self, parent)
self.path = path
self.set_image()
self.set_duration()
def set_image(self):
self.image = image.load(self.path).convert_alpha()
def set_duration(self):
separator = self.get_configuration("creature", "field-separator")
self.duration = int(search(separator + "(.*)\.",
basename(self.path)).group(1))
def get_rect(self):
return self.image.get_rect()
def get_size(self):
return self.image.get_size()