Browse Source

Finished writing the NodeSprite class. Lots of smaller tweaks to other Node classes to accomodate. UNTESTEDgit add .

master
Bryan Miller 7 years ago
parent
commit
d91500e9b1
1 changed files with 194 additions and 43 deletions
  1. +194
    -43
      game/gbe/nodes.py

+ 194
- 43
game/gbe/nodes.py View File



from .display import Display from .display import Display
from .events import Events from .events import Events
from .resource import Manager
from .resource import ResourceManager
import pygame import pygame




self._NODE_DATA={ self._NODE_DATA={
"parent":None, "parent":None,
"name":name, "name":name,
"children":[]
"children":[],
"resource":None "resource":None
} }
if parent is not None: if parent is not None:
Node.__init__(self, name, parent) Node.__init__(self, name, parent)
except NodeError as e: except NodeError as e:
raise e raise e
self._NODE2D_DATA={
"position":[0.0, 0.0]
}


def _render(self, surface):
Node._render(self, surface)
@property
def position(self):
p = self._NODE2D_DATA["position"]
return (p[0], p[1])
@position.setter
def position(self, pos):
if not isinstance(pos, (list, tuple)):
raise TypeError("Expected a list or tuple.")
if len(pos) != 2:
raise ValueError("Wrong number of values given.")
try:
self.position_x = pos[0]
self.position_y = pos[1]
except Exception as e:
raise e

@property
def position_x(self):
return self._NODE2D_DATA["position"][0]
@position_x.setter
def position_x(self, v):
if not isinstance(v, (int, float)):
raise TypeError("Excepted an number value.")
self._NODE2D_DATA["position"][0] = float(v)

@property
def position_y(self):
return self._NODE2D_DATA["position"][1]
@position_y.setter
def position_y(self, v):
if not isinstance(v, (int, float)):
raise TypeError("Excepted an number value.")
self._NODE2D_DATA["position"][1] = float(v)


def _callOnRender(self, surface):
if hasattr(self, "on_render"): if hasattr(self, "on_render"):
self._ACTIVE_SURF = surface self._ACTIVE_SURF = surface
self.on_render() self.on_render()
del self._ACTIVE_SURF del self._ACTIVE_SURF


def _render(self, surface):
self._callOnRender(surface)
Node._render(self, surface)

def draw_image(self, img, pos=(0,0), rect=None): def draw_image(self, img, pos=(0,0), rect=None):
if not hasattr(self, "_ACTIVE_SURF"): if not hasattr(self, "_ACTIVE_SURF"):
return return
except NodeError as e: except NodeError as e:
raise e raise e
# TODO: Update this class to use the _NODE*_DATA={} structure. # TODO: Update this class to use the _NODE*_DATA={} structure.
self._offset = (0.0, 0.0)
self._scale = (1.0, 1.0) self._scale = (1.0, 1.0)
self._scaleToDisplay = False self._scaleToDisplay = False
self._scaleDirty = False self._scaleDirty = False


@property @property
def height(self): def height(self):
return self.resolution[1]

@property
def offset(self):
return self._offset
@offset.setter
def offset(self, offset):
if not isinstance(offset, tuple):
raise TypeError("Expected a tuple")
if len(offset) != 2:
raise ValueError("Expected tuple of length two.")
if not isinstance(offset[0], (int, float)) or not isinstance(offset[1], (int, float)):
raise TypeError("Expected number values.")
self._offset = (float(offset[0]), float(offset[1]))

@property
def offset_x(self):
return self._offset[0]
@offset_x.setter
def offset_x(self, x):
if not isinstance(x, (int, float)):
raise TypeError("Expected number value.")
self._offset = (x, self._offset[1])

@property
def offset_y(self):
return self._offset[1]
@offset_y.setter
def offset_y(self, y):
if not isinstance(y, (int, float)):
raise TypeError("Expected number value.")
self._offset = (self._offset[0], y)
return self.resolution[1]


@property @property
def scale(self): def scale(self):
src = self._tsurface src = self._tsurface


ssize = src.get_size() ssize = src.get_size()
posx = self._offset[0]
posy = self._offset[1]
posx = self.position_x
posy = self.position_y
if self._alignCenter: if self._alignCenter:
if dsize[0] > ssize[0]: if dsize[0] > ssize[0]:
posx += (dsize[0] - ssize[0]) * 0.5 posx += (dsize[0] - ssize[0]) * 0.5
} }


@property @property
def image_width(self):
if self._NODESPRITE_DATA["surface"] is None:
return 0
surf = self._NODESPRITE_DATA["surface"]()
return surf.get_width()

@property
def image_height(self):
if self._NODESPRITE_DATA["surface"] is None:
return 0
surf = self._NODESPRITE_DATA["surface"]()
return surf.get_height()

@property
def sprite_width(self):
return int(self.rect_width * self.scale_x)

@property
def sprite_height(self):
return int(self.rect_height * self.scale_y)

@property
def rect(self): def rect(self):
return (self._NODESPRITE_DATA["rect"][0], return (self._NODESPRITE_DATA["rect"][0],
self._NODESPRITE_DATA["rect"][1], self._NODESPRITE_DATA["rect"][1],
self.rect_width = rect[2] self.rect_width = rect[2]
self.rect_height = rect[3] self.rect_height = rect[3]
except Exception as e: except Exception as e:
raise e
raise e


@property @property
def rect_x(self): def rect_x(self):
if not isinstance(v, int): if not isinstance(v, int):
raise TypeError("Expected integer value.") raise TypeError("Expected integer value.")
self._NODESPRITE_DATA["rect"][0] = v self._NODESPRITE_DATA["rect"][0] = v
self._NODESPRITE_ValidateRect()


@property @property
def rect_y(self): def rect_y(self):
if not isinstance(v, int): if not isinstance(v, int):
raise TypeError("Expected integer value.") raise TypeError("Expected integer value.")
self._NODESPRITE_DATA["rect"][1] = v self._NODESPRITE_DATA["rect"][1] = v
self._NODESPRITE_ValidateRect()




@property @property
if not isinstance(v, int): if not isinstance(v, int):
raise TypeError("Expected integer value.") raise TypeError("Expected integer value.")
self._NODESPRITE_DATA["rect"][2] = v self._NODESPRITE_DATA["rect"][2] = v
self._NODESPRITE_ValidateRect()




@property @property
if not isinstance(v, int): if not isinstance(v, int):
raise TypeError("Expected integer value.") raise TypeError("Expected integer value.")
self._NODESPRITE_DATA["rect"][3] = v self._NODESPRITE_DATA["rect"][3] = v
self._NODESPRITE_ValidateRect()


@property @property
def center(self): def center(self):
@property @property
def scale(self): def scale(self):
return (self._NODESPRITE_DATA["scale"][0], self._NODESPRITE_DATA["scale"][1]) return (self._NODESPRITE_DATA["scale"][0], self._NODESPRITE_DATA["scale"][1])
@scale.setter(self, scale):
@scale.setter
def scale(self, scale):
if not isinstance(scale, (list, tuple)): if not isinstance(scale, (list, tuple)):
raise TypeError("Expected a list or tuple.") raise TypeError("Expected a list or tuple.")
if len(scale) != 2: if len(scale) != 2:
if not isinstance(v, (int, float)): if not isinstance(v, (int, float)):
raise TypeError("Expected number value.") raise TypeError("Expected number value.")
self._NODESPRITE_DATA["scale"][0] = float(v) self._NODESPRITE_DATA["scale"][0] = float(v)
self._NODESPRITE_DATA["scale_dirty"] = True


@property @property
def scale_y(self): def scale_y(self):
if not isinstance(v, (int, float)): if not isinstance(v, (int, float)):
raise TypeError("Expected number value.") raise TypeError("Expected number value.")
self._NODESPRITE_DATA["scale"][1] = float(v) self._NODESPRITE_DATA["scale"][1] = float(v)
self._NODESPRITE_DATA["scale_dirty"] = True


@property @property
def image(self): def image(self):
return self._NODESPRITE_DATA["image"] return self._NODESPRITE_DATA["image"]
@image.setter @image.setter
def image(self, image):
def image(self, src):
src = src.strip()
if self._NODESPRITE_DATA["image"] == src:
return # Nothing to change... lol
if self._NODESPRITE_DATA["image"] != "": if self._NODESPRITE_DATA["image"] != "":
self._NODESPRITE_DATA["surface"] = None # Clear reference to original surface. self._NODESPRITE_DATA["surface"] = None # Clear reference to original surface.
pass
if src != "":
rm = self.resource
try:
if not rm.has("graphic", src):
rm.store("graphic", src)
self._NODESPRITE_DATA["image"] = src
self._NODESPRITE_DATA["surface"] = rm.get("graphic", src)
if self._NODESPRITE_DATA["surface"] is None:
self._NODESPRITE_DATA["image"] = ""
self._NODESPRITE_DATA["rect"]=[0,0,0,0]
else:
# Resetting the rect to identity for the new image.
surf = self._NODESPRITE_DATA["surface"]()
size = surf.get_size()
self._NODESPRITE_DATA["rect"]=[0,0,size[0], size[1]]
except Exception as e:
raise e
else:
self._NODESPRITE_DATA["image"] = ""
self._NODESPRITE_DATA["rect"]=[0,0,0,0]

def _render(self, surface):
# Call the on_render() method, if any
Node2D._callOnRender(self, surface)
# Paint the sprite onto the surface
if self._NODESPRITE_DATA["surface"] is not None:
rect = self._NODESPRITE_DATA["rect"]
scale = self._NODESPRITE_DATA["scale"]
surf = self._NODESPRITE_DATA["surface"]()
# Of course, only bother if we have a surface to work with.
if surf is not None:
# Do some prescaling work, if needed.
if self._NODESPRITE_DATA["scale_dirty"]:
self._NODESPRITE_UpdateScaleSurface(scale, surf)
fsurf = surf # Initial assumption that the surface is also the "frame"
# If we have a "frame" surface, however, let's get it and blit the rect into the frame surface.
if "frame_surf" in self._NODESPRITE_DATA:
fsurf = self._NODESPRITE_DATA["frame_surf"]
fsurf.blit(surf, (0, 0), rect)
# If scaling, then transform (scale) the frame surface into the scale surface and set the frame surface to the scale surface.
if "scale_surf" in self._NODESPRITE_DATA:
ssurf = self._NODESPRITE_DATA["scale_surf"]
pygame.transform.scale(fsurf, ssurf.get_size(), ssurf)
fsurf = ssurf

# Place the sprite! WHEEEEE!
pos = self.position
surface.blit(fsurf, pos)

# Call on all children
Node._render(self, surface)


def _NODESPRITE_UpdateScaleSurface(self, scale, surf):
self._NODESPRITE_DATA["scale_dirty"] = False
ssurf = None
if "scale_surf" in self._NODESPRITE_DATA:
ssurf = self._NODESPRITE_DATA["scale_surf"]

if scale[0] == 1.0 and scale[1] == 1.0:
if ssurf is not None:
del self._NODESPRITE_DATA["scale_surf"]
return
nw = int(self.rect_width * scale[0])
nh = int(self.rect_height * scale[1])

if nw != ssurf.get_width() or nh != ssurf.get_height():
ssurf = pygame.Surface((nw, nh), pygame.SRCALPHA, surf)
ssurf.fill(pygame.Color(0,0,0,0))
self._NODESPRITE_DATA["scale_surf"] = ssurf

def _NODESPRITE_ValidateRect(self):
if self._NODESPRITE_DATA["surface"] is None:
self._NODESPRITE_DATA["rect"] = [0,0,0,0]
else:
rect = self._NODESPRITE_DATA["rect"]
isize = (self.image_width, self.image_height)
if rect[0] < 0:
rect[2] += rect[0]
rect[0] = 0
elif rect[0] >= isize[0]:
rect[0] = isize[0]-1
rect[2] = 0
if rect[1] < 0:
rect[3] += rect[1]
rect[1] = 0
elif rect[1] >= isize[1]:
rect[1] = isize[1]-1
rect[3] = 0
if rect[2] < 0:
rect[2] = 0
elif rect[0] + rect[2] > isize[0]:
rect[2] = isize[0] - rect[0]
if rect[3] < 0:
rect[3] = 0
elif rect[1] + rect[3] > isize[1]:
rect[3] = isize[1] - rect[1]

fssize = [0,0]
if rect[2] > 0 and rect[3] > 0:
if rect[2] < isize[0] or rect[1] < isize[1]:
surf = self._NODESPRITE_DATA["surface"]()
self._NODESPRITE_DATA["frame_surf"] = pygame.Surface((rect[2], rect[3]), pygame.SRCALPHA, surf)
if fssize[0] > 0 and fssize[1] > 0:
pass
elif "frame_surf" in self._NODESPRITE_DATA:
del self._NODESPRITE_DATA["frame_surf"]





Loading…
Cancel
Save