evector; sprite neighbor, step

This commit is contained in:
Frank DeMarco 2015-11-28 17:37:48 -05:00
parent bc7d3b9cfb
commit e253306cb1
2 changed files with 97 additions and 12 deletions

View File

@ -9,12 +9,12 @@ from pygame.transform import flip
from pygame.locals import *
from Animation import Animation
from Vector import Vector
from extension import get_hue_shifted_surface
from Vector import Vector, EVector
from extension import get_hue_shifted_surface, get_step
class Sprite(Animation):
def __init__(self, parent, framerate=None):
def __init__(self, parent, framerate=None, neighbors=[], mass=None):
Animation.__init__(self, parent, self.shift_frame, framerate)
self.frames = []
self.mirrored = False
@ -22,10 +22,12 @@ class Sprite(Animation):
self.locations = []
self.framesets = [Frameset(self, framerate=framerate)]
self.frameset_index = 0
self.neighbors = neighbors
self.mass = mass
self.step = EVector()
self.set_frameset(0)
self.locations.append(Location(self))
self.motion_overflow = Vector()
self.stop()
self.display_surface = self.get_display_surface()
def __getattr__(self, name):
@ -208,21 +210,26 @@ class Sprite(Animation):
for frameset in self.framesets:
frameset.reverse()
def go(self, dx=0, dy=0):
self.go_vector = Vector(dx, dy)
def set_step(self, dx=0, dy=0, magnitude=None, angle=0):
self.step.set_step(dx, dy, magnitude, angle)
def stop(self):
self.go_vector = Vector()
def cancel_step(self):
self.step.set_step(0, 0)
def is_going(self):
return self.go_vector != [0, 0]
def is_stepping(self):
return bool(self.step)
def update(self, areas=None, substitute=None):
Animation.update(self)
if self.is_going():
self.move(*self.go_vector)
if self.is_stepping():
self.move(self.step.dx, self.step.dy)
for neighbor in self.neighbors:
self.move(*get_step(self.location.center, neighbor.location.center,
neighbor.mass))
if self.get_current_frameset().length():
self.draw(areas, substitute)
# for location in self.locations:
# location.update()
def draw(self, areas=None, substitute=None):
for location in self.locations:
@ -253,6 +260,10 @@ class Location(Rect):
overflow[1] -= int(overflow[1])
return excess
def move_to(self, x, y, base=None):
ox, oy = self.apply_motion_overflow(base)
self.move_ip(x - ox, y - oy)
def reset_motion_overflow(self):
self.motion_overflow.place_at_origin()
@ -273,6 +284,18 @@ class Location(Rect):
def is_hidden(self):
return self.hidden
def update(self):
pass
# for neighbor in self.sprite.neighbors:
# if neighbor.mass:
# closest = neighbor.location
# for location in neighbor.locations[1:]:
# if get_distance(self.center, location.center) < \
# get_distance(self.center, closest.center):
# closest = location
# self.move_ip(get_step(self.center, closest.center,
# neighbor.mass))
class Fader(Surface):

View File

@ -1,8 +1,18 @@
from math import pi, degrees
from extension import get_delta, get_distance, get_angle
class Vector(list):
def __init__(self, x=0, y=0):
list.__init__(self, (x, y))
def __repr__(self):
message = "<%f" % self[0]
for value in self[1:]:
message += ", %f" % value
return message + ">"
def __getattr__(self, name):
if name == "x":
return self[0]
@ -48,6 +58,24 @@ class Vector(list):
self.y *= other
return self
def __eq__(self, other):
for sv, ov in zip(self, other):
if value != other[ii]:
return False
return True
def __ne__(self, other):
for sv, ov in zip(self, other):
if value == other[ii]:
return False
return True
def __nonzero__(self):
for value in self:
if bool(value):
return True
return False
def apply_to_components(self, function):
self.x = function(self.x)
self.y = function(self.y)
@ -67,3 +95,37 @@ class Vector(list):
def place_at_origin(self):
self.x = 0
self.y = 0
class EVector(Vector):
def __init__(self, x=0, y=0, dx=0, dy=0, magnitude=None, angle=0):
Vector.__init__(self, x, y)
self.set_step(dx, dy, magnitude, angle)
def set_step(self, dx=0, dy=0, magnitude=None, angle=0):
"""specify angle in radians, counter-clockwise, 0 is up"""
if magnitude is not None:
self.magnitude = magnitude
self.angle = angle
self.dx, self.dy = get_delta(angle, magnitude, False)
else:
self.dx = dx
self.dy = dy
if dx == 0 and dy == 0:
self.magnitude = 0
self.angle = 0
else:
end = self.x + dx, self.y + dy
self.magnitude = get_distance(self, end)
self.angle = -get_angle(self, end) - pi
def __repr__(self):
return "<dx=%.2f, dy=%.2f, m=%.2f, ang=%.2f>" % \
(self.dx, self.dy, self.magnitude, self.angle)
def __nonzero__(self):
return bool(self.magnitude)
def move(self):
self += self.dx, self.dy