class ControllerMarker(Counter): """ Subclass of counter to use for markers to indicate controller of permanents. """ # This class needs its own piece_list and radius separate from Counter piece_list = None radius = CONTROLLER_MARKER_RADIUS alpha = anim.Animatable() def __init__(self, color): super(ControllerMarker, self).__init__('controller_marker', color=color) self.alpha = 0.4 # more transparent than regular counters
class Image(Widget): alpha = anim.Animatable() width = property(fget=lambda self: self.img.width * self._final_scale) height = property(fget=lambda self: self.img.height * self._final_scale) def __init__(self, value, pos=euclid.Vector3(0, 0, 0)): super(Image, self).__init__(pos) if isinstance(value, str): self.img = ImageCache.get(value) else: self.img = value self.alpha = anim.animate(1.0, 1.0, dt=1, method="sine") self.color = (1.0, 1.0, 1.0) self._scale = anim.animate(self._final_scale, self._final_scale, dt=0.25, method="sine") def render_after_transform(self): glColor4f(self.color[0], self.color[1], self.color[2], self.alpha) img = self.img img.blit(-img.width / 2, -img.height / 2, 0)
class PlayCard(Card): tapping = anim.Animatable() zooming = anim.Animatable() highlighting = anim.Animatable() def spacing(): def fget(self): if self.is_tapped: return self.height else: return self.width return locals() spacing = property(**spacing()) def __init__(self, gamecard, front, back): super(PlayCard, self).__init__(gamecard, front, back) self.is_creature = False self.draw = self.draw_permanent #self.info_box = Label("", size=12, background=True, shadow=False, valign="top") #self.info_box._pos.set_transition(dt=0.4, method="sine") #self.info_box.pos = euclid.Vector3(self.width/2+self.info_box.border, self.height/2-self.info_box.border, 0.005) #self.info_box.visible = False def type_modified(self, sender): is_creature = self.gamecard.types == Creature if is_creature and not self.is_creature: self.setup_creature_role() elif not is_creature and self.is_creature: self.remove_creature_role() def setup_creature_role(self): self.is_creature = True gamecard = self.gamecard self.power = 0 #gamecard.power self.toughness = 0 #gamecard.toughness self.damage = 0 #gamecard.currentDamage() #dispatcher.connect(self.change_value, signal=PowerToughnessModifiedEvent(), sender=gamecard) # XXX This will lead to a lot of events each time priority is passed # but I'm not sure how to do it otherwise for cards like "Coat of Arms", which use a lambda function # or for damage self.text = Label("", size=34, background=True, shadow=False, halign="center", valign="center") #self.text._scale = anim.animate(0, 2.0, dt=0.25, method="sine") self.text.scale = 2.0 #self.text._pos.set(euclid.Vector3(0,0,0)) #_transition(dt=0.25, method="sine") self.text.orig_pos = euclid.Vector3(0, -self.height * 0.25, 0.001) self.text.zoom_pos = euclid.Vector3(self.width * 1.375, -self.height * 0.454, 0.01) self.text.pos = self.text.orig_pos #self.damage_text = Label("", size=34, background=True, shadow=False, halign="center", valign="center", color=(1., 0., 0., 1.)) #self.damage_text._scale = anim.animate(0.0, 0.0, dt=0.25, method="sine") #self.damage_text.scale = 0.4 #self.damage_text.visible = 0 #self.damage_text._pos.set(euclid.Vector3(0,0,0)) #_transition(dt=0.25, method="sine") #self.damage_text.zoom_pos = euclid.Vector3(self.width*(1-.375),-self.height*0.454, 0.01) #self.damage_text.pos = self.damage_text.zoom_pos self.change_value() self.draw = self.draw_creature dispatcher.connect(self.change_value, signal=TimestepEvent()) def remove_creature_role(self): self.is_creature = False self.draw = self.draw_permanent dispatcher.disconnect(self.change_value, signal=TimestepEvent()) def entering_play(self): self.is_tapped = False self.tapping = anim.animate(0, 0, dt=0.3) self.highlighting = anim.animate(0, 0, dt=0.2) self.zooming = anim.animate(0, 0, dt=0.2) self.pos_transition = "ease_out_circ" #"ease_out_back" self._pos.set_transition(dt=0.4, method=self.pos_transition) #self._pos.y = anim.animate(guicard._pos.y, guicard._pos.y, dt=0.4, method="ease_out") self._orientation.set_transition(dt=0.3, method="sine") self.can_layout = True if self.gamecard.types == Creature: self.setup_creature_role() # Check for counters dispatcher.connect(self.add_counter, signal=CounterAddedEvent(), sender=self.gamecard) dispatcher.connect(self.remove_counter, signal=CounterRemovedEvent(), sender=self.gamecard) dispatcher.connect(self.type_modified, signal=TypesModifiedEvent(), sender=self.gamecard) self.counters = [ Counter(counter.ctype) for counter in self.gamecard.counters ] self.layout_counters() def leaving_play(self): if self.is_creature: self.remove_creature_role() dispatcher.disconnect(self.add_counter, signal=CounterAddedEvent(), sender=self.gamecard) dispatcher.disconnect(self.remove_counter, signal=CounterRemovedEvent(), sender=self.gamecard) dispatcher.disconnect(self.type_modified, signal=TypesModifiedEvent(), sender=self.gamecard) def layout_counters(self): numc = len(self.counters) if numc > 0: spacing = self.counters[0].radius * 2.2 y = self.height / 4 max_per_row = int(self.width / spacing) num_rows = int(math.ceil(float(numc) / max_per_row)) x = -spacing * (max_per_row - 1) * 0.5 row = j = 0 for counter in self.counters: counter.pos = euclid.Vector3(x + j * spacing, y - row * spacing, counter.height / 2) j += 1 if j == max_per_row: j = 0 row += 1 if row == num_rows - 1: num_per_row = numc % max_per_row if num_per_row == 0: num_per_row = max_per_row x = -spacing * (num_per_row - 1) * 0.5 def add_counter(self, counter): self.counters.append(Counter(counter.ctype)) self.layout_counters() def remove_counter(self, counter): for c in self.counters: if c.ctype == counter.ctype: break else: raise Exception self.counters.remove(c) self.layout_counters() def change_value(self): p, t = self.gamecard.power, self.gamecard.toughness d = self.gamecard.currentDamage() if not (self.power == p and self.toughness == t and self.damage == d): self.power, self.toughness, self.damage = p, t, d self.text.set_text("%d/%d" % (p, t - d)) #if d > 0: self.damage_text.set_text("-%d"%d) #else: self.damage_text.set_text("") def tap(self): if self.tapping == 0.0: self.is_tapped = True self.tapping = 1.0 #anim.animate(0, 1, dt=0.3) self.untapped_orientation = self.orientation self.orientation *= euclid.Quaternion.new_rotate_axis( math.pi / 2, euclid.Vector3(0, 0, -1)) def untap(self): self.is_tapped = False self.orientation = self.untapped_orientation self.tapping = 0.0 def flash(self): self.highlighting = anim.animate(1, 0, dt=0.75, method="step") self.highlight_alpha = anim.animate(0.0, 0.8, dt=0.75, method="oscillate") def select(self): self.highlighting = 1.0 self.highlight_alpha = anim.animate(0., 1., dt=0.2, method="linear") def deselect(self): self.highlighting = 0.0 def highlight(self): if self.highlighting == 0: self.highlighting = anim.animate(0, 1, dt=0.75) self.old_pos = self.pos self.pos += euclid.Vector3(0, 3, 0) self.highlight_alpha = anim.animate(0.0, 0.8, dt=1, method="oscillate", extend="repeat") #self.old_size = self.size #self.size = anim.animate(self.size,1.05*self.size,dt=2.0,method="oscillate", extend="repeat") def unhighlight(self): self.highlighting = 0.0 self.pos = self.old_pos #self.size = anim.animate(self.old_size, self.old_size, dt=0.2, method="sine") def shake(self): self._pos.set_transition(dt=0.25, method=lambda t: anim.oscillate_n(t, 3)) self.pos += euclid.Vector3(0.05, 0, 0) def unshake(self): # XXX Need to reset position transition - this is a bit hacky - I need to be able to layer animations self._pos.set_transition(dt=0.4, method=self.pos_transition) def zoom_to_camera(self, camera, z, size=0.02, show_info=True, offset=euclid.Vector3(0, 0, 0)): if self.zooming == 0.0: self._texture = self._img self._old_list, self.cardlist = self.cardlist, self.renderlist self.zooming = 1.0 self.old_pos = self.pos self._pos.set_transition(dt=0.2, method="ease_out") #self.pos_transition) #self._pos.y = anim.animate(self._pos.y, self._pos.y, dt=0.4, method="sine") #self._orientation.set_transition(dt=0.5, method="sine") if show_info: offset = offset + euclid.Vector3(-self.width * size / 2, 0, 0) self.pos = camera.pos - camera.orientation * euclid.Vector3( 0, 0, camera.vis_distance) - euclid.Vector3(0, 0, z) + offset self.orig_orientation = self.orientation new_orient = camera.orientation if self.is_tapped: new_orient *= euclid.Quaternion.new_rotate_axis( math.pi / 10, euclid.Vector3(0, 0, -1)) self.orientation = new_orient self.old_size = self.size self.size = size * 0.7 if self.is_creature: self.text.visible = False self.text.set_text("%d/%d" % (self.power, self.toughness)) self.text.pos = self.text.zoom_pos self.text.scale = 0.4 #self.damage_text.visible = True #if show_info: # self.info_box.visible = True # self.info_box.set_text('\n'.join(self.gamecard.info.split("\n")[:17]), width=self.width) # self.info_box._height = self.height-self.info_box.border #else: self.info_box.visible = False def restore_pos(self): self.zooming = 0.0 #anim.animate(self.zooming, 0.0, dt=0.2) self._texture = self.front self.cardlist = self._old_list self._pos.set_transition(dt=0.4, method=self.pos_transition) #self._pos.y = anim.animate(self._pos.y, self._pos.y, dt=0.4, method="sine") # XXX old self._pos.set_transition(dt=0.2, method="ease_out_circ") #self._orientation.set_transition(dt=0.3, method="sine") self.pos = self.old_pos self.orientation = self.orig_orientation self.size = self.old_size if self.is_creature: self.text.visible = True self.text.set_text("%d/%d" % (self.power, self.toughness - self.damage)) self.text.pos = self.text.orig_pos self.text.scale = 2.0 #self.damage_text.scale = 0.4 #self.damage_text.pos = self.damage_text.zoom_pos #self.damage_text.visible = 0.0 #self.info_box.visible = False def render_extra(self, width, height): if hasattr(self, "damage") and self.damage != 0: ImageCache.get_texture("overlays/damage.png").blit( 0.59 * width, -0.01 * height) pyglet.text.Label( "%d" % self.damage, #font_name="MPlantin", font_size=0.073 * width, x=0.69 * width, y=0.073 * height, anchor_x="center", anchor_y="center").draw() def draw_permanent(self): if self.visible > 0: size = self.size glPushMatrix() if self.highlighting != 0: glPushMatrix() glTranslatef(self.pos.x, self.pos.y - 0.0005, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size * 1.1, size * 1.1, size * 1.1) glColor4f(1.0, 1.0, 1.0, self.highlight_alpha.get()) glCallList(self.cardlist) glPopMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) #glScalef(size, size, size) glScalef(size, size, 1) glEnable(self._texture.target) glBindTexture(self._texture.target, self._texture.id) glColor4f(self.alpha, self.alpha, self.alpha, self.alpha) #foil.install() glCallList(self.cardlist) #foil.uninstall() #self.info_box.render() glDisable(self._texture.target) for c in self.counters: c.draw() glPopMatrix() def draw_creature(self): if self.visible > 0: size = self.size glPushMatrix() if self.highlighting: glPushMatrix() glTranslatef(self.pos.x, self.pos.y - 0.0005, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size * 1.1, size * 1.1, size * 1.1) #glScalef(size*1.1, size*1.1, 1) glColor4f(1.0, 1.0, 1.0, self.highlight_alpha.get()) glCallList(self.cardlist) glPopMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) #glScalef(size, size, size) glScalef(size, size, 1) glEnable(self._texture.target) glBindTexture(self._texture.target, self._texture.id) glColor4f(self.alpha, self.alpha, self.alpha, self.alpha) glCallList(self.cardlist) #self.info_box.render() #self.text.render() #self.damage_text.render() glDisable(self._texture.target) for c in self.counters: c.draw() glPopMatrix()
class StackCard(Card): highlighting = anim.Animatable() borderedlist = None COLORS = ColorDict() def __init__(self, gamecard, front, back, art, text="", style="regular"): super(StackCard, self).__init__(gamecard, front, back) self._art = art self.highlighting = anim.animate(0, 0, dt=0.2, method="step") self.size = anim.animate(self.size, self.size, dt=0.2, method="sine") self.alpha = anim.animate(0, 0, dt=1.0, method="ease_out_circ") self.style = style self.stackwidth, self.stackheight = 368, 414 if self.style == "regular": self._texture = pyglet.image.Texture.create(self.renderwidth, self.renderheight, force_rectangle=True) Card._render(self._texture, self._art, self.gamecard) else: self._texture = pyglet.image.Texture.create(self.stackwidth, self.stackheight, force_rectangle=True) self.text = text self.render_special() if not StackCard.borderedlist: StackCard.borderedlist = self.build_renderlist( self.stackwidth, self.stackheight) #self.color = self.COLORS.get(str(gamecard.color)) #colors = self.COLORS.get_multi(str(gamecard.color)) #if len(colors) == 1: self.color = colors[0] #else: # self.color = colors # self.draw = self.draw_multi #self.bordered = bordered #self.border = border #if bordered and not StackCard.borderedlist: self.build_borderedlist() def build_borderedlist(self): cls = StackCard width = self.border.width / 2.0 height = self.border.height / 2.0 vertlist = [ euclid.Point3(-width, -height, 0), euclid.Point3(width, -height, 0), euclid.Point3(width, height, 0), euclid.Point3(-width, height, 0) ] tc = self.border.tex_coords cardlist = glGenLists(1) cls.borderedlist = cardlist glNewList(cardlist, GL_COMPILE) glBegin(GL_QUADS) glTexCoord2f(tc[0], tc[1]) glVertex3f(*tuple(vertlist[0])) glTexCoord2f(tc[3], tc[4]) glVertex3f(*tuple(vertlist[1])) glTexCoord2f(tc[6], tc[7]) glVertex3f(*tuple(vertlist[2])) glTexCoord2f(tc[9], tc[10]) glVertex3f(*tuple(vertlist[3])) glEnd() glEndList() def multicolored_border(self): width = self.border.width / 2.0 height = self.border.height / 2.0 vertlist = [ euclid.Point3(-width, -height, 0), euclid.Point3(width, -height, 0), euclid.Point3(width, height, 0), euclid.Point3(-width, height, 0) ] tc = self.border.tex_coords color1, color2 = self.color glBegin(GL_QUADS) glColor4f(color1[0], color1[1], color1[2], self.alpha) glTexCoord2f(tc[0], tc[1]) glVertex3f(*tuple(vertlist[0])) glColor4f(color2[0], color2[1], color2[2], self.alpha) glTexCoord2f(tc[3], tc[4]) glVertex3f(*tuple(vertlist[1])) glColor4f(color2[0], color2[1], color2[2], self.alpha) glTexCoord2f(tc[6], tc[7]) glVertex3f(*tuple(vertlist[2])) glColor4f(color1[0], color1[1], color1[2], self.alpha) glTexCoord2f(tc[9], tc[10]) glVertex3f(*tuple(vertlist[3])) glEnd() def render_special(self): glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, self.fbo) img = self._texture glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, img.target, img.id, 0) width, height = self.stackwidth, self.stackheight #//------------------------- glPushAttrib(GL_VIEWPORT_BIT) glViewport(0, 0, width, height) glPushAttrib(GL_TRANSFORM_BIT) glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0.0, width, 0.0, height, -1.0, 1.0) glClearColor(1., 1., 1., 1.) glClear(GL_COLOR_BUFFER_BIT) # draw card image glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glColor4f(1., 1., 1., 1.0) #art = self.front.get_region(8, 125, 185, 135) #art.blit(0.054*width, 0.2428*height, width=0.889*width, height=0.5857*height) blend_frac = 0.5 blend_y = blend_frac * 135 artsolid = self._art.get_region(8, 125 + blend_y, 185, 135 - blend_y) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) artsolid.blit(0.054 * width, 0.54564 * height, width=0.889 * width, height=(0.5857 * height) * blend_frac) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE) artfade = self._art.get_region(8, 125, 185, blend_y) tc = artfade.tex_coords glEnable(artfade.target) glBindTexture(artfade.target, artfade.id) glBegin(GL_QUADS) glColor4f(1., 1., 1., 0.0) glTexCoord2f(tc[0], tc[1]) glVertex3f(0.054 * width, 0.2428 * height, 0) glTexCoord2f(tc[3], tc[4]) glVertex3f(0.943 * width, 0.2428 * height, 0) glColor4f(1., 1., 1., 1.0) glTexCoord2f(tc[6], tc[7]) glVertex3f(0.943 * width, 0.54564 * height, 0) glTexCoord2f(tc[9], tc[10]) glVertex3f(0.054 * width, 0.54564 * height, 0) glEnd() glDisable(artfade.target) x, y, x2, y2 = 20, 44, 345, 152 glBegin(GL_QUADS) glColor4f(1., 1., 1., 1.0) glVertex3f(x, y, 0) glVertex3f(x2, y, 0) glColor4f(1., 1., 1., 0.0) glVertex3f(x2, y2, 0) glVertex3f(x, y2, 0) glEnd() glColor4f(1., 1., 1., 1.) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) ImageCache.get_texture("frames/Gld-stack.png").blit(0, 0) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE) name = str(self.gamecard.name) header = "%s ability of\n%s" % (self.style.capitalize(), name) document = pyglet.text.decode_text(header) document.set_style( 0, len(document.text), dict(font_name="MatrixBold", font_size=0.047 * width, leading=0, color=(0, 0, 0, 255))) namebox = pyglet.text.DocumentLabel(document, multiline=True, width=width * 0.85, x=width / 2.05, y=0.91 * height, anchor_x="center", anchor_y="baseline") document = mtg_decoder.decode_text(self.text.replace('~', name)) document.set_style( 0, len(document.text), dict(bold=True, font_name="MPlantin", font_size=0.0353 * width, color=(0, 0, 0, 255))) textbox = pyglet.text.DocumentLabel(document, multiline=True, width=width * 0.85, x=width / 2, y=height * .23, anchor_x="center", anchor_y="center") for text in [namebox, textbox]: text.draw() glPopMatrix() glMatrixMode(GL_MODELVIEW) glPopMatrix() glPopAttrib() glPopAttrib() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) #img.save("%s_ability.png"%self.gamecard.name) def highlight(self): if self.highlighting == 0: self.highlighting = anim.animate(0, 1, dt=0.75) #self.old_size = self.size self.size = anim.animate(self.size, 1.5 * self.size, dt=0.5, method="oscillate", extend="repeat") def unhighlight(self): self.highlighting = 0.0 self.size = anim.animate(self.size, self.size, dt=0.2, method="sine") def draw(self): if self.visible > 0: size = self.size glPushMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size, size, 1) glEnable(self._texture.target) glBindTexture(self._texture.target, self._texture.id) glColor4f(1, 1, 1, self.alpha) if self.style == "regular": glCallList(self.renderlist) else: glCallList(self.borderedlist) #if self.bordered: # color = self.color # glBindTexture(self.border.target, self.border.id) # glColor4f(color[0], color[1], color[2], self.alpha) # glCallList(self.borderedlist) glDisable(self._texture.target) glPopMatrix() def draw_multi(self): if self.visible > 0: size = self.size glPushMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size, size, 1) glEnable(self._texture.target) glBindTexture(self._texture.target, self._texture.id) glColor4f(1, 1, 1, self.alpha) glCallList(self.cardlist) if self.bordered: glBindTexture(self.border.target, self.border.id) self.multicolored_border() glDisable(self._texture.target) glPopMatrix()
class HandCard(Card): zooming = anim.Animatable() def __init__(self, gamecard, front, back): super(HandCard, self).__init__(gamecard, front, back) self.zooming = 0
class Card(anim.Animable): def pos(): def fget(self): return euclid.Vector3(self._pos.x, self._pos.y, self._pos.z) def fset(self, val): self._pos.x = val.x self._pos.y = val.y self._pos.z = val.z return locals() pos = property(**pos()) def orientation(): def fget(self): return self._orientation.copy() def fset(self, val): self._orientation.x = val.x self._orientation.y = val.y self._orientation.z = val.z self._orientation.w = val.w return locals() orientation = property(**orientation()) def hidden(): def fget(self): return self._hidden def fset(self, hidden): self._hidden = hidden if hidden: self._texture = self.back else: self._texture = self.front return locals() hidden = property(**hidden()) size = anim.Animatable() visible = anim.Animatable() alpha = anim.Animatable() vertlist = None cardlist = None renderlist = None fbo = None renderwidth, renderheight = 397, 553 def __init__(self, gamecard, front, back): self.gamecard = gamecard self.front = front self.back = back self.hidden = False self.width, self.height = self.front.width, self.front.height self.size = anim.constant(1.0) self._pos = AnimatedVector3(0, 0, 0) self.pos_transition = "ease_out_circ" self._orientation = AnimatedQuaternion() self.visible = anim.constant(1.0) self.alpha = anim.constant(1.0) if not Card.cardlist: Card.cardlist = self.build_displaylist(self.width, self.height) #self.renderwidth, self.renderheight = 736, 1050 #self.renderwidth, self.renderheight = 368, 525 #self.renderwidth, self.renderheight = 397, 553 if not Card.fbo: Card.build_fbo() if not Card.renderlist: Card.renderlist = self.build_renderlist(self.renderwidth, self.renderheight) @classmethod def build_fbo(cls): id = ctypes.c_uint() glGenFramebuffersEXT(1, ctypes.byref(id)) fbo = id.value glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo) width, height = cls.renderwidth, cls.renderheight #img = pyglet.image.Texture.create(self.width, self.height, force_rectangle=True) img = pyglet.image.Texture.create(width, height, force_rectangle=True) #glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, img.target, img.id, 0); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) #if not status == GL_FRAMEBUFFER_COMPLETE_EXT: # raise Exception() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) cls.fbo = fbo cls._img = img def del_fbo(self): glDeleteFramebuffersEXT(1, self.fbo) def render_extra(self, width, height): pass def render(self): Card._render(Card._img, self._art, self.gamecard) @classmethod def _render(cls, img, front, gamecard, tiny=False): glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, cls.fbo) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, img.target, img.id, 0) width, height = img.width, img.height wf, hf = (width / 397.), (height / 553.) tiny_font = "pixelmix" tfont_size = 6 #//------------------------- glPushAttrib(GL_VIEWPORT_BIT) glViewport(0, 0, width, height) glPushAttrib(GL_TRANSFORM_BIT) glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0.0, width, 0.0, height, -1.0, 1.0) glClearColor(0., 0., 0., 0.) glClear(GL_COLOR_BUFFER_BIT) #glClearColor(1.,1.,1.,1.) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) cmap = dict(zip(["White", "Blue", "Black", "Red", "Green"], "WUBRG")) cmap1 = dict(zip("WUBRG", range(5))) colors = tuple( sorted([cmap[str(c)] for c in gamecard.color], key=lambda c: cmap1[c])) num_colors = len(colors) blend_color = None overlay_color = None overlay_blend = None final_overlay = None if gamecard.types == Land: frame = ImageCache.get_texture("frames/Land.png") abilities = map(str, gamecard.abilities) mana = list( itertools.chain(*[ re.findall("{([WUBRG])}", a) for a in abilities if "Add " in a ])) num_colors = len(mana) if num_colors == 0: pass elif num_colors <= 2: overlay_color = mana[0] if num_colors == 2: overlay_blend = mana[1] final_overlay = "C" else: overlay_color = "Gld" elif gamecard.types == Artifact: frame = ImageCache.get_texture("frames/Art.png") if num_colors == 1: overlay_color = colors[0] elif num_colors == 2: overlay_color, overlay_blend = colors final_overlay = "Gld" elif num_colors > 2: overlay_color = "Gld" else: if num_colors == 0: frame = ImageCache.get_texture("frames/C.png") elif num_colors == 1: frame = ImageCache.get_texture("frames/%s.png" % colors[0]) else: frame = ImageCache.get_texture("frames/Gld.png") if num_colors == 2: overlay_color, overlay_blend = colors final_overlay = "Gld" #glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) #glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE) frame.blit(0, 0, width=width, height=height) #glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE) def blend(texture, width, height): tw, th = texture.width, texture.height glEnable(texture.target) glBindTexture(texture.target, texture.id) glBegin(GL_QUADS) glColor4f(1., 1., 1., 1.0) glTexCoord2f(0.65 * tw, 0) glVertex3f(0.65 * width, 0, 0) glTexCoord2f(tw, 0) glVertex3f(width, 0, 0) glTexCoord2f(tw, th) glVertex3f(width, height, 0) glTexCoord2f(0.65 * tw, th) glVertex3f(0.65 * width, height, 0) glColor4f(1., 1., 1., 0) glTexCoord2f(0.35 * tw, 0) glVertex3f(0.35 * width, 0, 0) glColor4f(1., 1., 1., 1) glTexCoord2f(0.65 * tw, 0) glVertex3f(0.65 * width, 0, 0) glColor4f(1., 1., 1., 1) glTexCoord2f(0.65 * tw, th) glVertex3f(0.65 * width, height, 0) glColor4f(1., 1., 1., 0) glTexCoord2f(0.35 * tw, th) glVertex3f(0.35 * width, height, 0) glEnd() glDisable(texture.target) glColor4f(1., 1., 1., 1.) if blend_color: blend(ImageCache.get_texture("frames/%s.png" % blend_color)) if overlay_color: t = ImageCache.get_texture("overlays/%s.png" % overlay_color) t.blit(0, 0, width=wf * t.width, height=hf * t.height) if overlay_blend: t = ImageCache.get_texture("overlays/%s.png" % overlay_blend) blend(t, width=width, height=height) if final_overlay: t = ImageCache.get_texture("overlays/%s-overlay.png" % final_overlay) t.blit(0, 0, width=wf * t.width, height=hf * t.height) # draw card image #glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) front.get_region(8, 125, 185, 135).blit(0.087 * width, 0.4484 * height, width=0.824 * width, height=0.4368 * height) #glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE) # Draw all card text first name = unicode(gamecard.name) font_name = "MatrixBold" if not tiny else tiny_font font_size = 0.043 * width if not tiny else tfont_size name_label = pyglet.text.Label(name, font_name=font_name, font_size=font_size, color=(0, 0, 0, 255), x=0.098 * width, y=0.902 * height) supertypes = unicode(gamecard.supertypes) types = unicode(gamecard.types) subtypes = unicode(gamecard.subtypes) typeline = u"" if supertypes: typeline += supertypes + " " typeline += types if subtypes: typeline += u" - %s" % subtypes font_size = 0.038 * width if not tiny else tfont_size type_label = pyglet.text.Label(typeline, font_name=font_name, font_size=font_size, color=(0, 0, 0, 255), x=0.098 * width, y=0.40 * height) text = unicode("\n\n".join( [str(a).replace("~", name) for a in list(gamecard.abilities)])) if not text: text = gamecard.text.replace('~', name).split('\n') text = unicode('\n'.join(text[:4])) if text: document = mtg_decoder.decode_text(text) font_name = "Helvetica" if not tiny else tiny_font font_size = 0.035 * width if not tiny else tfont_size document.set_style( 0, len(document.text), dict(font_name=font_name, font_size=font_size, color=(0, 0, 0, 255))) #textbox = pyglet.text.layout.IncrementalTextLayout(document, # int(0.82*width), int(0.25*height), # multiline=True) textbox = pyglet.text.DocumentLabel(document, width=0.80 * width, height=0.25 * height, multiline=True) textbox.x = int(0.501 * width) textbox.y = int(0.25 * height) textbox.anchor_x = "center" textbox.anchor_y = "center" textbox.content_valign = 'center' textbox.draw() for text in [name_label, type_label]: text.draw() # mana costs tf = 1.9 if tiny else 1 mana_x, mana_y, diff_x = 0.883 * width, 0.916 * height, 0.053 * width * tf mana = set("BCGRUWXYZ") for c in str(gamecard.cost)[::-1]: if c in mana: if tiny: c = 's%s' % c ms = ImageCache.get(c) ms.blit(mana_x, mana_y, width=tf * wf * ms.width, height=tf * hf * ms.height) else: ms = ImageCache.get("C" if not tiny else "sC") ms.blit(mana_x, mana_y, width=tf * wf * ms.width, height=tf * hf * ms.height) font_name = "MPlantin" # if not tiny else tiny_font font_size = 0.043 * width * tf pyglet.text.Label(c, font_name=font_name, font_size=font_size, color=(0, 0, 0, 255), x=mana_x, y=mana_y + 1, anchor_x="center", anchor_y="center").draw() mana_x -= diff_x if gamecard.types == Creature: if num_colors == 0: if gamecard.types == Artifact: pt = ImageCache.get_texture("pt/Art.png") else: pt = ImageCache.get_texture("pt/C.png") elif num_colors == 1: pt = ImageCache.get_texture("pt/%s.png" % colors[0]) elif num_colors > 1: if final_overlay: col = final_overlay elif overlay_color: col = overlay_color else: col = "Gld" pt = ImageCache.get_texture("pt/%s.png" % col) pt.blit(0, 0, width=wf * pt.width, height=hf * pt.height) font_name = "MatrixBoldSmallCaps" if not tiny else tiny_font font_size = 0.051 * width if not tiny else tfont_size + 1 ptbox = pyglet.text.Label('%s/%s' % (gamecard.power, gamecard.toughness), font_name=font_name, font_size=font_size, color=(0, 0, 0, 255), x=0.828 * width, y=0.072 * height, anchor_x="center", anchor_y="baseline") ptbox.draw() # expansion symbol exp = ImageCache.get_texture("sets/M10_C.png") exp.anchor_x = exp.width / 2. exp.anchor_y = exp.height / 2. exp.blit(0.866 * width, 0.413 * height, width=tf * wf * exp.width, height=tf * hf * exp.height) #self.render_extra(width, height) glPopMatrix() glMatrixMode(GL_MODELVIEW) glPopMatrix() glPopAttrib() glPopAttrib() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) #if not tiny: img.save("%s.png"%gamecard.name) def build_renderlist(self, width, height): renderlist = glGenLists(1) width, height = width / 2, height / 2 glNewList(renderlist, GL_COMPILE) glBegin(GL_QUADS) glTexCoord2f(0, 0) glVertex3f(-width, -height, 0) glTexCoord2f(width * 2, 0) glVertex3f(width, -height, 0) glTexCoord2f(width * 2, height * 2) glVertex3f(width, height, 0) glTexCoord2f(0, height * 2) glVertex3f(-width, height, 0) glEnd() glEndList() return renderlist def build_displaylist(self, width, height): cls = Card width, height = width / 2.0, height / 2.0 vertlist = [ euclid.Point3(-width, -height, 0), euclid.Point3(width, -height, 0), euclid.Point3(width, height, 0), euclid.Point3(-width, height, 0) ] cls.vertlist = vertlist tc = self._texture.tex_coords cardlist = glGenLists(1) glNewList(cardlist, GL_COMPILE) glBegin(GL_QUADS) glTexCoord2f(tc[0], tc[1]) glVertex3f(*tuple(vertlist[0])) glTexCoord2f(tc[3], tc[4]) glVertex3f(*tuple(vertlist[1])) glTexCoord2f(tc[6], tc[7]) glVertex3f(*tuple(vertlist[2])) glTexCoord2f(tc[9], tc[10]) glVertex3f(*tuple(vertlist[3])) glEnd() glEndList() return cardlist def shake(self): self._pos.set_transition(dt=0.25, method=lambda t: anim.oscillate_n(t, 3)) self.pos += euclid.Vector3(0.05, 0, 0) def unshake(self): # XXX Need to reset position transition - this is a bit hacky - I need to be able to layer animations self._pos.set_transition(dt=0.4, method=self.pos_transition) def draw(self): if self.visible > 0: size = self.size glPushMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size, size, 1) glEnable(self._texture.target) glBindTexture(self._texture.target, self._texture.id) #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) #LINEAR) glColor4f(self.alpha, self.alpha, self.alpha, 1.0) #self.alpha) glCallList(self.cardlist) glDisable(self._texture.target) glPopMatrix() def intersects(self, selectRay): # This is the slow way m = euclid.Matrix4() m.translate(*tuple(self.pos)) m *= self.orientation.get_matrix() size = self.size m.scale(size, size, 1) vertlist = [m * v for v in self.vertlist] for i in range(1, len(vertlist) - 1): poly = euclid.Triangle(vertlist[0], vertlist[i], vertlist[i + 1]) result = poly.intersect(selectRay) if result: return result else: return False def __str__(self): return str(self.gamecard) def __repr__(self): return repr(self.gamecard)
class Counter(anim.Animable): def pos(): def fget(self): return euclid.Vector3(self._pos.x, self._pos.y, self._pos.z) def fset(self, val): self._pos.x = val.x self._pos.y = val.y self._pos.z = val.z return locals() pos = property(**pos()) def orientation(): def fget(self): return self._orientation.copy() def fset(self, val): self._orientation.x = val.x self._orientation.y = val.y self._orientation.z = val.z self._orientation.w = val.w return locals() orientation = property(**orientation()) size = anim.Animatable() visible = anim.Animatable() alpha = anim.Animatable() piece_list = None radius = PIECE_RADIUS height = PIECE_HEIGHT def __init__(self, ctype, color=None): self.ctype = ctype if not color: color = [0, 0, 0] temp = hash(ctype) % 2**24 color[0] = temp / 2**16 temp = temp % 2**16 color[1] = temp / 2**8 color[2] = temp % 2**8 self.color = (color[0] / 255.0, color[1] / 255.0, color[2] / 255.0) else: self.color = color self.size = anim.constant(1) self._pos = AnimatedVector3(0, 0, 0) self._orientation = AnimatedQuaternion() self.orientation = euclid.Quaternion.new_rotate_axis( pi, euclid.Vector3(0, 0, 1)) self.visible = anim.constant(1.0) self.alpha = 0.9 #0.7 #anim.constant(1.0) cls = self.__class__ if not cls.piece_list: self.build_piece_list(cls) def build_piece_list(self, cls): #def point_fn(i): # return [(0, self.height), # (cls.radius/2, cls.height), # (cls.radius - PIECE_BEVEL, cls.height), # (cls.radius, cls.height - PIECE_BEVEL), # (cls.radius, PIECE_BEVEL), # (cls.radius - PIECE_BEVEL, 0), # ] cls.piece_list = glGenLists(1) glNewList(cls.piece_list, GL_COMPILE) # First version #glEnable(GL_BLEND) #glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) #glDisable(GL_BLEND) # Second version #glCullFace(GL_FRONT) #draw_lathe(point_fn, PIECE_SLICES) #glCullFace(GL_BACK) #draw_lathe(point_fn, PIECE_SLICES) # Third version draw_circle(0, 0, cls.radius) # 2D circle function glEndList() def draw(self): if self.visible > 0: size = self.size glPushMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glMultMatrixf(sixteenfv(*tuple(self.orientation.get_matrix()))) glScalef(size, size, size) glColor4f(self.color[0], self.color[1], self.color[2], self.alpha) glCallList(self.piece_list) glPopMatrix()
class HandView(CardView): zooming = anim.Animatable() def __init__(self, pos=euclid.Vector3(0,0,0), is_opponent=False): super(HandView,self).__init__(pos, reverse_draw=True) self._pos.set_transition(dt=0.3, method="sine") #"ease_out_back") #if is_opponent: # self.dir = -1 # align="left" #else: # self.dir = 1 # align = "right" self.dir = 1 align = "left" #self.hand_size = Label("0", size=30, halign=align, valign="center") self.is_opponent = is_opponent self.small_size = 0.6 self.focus_idx = 0 self.visible = 0.0 self.zooming = 0 self.avail_width = 0 self.height = 0 self.layout = self.unfocused_layout self.render_after_transform = self.render_unfocused self.unfocused_size = (0.05, 0.40) self.unfocused_spacing = 1.025 self.hidden = True self._card_map = {} def set_hidden(self, value=True): self.hidden = value for card in self.cards: card.hidden = value def resize(self, width, height, avail_width): self.screen_width = width offset = 5 self.avail_width = avail_width-10-2*offset self.height = 136 #90 #85.5 if not self.is_opponent: self.pos = euclid.Vector3(width-offset-self.avail_width, offset+self.height/2, 0) else: self.pos = euclid.Vector3(width-self.avail_width-offset, height - self.height/2 - offset, 0) #if not self.is_opponent: self.pos = euclid.Vector3(width-self.avail_width, 1.1*self.height/2, 0) #else: self.pos = euclid.Vector3(0, height - 1.1*self.height/2, 0) self.layout() def setup_player(self, color): self.color = color #def show(self): # #self.focus_idx = len(self)/2 # self.layout = self.layout_staggered # self.render_after_transform = self.render_focused # self.pos = euclid.Vector3(self.screen_width/2, 150, 0) # for card in self.cards: # card.alpha = 1.0 # card._pos.set_transition(dt=0.4, method=self.pos_transition) # self.layout() # #super(HandView,self).show() #def hide(self): # self.layout = self.unfocused_layout # self.render_after_transform = self.render_unfocused # for card in self.cards: # #card.alpha = 0.85 # card._pos.set_transition(dt=0.4, method="sine") # self.layout() # #super(HandView,self).hide() def add_card(self, card): newcard = CardLibrary.CardLibrary.getHandCard(card) self._card_map[card.key] = newcard newcard.hidden = self.hidden newcard._pos.set_transition(dt=0.8, method="sine") #self.pos_transition) newcard._orientation.set_transition(dt=0.2, method=self.orientation_transition) newcard.size = anim.animate(newcard.size, newcard.size, dt=0.2, method="sine") newcard.alpha = anim.animate(0, 1.0, dt=1.0, method="ease_out_circ") self.cards.append(newcard) self.layout() def remove_card(self, card): card = self._card_map.pop(card.key) self.cards.remove(card) if self.focus_dir < 0: self.focus_idx += self.focus_dir if self.focus_idx > len(self)-1: self.focus_idx = len(self)-1 elif self.focus_idx < 0: self.focus_idx = 0 self.layout() def shift_right(self, card): idx = self.cards.index(card) if idx != 0: self.cards[idx], self.cards[idx-1] = self.cards[idx-1], self.cards[idx] def shift_left(self, card): idx = self.cards.index(card) if idx != len(self.cards)-1: self.cards[idx+1], self.cards[idx] = self.cards[idx], self.cards[idx+1] def zoom_card(self, card): if card.zooming == 0: #self.zooming_card = card card.zooming = anim.animate(0, 1, dt=0.3, method="linear") card.old_pos = card.pos card.old_size = card.size if self.is_opponent and card.pos.x-card.width/2 < 0: pos_shift = card.width/1.5 elif card.pos.x+card.width/2 > self.avail_width: pos_shift = self.avail_width - card.width/1.5 else: pos_shift = card.pos.x card._pos.set_transition(dt=0.2, method="sine") #self.pos_transition) card.pos = euclid.Vector3(pos_shift, (self.height+card.height/2)*self.dir, 0) card.size = 1.0 def restore_card(self, card): #if self.zooming == 1.0: # This will finish the zooming motion if True: card.zooming = anim.animate(1, 0, dt=0.3, method="linear") #card = self.zooming_card card.size = card.old_size card.pos = card.old_pos def unfocused_layout(self): numhand = len(self.cards) #self.hand_size.set_text(numhand) #if not self.is_opponent: self.hand_size.pos = euclid.Vector3(self.avail_width-10, 0, 0) #else: self.hand_size.pos = euclid.Vector3(10, 0, 0) #avail_width = self.avail_width - self.hand_size.width - 20 avail_width = self.avail_width - 20 size = self.unfocused_size[1] if numhand > 0: self.visible = 1.0 cardwidth = self.cards[0].width # First lay out, then overlap, and then scale spacing = self.unfocused_spacing numhand += .5 while (numhand*cardwidth*size*spacing) - avail_width > 0.005: # Figure out the spacing that will fit spacing = avail_width / (numhand*cardwidth*size) if spacing < 0.7: spacing = self.unfocused_spacing size -= 0.005 x_incr = cardwidth*size*spacing*self.dir x, y = avail_width-cardwidth*size/2, 0 #if not self.is_opponent: x, y = avail_width-cardwidth*size/2, 0 #else: x, y = self.hand_size.width + cardwidth*size/2 + 20, 0 z = 0 for card in self.cards: card.size = size card.orientation = euclid.Quaternion() card._pos.set_transition(dt=0.8, method="sine") card.pos = euclid.Vector3(x,y,z) x -= x_incr else: self.visible = 0.0 self.box = (0, -self.height/2, self.avail_width, self.height/2) def layout_original(self): if len(self) > 0: if self.focus_idx == -1: self.focus_idx = len(self)-1 cards = self.cards w, h = cards[0].width, cards[0].height radius = h*1.5 incr_arc = math.pi/180*-2 extra_arc = math.pi/180*-27 Q = euclid.Quaternion.new_rotate_axis(incr_arc*(self.focus_idx-1)+extra_arc, euclid.Vector3(0,0,-1)) i = 0.001 for card in cards[:self.focus_idx]: card.orientation = Q card.pos = Q*euclid.Vector3(0,radius,0) - euclid.Vector3(0,radius,i) card.size = self.small_size Q.rotate_axis(incr_arc, euclid.Vector3(0,0,1)) i += 0.001 card = cards[self.focus_idx] card.pos = euclid.Vector3(0,0,i) i += 0.001 card.orientation = euclid.Quaternion() card.size = self.focus_size Q = euclid.Quaternion.new_rotate_axis(-extra_arc, euclid.Vector3(0,0,-1)) for card in cards[self.focus_idx+1:]: card.orientation = Q card.pos = Q*euclid.Vector3(0,radius,0) - euclid.Vector3(0,radius,i) card.size = self.small_size Q.rotate_axis(incr_arc, euclid.Vector3(0,0,1)) i += 0.001 def layout_staggered(self): if len(self) > 0: if self.focus_idx == -1: self.focus_idx = len(self)-1 cards = self.cards w, h = cards[0].width, cards[0].height radius = h*8#1.5 incr_arc = math.pi/180*-0.75 #1 extra_arc = math.pi/180*-4.5 #10 #-27 Q = euclid.Quaternion.new_rotate_axis(incr_arc*(self.focus_idx-1)+extra_arc, euclid.Vector3(0,0,-1)) i = 0.001 y_incr = (self.focus_idx-1)*h*0.1*self.small_size size = self.small_size for card in cards[:self.focus_idx]: card.orientation = Q card.pos = Q*euclid.Vector3(0,radius,0) - euclid.Vector3(0,radius+y_incr,i) card.size = size Q.rotate_axis(incr_arc, euclid.Vector3(0,0,1)) y_incr -= h*0.1*size #if size < self.small_size: size += 0.05 i += 0.001 card = cards[self.focus_idx] card.pos = euclid.Vector3(0,0,i) i += 0.001 card.orientation = euclid.Quaternion() card.size = self.focus_size Q = euclid.Quaternion.new_rotate_axis(-extra_arc, euclid.Vector3(0,0,-1)) y_incr += h*0.1*self.small_size for card in cards[self.focus_idx+1:]: card.orientation = Q card.pos = Q*euclid.Vector3(0,radius,0) - euclid.Vector3(0,radius+y_incr,i) card.size = self.small_size Q.rotate_axis(incr_arc, euclid.Vector3(0,0,1)) y_incr += h*0.1*self.small_size i += 0.001 def render_unfocused(self): #glColor4f(0.2,0.2,0.3,0.5) #glDisable(GL_TEXTURE_2D) #glBegin(GL_QUADS) c = self.color glColor4f(c[0], c[1], c[2], 1.0) l, b, r, t = self.box render_9_part("box4", r-l, t-b, x=l, y=b) for card in self.cards: card.draw() def render_focused(self): for card in self.cards[self.focus_idx::-1]: card.draw() for card in self.cards[self.focus_idx+1:]: card.draw()
class ZoneView(CardView): selected_width = anim.Animatable() def __init__(self, pos=euclid.Vector3(0,0,0)): super(ZoneView,self).__init__(pos,reverse_draw=True) self._pos.set_transition(dt=0.001) self.selected_width = anim.animate(0, 0, dt=0.3, method="sine") self.sorted = False self.padding = 15 points = [(0.0, 0.0), (26.0, 244.0), (184.0, 368.0), (400.0, 226.0)] self.path = BezierPath(*[euclid.Point2(v[0], v[1]) for v in points]) self.visible = anim.animate(0,0,dt=0.3) self.layout = self.layout_straight self.is_library = False def build(self, zone, is_opponent): self.cards = [] self.selected = [] self.shift_factor = 0.05 #0.1 if is_opponent: self.dir = -1 # align = ["left", "right"] else: self.dir = 1 # align = ["right", "left"] #self.selected_text = [Label("Top", halign=align[0], background=True), Label("Bottom", halign=align[1], background=True)] #self.selected_text[0].visible = self.selected_text[1].visible = 0.0 for card in zone: self.add_card(card) if str(card.zone) == "library": self.is_library = True self.cards.reverse() self.focus_idx = len(self.cards)-1 #0 self.orig_order = dict([(c.gamecard.key, i) for i, c in enumerate(self.cards)]) self.layout() self.selected_width = 0 def focus_next(self): dir = 1 if dir == 1: cond = (self.focus_idx < len(self)-1) else: cond = self.focus_idx > 0 if cond: #self.focus_idx < len(self)-1: dispatcher.send(GUIEvent.FocusCard()) self.focus_dir = dir self.focus_idx += self.focus_dir self.layout() return True else: return False def focus_previous(self): dir = 1 if dir == 1: cond = self.focus_idx > 0 else: cond = self.focus_idx < len(self)-1 if cond: #self.focus_idx > 0: dispatcher.send(GUIEvent.FocusCard()) self.focus_dir = -dir self.focus_idx += self.focus_dir self.layout() return True else: return False def toggle_sort(self): if self.sorted: self.sorted = False self.cards.sort(key=lambda c: self.orig_order[c.gamecard.key]) self.layout() else: self.sorted = True self.cards.sort(key=lambda c: str(c)) self.layout() def add_card(self, card): newcard = CardLibrary.CardLibrary.getCard(card) newcard._pos.set_transition(dt=0.3, method="sine") #ease_out_back") #self.pos_transition) #newcard._orientation.set(euclid.Quaternion()) #newcard._orientation.set_transition(dt=0.2, method=self.orientation_transition) newcard.size = anim.animate(0.1, 0.1, dt=0.3, method="sine") newcard.alpha = anim.animate(0, 1, dt=0.1, method="linear") self.cards.append(newcard) def move_to_end(self, card): self.cards.remove(card) self.cards.append(card) self.layout() def select_card(self, card): self.cards.remove(card) self.selected.append(card) #if self.focus_dir < 0: self.focus_idx += self.focus_dir #self.focus_idx += 1 if self.focus_idx > len(self)-1: self.focus_idx = len(self)-1 elif self.focus_idx < 0 and self.cards: self.focus_idx = 0 self.layout() self.layout_selected() def deselect_card(self, card): self.selected.remove(card) #self.cards.insert(self.focus_idx, card) # Find the right position to reinsert #if self.focus_idx < 0: self.focus_idx = 0 if self.focus_idx == len(self)-1: self.cards.append(card) else: self.cards.insert(self.focus_idx+1, card) # Find the right position to reinsert self.focus_idx += 1 self.layout() self.layout_selected() def handle_click(self, x, y): size = self.focus_size / 4. card = self.focused if card: sx, sy, sw, sh = card.pos.x, card.pos.y, card.width/2, card.height/2 if x > sx-sw and x < sx+sw and y >= sy-sh and y <= sy+sh: return 0, card for card in self.selected: sx, sy, sw, sh = card.pos.x, card.pos.y, card.width*size, card.height*size if x > sx-sw and x < sx+sw and y >= sy-sh and y <= sy+sh: return 1, card return -1, None def show(self): self.visible = 1.0 def hide(self): self.visible = 0.0 for card in self.cards: card.alpha = 0.5 #card._pos.set_transition(dt=0.25, method="ease_out_circ") card.pos = euclid.Vector3(-self.padding,0,0) card.size = anim.animate(card.size, 0.1, dt=0.25, method="ease_out_circ") for card in self.selected: card.alpha = 0.5 #card._pos.set_transition(dt=0.25, method="ease_out_circ") card.pos = euclid.Vector3(-self.padding,0,0) card.size = anim.animate(card.size, 0.1, dt=0.25, method="ease_out_circ") def layout_selected(self): if self.selected: size = self.focus_size / 2 swidth, sheight = self.selected[0].width*size, self.selected[0].height*size self.selected_width = swidth+2*self.padding x = self.width+swidth/2+2*self.padding yincr = (self.height-sheight) / (len(self.selected)+1) y = yincr+sheight/2 if self.dir == -1: y += -self.height for card in self.selected: card.size = size card.pos = euclid.Vector3(x,y,0) y += yincr else: self.selected_width = 0 def layout_straight(self): numcards = len(self) if numcards > 0: cards = self.cards dir = 1 #self.dir size = self.focus_size*0.95 #0.25 i = 0.001 x_bump = ((4-self.focus_idx)*self.shift_factor) if self.focus_idx < 4 else 0 x, y = self.cards[0].width*size*(x_bump+1/2.), 0 self.height = self.cards[0].height*self.focus_size if self.dir == -1: y = -self.height xincr = 0 #self.shift_factor j = 0 for card in cards[:self.focus_idx]: j+= 1 if j > self.focus_idx-4: xincr = self.shift_factor card.size = size card.alpha = 0.8 x += card.width*size*xincr #*dir card.pos = euclid.Vector3(x, y+card.height*self.focus_size/2*dir,i) #if self.is_library: card.hidden = True #i += 0.001 xincr = self.shift_factor*5 card = cards[self.focus_idx] card.size = self.focus_size card.alpha = 1.0 #x += card.width*self.focus_size*0.5*dir x += card.width*self.focus_size*2*xincr #*dir card.pos = euclid.Vector3(x, y+card.height*self.focus_size/2*dir,i) if self.is_library: card.hidden = False x += card.width*self.focus_size*2*xincr #*dir #x += card.width*self.focus_size*(1+xincr) #*dir #x += card.width*self.focus_size*0.5*dir xincr = 0 #self.shift_factor #i += 0.001 xincr = self.shift_factor j = 0 for card in cards[self.focus_idx+1:]: j += 1 if j > 4 : xincr = 0 card.size = size card.alpha = 0.8 x += card.width*size*xincr#*dir card.pos = euclid.Vector3(x, y+card.height*self.focus_size/2*dir,i) if self.is_library: card.hidden = False #i += 0.001 x_bump = ((4-j)*self.shift_factor) if j < 4 else 0 self.width = x+card.width*size*(x_bump+1/2.) self.scroll_bar = (0, y-28*dir, self.width, y-11*dir) self.scroll_shift = 6 self.scroll = (self.scroll_shift*self.focus_idx, self.scroll_bar[1], self.scroll_shift*(self.focus_idx+1-numcards)+self.width, self.scroll_bar[3]) else: self.width = 0 def layout_up(self): numcards = len(self) if numcards > 0: cards = self.cards dir = self.dir i = 0.001 x = 0 size = 0.8 y = cards[0].height*size*0.5*dir for card in cards[::dir]: card.size = size y += card.height*size*0.08*dir card.pos = euclid.Vector3(x,y,i) i += 0.001 def layout_bezier(self): numcards = len(self) dir = self.dir if numcards > 0: cards = self.cards path_param = 1./numcards cardcounter = 0 i = 0.001 for card in cards[:self.focus_idx]: point = self.path.get(cardcounter*path_param) card.pos = euclid.Vector3(point.x, point.y,i) card.size = 0.25 i += 0.001 cardcounter += 1 card = cards[self.focus_idx] point = self.path.get(cardcounter*path_param) card.pos = euclid.Vector3(point.x, point.y,i) card.size = 0.25 cardcounter += 1 i += 0.001 for card in cards[self.focus_idx+1:]: point = self.path.get(cardcounter*path_param) card.pos = euclid.Vector3(point.x, point.y,i) card.size = 0.25 i += 0.001 cardcounter += 1 self.width = int(point.x) #+card.width*0.25 self.scroll_bar = (0, -5*dir, self.width, -20*dir) #self.scroll_shift = self.width/len(self.cards) def render_after_transform(self): if self.dir == -1: y = -self.height else: y = 0 if self.visible == 1: alpha = 0.8 glColor4f(1., 1., 1., alpha) w, h = self.width+self.selected_width+self.padding*2, self.height+self.padding*4 x = -self.padding render_9_part("box2", w, h, x=x, y=y-self.padding*3) #w, h, x=0, y=-20) if len(self.cards) > 1: glColor4f(1., 1., 1., 1.) l, b, r, t = self.scroll_bar render_9_part("box6", width=r-l, height=t-b, x=l, y=b) l, b, r, t = self.scroll render_9_part("box2", width=r-l, height=t-b-2, x=l, y=b+1) arrow_width = 10 glColor4f(0,0,0,alpha) glBegin(GL_TRIANGLES) glVertex2f(x+1, arrow_width) glVertex2f(x+1, -arrow_width) glVertex2f(x-arrow_width, 0) glEnd() if self.cards: for card in self.cards[-1:self.focus_idx:-1]: card.draw() for card in self.cards[:self.focus_idx]: card.draw() self.focused.draw() for card in self.selected[::-1]: card.draw()
class StackView(CardView): width = anim.Animatable() height = anim.Animatable() def __init__(self, pos=euclid.Vector3(0,0,0)): super(StackView,self).__init__(pos) self.is_focused = False self._is_spaced = True self.visible = anim.constant(0) #self.header = Label("Stack", halign="left", valign="top") #self.header.pos = euclid.Vector3(0,0,0) #self.text = Label("", halign="left", valign="center", shadow=False, background=True) #self.text.visible = anim.animate(0, 0, dt=0.4, method="linear") self.width = anim.animate(0, 0, dt=0.2, method="ease_out") self.height = anim.animate(0, 0, dt=0.2, method="ease_out") #self.layout() def toggle(self): self._is_spaced = not self._is_spaced self.layout() def announce(self, ability, startt=0): if isinstance(ability, CastSpell): func = CardLibrary.CardLibrary.getStackCard elif isinstance(ability, ActivatedAbility): func = CardLibrary.CardLibrary.getActivatedCard else: func = CardLibrary.CardLibrary.getTriggeredCard newcard = func(ability.source, str(ability)) newcard.ability = ability return self.add_ability(newcard, startt) def add_ability(self, newcard, startt): self.cards.append(newcard) self.focus_idx = len(self)-1 newcard.size = anim.animate(0.2, 0.2, startt=startt, dt=0.5, method="ease_out_circ") if startt != 0: newcard.visible = anim.animate(0,1,dt=startt, method="step") #self.header.dt = startt else: pass #self.header.dt = 0.01 self.layout() newcard.alpha = anim.animate(0, 0.5, startt=startt, dt=0.3, method="ease_out_circ") newcard._pos.set_transition(dt=0.2, method="ease_out") #self.pos_transition) newcard.announced = False return newcard def finalize_announcement(self, ability): if ability.source == "Assign Damage": newcard = CardLibrary.CardLibrary.getCombatCard(ability) newcard.bordered = True newcard.ability = ability self.add_ability(newcard, 0) else: for card in self.cards: if ability == card.ability: card.announced = True card.alpha = 1.0 def remove_ability(self, ability): for idx, card in enumerate(self.cards): if ability == card.ability: self.cards.remove(card) if self.focus_idx >= len(self): self.focus_idx = len(self)-1 break else: raise Exception self.layout() def get_card(self, ability): for card in self.cards: if ability == card.ability: return card else: return None def focus(self, idx=-1): self.is_focused = True if idx == -1: self.focus_idx = len(self)-1 else: self.focus_idx = idx self.layout() def unfocus(self): self.is_focused = False self.unfocused_layout() def layout(self): if self.is_focused: self.focused_layout() else: self.unfocused_layout() def unfocused_layout(self): if self._is_spaced: spacing = 0.4 alpha = 1.0 else: spacing = 0.1 alpha = 0.1 size = 0.5 #self.text.visible = anim.animate(0.0, 0.0, dt=0.1) if len(self.cards): self.visible = 1.0 #self.header.visible = anim.animate(self.header.visible, 1.0, dt=self.header.dt, method="linear") #width, height = self.cards[0].width*size, self.cards[0].height*size width, height = self.cards[0].renderwidth*size, self.cards[0].renderheight*size self.cardwidth = width x_incr, y_incr = width*spacing, 0 #-height*size*0.20 #x, y = width*size/2, -self.header.height-height*size/2 #x, y = width*size/2+spacing, -height*size/2+y_incr x, y, z = spacing,0,0 for card in self.cards: card.size = size card.pos = euclid.Vector3(x,y,z) card.alpha = alpha x += x_incr y += y_incr z += 0.001 #card.alpha = alpha self.width = width + x_incr*(len(self.cards)-1) self.height = height else: self.visible = 0 def focused_layout(self): min_size = 0.2 if len(self) > 0: self.visible = 1.0 #self.header.visible = 0 #self.header.dt = 0.01 w, h = self.cards[0].width, self.cards[0].height x_incr = w*0.025 y_incr = h*0.025 startx, starty = 20, -20 x = startx-self.focus_idx*x_incr y = starty+(self.focus_idx-1)*y_incr z = 0.001 for i, card in enumerate(self.cards[:self.focus_idx]): card.size = min_size card.pos = euclid.Vector3(x,y,z) x += x_incr y -= y_incr z += 0.001 card = self.cards[self.focus_idx] card.size = self.focus_size #anim.animate(card.size, self.focus_size, dt=0.2, method="sine") card.pos = euclid.Vector3(startx+w*0.45, y-h*0.4, z) #self.text.visible = 1.0 #if card.bordered: self.text.visible = 1.0 #else: self.text.visible = 0.0 #self.text.pos = euclid.Vector3(startx, y-h*0.7, z) #self.text.set_text(str(card.ability), width=0.9*w) x -= x_incr*4 y -= h*0.8 z += 0.001 for i, card in enumerate(self.cards[self.focus_idx+1:]): card.size = min_size card.pos = euclid.Vector3(x,y,z) x -= x_incr y -= y_incr z += 0.001 else: self.visible = 0 def handle_click(self, x, y): x -= self.pos.x y -= self.pos.y w, h = self.width/2, self.height/2 if -w < x < w and -h < y < h: #if -10 < x < self.width+10 and self.height-10 < y < 5: for idx, card in enumerate(self.cards[::-1]): sx, sy, sw, sh = card.pos.x, card.pos.y, card.width*card.size/2, card.height*card.size/2 if x > sx-sw and x < sx+sw and y >= sy-sh and y <= sy+sh: return len(self.cards)-1-idx, card return -1, None def render_after_transform(self): #if self.header.visible == 1.0: #w, h = self.width, self.height #render_9_part("box2", # self.width*1.2, self.height, # x=-self.cardwidth/2, y=-h/2) super(StackView,self).render_after_transform()
class StatusView(Widget): alpha = anim.Animatable() def __init__(self, pos=zero, is_opponent=False): super(StatusView, self).__init__(pos) self._toggled = False self._spacing = 10 self._reveal_library = False self.color = (0.5, 0.5, 0.5) self.is_opponent = is_opponent #self._pos.set_transition(dt=0.1, method="linear") #symbols = ["life", "library", "hand", "graveyard", "exile"] symbols = ["life", "hand", "library", "graveyard", "exile"] self.symbols = dict([(symbol, cls(symbol)) for symbol, cls in zip( symbols, [Image, Image, Image, Image, Image])]) for symbol in self.symbols.values(): symbol.alpha = 0.8 self.player_name = Label("", 11, halign="left", fontname="Arial Bold", valign="center", shadow=False) #sizes = [20, 16, 14, 14, 14] sizes = [20, 14, 14, 14, 14] self.values = dict([(symbol, Label('', size, fontname="Arial Bold", halign="center", valign="center", shadow=False)) for symbol, size in zip(symbols, sizes)]) #for val in self.values.values(): self.avatar = Image(pyglet.image.Texture.create(80, 80)) self.avatar.shaking = 0 self.avatar.alpha = anim.animate(1., 1., dt=0.25) self.alpha = anim.animate(1., 1., dt=0.25) self.manapool = ManaPool(is_opponent) self.zone_view = ZoneView() self._library = LibraryImage(is_opponent) self.width, self.height = 145, 135 # self.layout() def resize(self, width, height): self.layout() # offset = 5 # if self.is_opponent: # pos = euclid.Vector3(offset, height-self.height-offset, 0) # else: # pos = euclid.Vector3(offset, offset, 0) # self._pos.set(pos) self._orig_pos = self.pos def clear(self): self.symbols['life'].rotatey = anim.constant(0) status = self.values counters = ["life", "hand", "library", "graveyard", "exile"] for c in counters: status[c].set_text(0) def toggle(self): if not self._toggled: x = self.width - self.values['life'].width - self._spacing * 1.5 self.pos += euclid.Vector3(-x, 0, 0) else: self.pos = self._orig_pos self._toggled = not self._toggled def toggle_library(self): self._reveal_library = not self._reveal_library def animate(self, status): symbol = self.symbols[status] symbol.scale = anim.animate(symbol.scale, 1.15 * symbol.scale, dt=1.0, method=lambda t: anim.oscillate_n(t, 3)) def handle_click(self, x, y): x -= self.pos.x y -= self.pos.y for status, item in self.symbols.items(): sx, sy, sw, sh = item.pos.x, item.pos.y, item.width / 2., item.height / 2. if x > sx - sw and x < sx + sw and y >= sy - sh and y <= sy + sh: return status else: return (0 < x <= self.width and 0 < y <= self.height) def setup_player(self, player, color, avatar): self.player = player self.color = color self.avatar.img = avatar.get_texture() self.player_name.set_text(player.name) self.update_life() for zone in ["library", "hand", "graveyard", "exile"]: self.update_zone(getattr(player, zone)) def new_turn(self, player): return life = self.symbols["life"] if self.player == player: life.rotatey = anim.animate(0, 360, dt=5, method='linear', extend='repeat') else: life.rotatey = anim.constant(0) def pass_priority(self, player): alpha = 1.0 if self.player == player else 0.6 self.alpha = self.avatar.alpha = alpha def animate_life(self, amount): symbol = self.symbols["life"] curr_scale = symbol._final_scale if amount > 0: final_scale = curr_scale * 1.5 else: final_scale = curr_scale * 0.5 symbol._scale = anim.animate(curr_scale, final_scale, dt=0.75, method="oscillate") symbol.alpha = anim.animate(symbol.alpha, 0.7, dt=0.75, method="oscillate") self.update_life() def update_life(self): status = self.values player = self.player counters = ["life"] #, "poison"] for c in counters: status[c].set_text(getattr(player, c)) def update_zone(self, zone): val = len(zone) status = self.values[str(zone)] if val > 0: # self.symbols[str(zone)].alpha = 0.8 status.set_text(val) else: # self.symbols[str(zone)].alpha = 0.4 status.set_text('0') if str(zone) == "library": self._library.update(zone) def layout(self): life_img, life = self.symbols["life"], self.values["life"] life_img.alpha = anim.constant(0.3) life_img._final_scale = 0.25 life_img._scale = anim.constant(life_img._final_scale) #life_img.visible = anim.constant(0) avatar = self.avatar spacing = self._spacing if self.is_opponent: x, y = spacing, life.height / 2. self.player_name.pos = euclid.Vector3(x, y, 0) self.manapool.pos = euclid.Vector3(self.width, 0, 0) x = self.width - life.width / 2 - spacing life.pos = life_img.pos = euclid.Vector3(x, y, 0) for i, status in enumerate(["graveyard", "library", "hand"]): symbol, value = self.symbols[status], self.values[status] #symbol.scale = 0.3 #symbol.pos = value.pos = euclid.Vector3(x, life.height+spacing+symbol.height/2+0.7*i*(symbol.height), 0) symbol.pos = value.pos = euclid.Vector3( x, life.height + spacing / 2 + symbol.height / 2 + i * (symbol.height), 0) library, lib = self._library, self.symbols["library"] library.scale = 0.5 library.pos = euclid.Vector3( self.width, life.height + spacing / 2 + 1.5 * lib.height, 0) #status = "library" #library, value = self.symbols["library"], self.values["library"] #library.scale = 0.3 #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, life.height+library.height/2+spacing,0) avatar.pos = euclid.Vector3( spacing + avatar.width / 2, life.height + avatar.height / 2 + spacing, 0) else: x, y = spacing, self.height - life.height / 2. self.player_name.pos = euclid.Vector3(x, y, 0) self.manapool.pos = euclid.Vector3(self.width, self.height, 0) x = self.width - life.width / 2 - spacing life.pos = life_img.pos = euclid.Vector3(x, y, 0) for i, status in enumerate(["graveyard", "library", "hand"][::-1]): symbol, value = self.symbols[status], self.values[status] #symbol.scale = 0.3 #symbol.pos = value.pos = euclid.Vector3(x, self.height-life.height-symbol.height/2-0.7*i*(symbol.height), 0) symbol.pos = value.pos = euclid.Vector3( x, self.height - life.height - symbol.height / 2 - i * (symbol.height) - spacing / 2, 0) library, lib = self._library, self.symbols["library"] library.scale = 0.5 library.pos = euclid.Vector3(self.width, 1.5 * lib.height, 0) #status = "library" #library, value = self.symbols["library"], self.values["library"] #library.scale = 0.3 #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, self.height-life.height-library.height/2-spacing,0) avatar.pos = euclid.Vector3( spacing + avatar.width / 2, self.height - life.height - avatar.height / 2 - spacing, 0) def render_after_transform(self): ac = self.color glColor4f(ac[0], ac[1], ac[2], self.alpha) life_height = self.values['life'].height h1, h2 = self.height - life_height, life_height if self.is_opponent: h1, h2 = h2, h1 render_9_part("box4", self.width, h1, x=0, y=0) render_9_part("box4", self.width, h2, x=0, y=h1) self.avatar.render() self.player_name.render() for status in ["life", "library", "hand", "graveyard"]: #, "exile"]: symbol, value = self.symbols[status], self.values[status] symbol.render() value.render() self.manapool.render() self.zone_view.render() if self._reveal_library: self._library.render()
class SelectionList(Widget): alpha = anim.Animatable() def __init__(self, pos=zero): super(SelectionList, self).__init__(pos) #self.options = [] #self.alpha = anim.animate(0, 0.9, dt=1.0, method="sine") self.border = 20 self.visible = anim.constant(0) #self.focus_idx = 0 self.large_size = 17 self.max_width = 700 #self.small_scale = 0.35 #self.intermediate_scale = 0.55 #self.layout = self.layout_normal self.prompt = Label("", size=self.large_size, halign="center", shadow=False) #def move_up(self): # if self.visible == 1 and self.focus_idx > 0: # self.focus_dir = -1 # self.options[self.focus_idx], self.options[self.focus_idx+self.focus_dir] = self.options[self.focus_idx+self.focus_dir], self.options[self.focus_idx] # self.focus_idx += self.focus_dir # self.layout() #def move_down(self): # if self.visible == 1 and self.focus_idx < len(self.options)-1: # self.focus_dir = 1 # self.options[self.focus_idx], self.options[self.focus_idx+self.focus_dir] = self.options[self.focus_idx+self.focus_dir], self.options[self.focus_idx] # self.focus_idx += self.focus_dir # self.layout() #def focus_previous(self): # if self.visible == 1 and self.focus_idx > 0: # self.focus_dir = -1 # self.focus_idx += self.focus_dir # self.layout() #def focus_next(self): # if self.visible == 1 and self.focus_idx < len(self.options)-1: # self.focus_dir = 1 # self.focus_idx += self.focus_dir # self.layout() #def hide(self): # for item, val in self.options: # item.pos = zero # self.visible = anim.animate(1., 0.0, dt=0.1) def construct(self, prompt, sellist): self.prompt.set_text(prompt) max_width = self.max_width document = mtg_decoder.decode_text(u'\u2028'.join( [str(val[0]) for val in sellist])) choice_list = pyglet.text.DocumentLabel(document, multiline=True, width=max_width, anchor_x="center", anchor_y="center") choice_list.set_style("color", (255, 255, 255, 255)) choice_list.set_style("font_name", "Arial") choice_list.set_style("font_size", 13.5) choice_list.set_style("halign", "center") self.choice_list = choice_list self.choices = [val[1] for val in sellist] #self.options = [(Label(str(val[0]), size=13.5, halign="center", shadow=False), val[1]) for val in sellist] #y = 0 #for item, val in self.options: # item._scale = anim.animate(1.0, 1.0, dt=dt, method=method) #self.focus_idx = len(self.options)/2 #self.layout() #self.width = max([item[0].width for item in self.options]+[self.prompt.width]) #self.height = sum([item[0].height for item in self.options]+[self.prompt.height]) #self.scroll = self.height/len(self.options) self.width = max(self.prompt.width, choice_list.content_width) self.height = choice_list.content_height + self.prompt.height self.prompt._pos.set( euclid.Vector3(0, (self.height - self.prompt.height) / 2, 0)) choice_list.x = (max_width - self.width) / 2 #def layout_normal(self): # x = y = 0 # self.prompt.scale = 0.7 # y -= self.prompt.height # self.prompt.pos = euclid.Vector3(0, y, 0) # for option, val in self.options: # #option.scale = 0.45 # y -= option.height # option.pos = euclid.Vector3(0, y, 0) #def layout_resize(self): # x = y = 0 # idx = self.focus_idx # self.prompt.scale = 0.7 # y -= self.prompt.height # self.prompt.pos = euclid.Vector3(0, y, 0) # count = 0 # for option, val in self.options[:idx]: # if count == idx - 1: option.scale = self.intermediate_scale # else: option.scale = self.small_scale # y -= option.height # option.pos = euclid.Vector3(0,y,0) # count += 1 # option, val = self.options[idx] # option.scale = 1.0 # y -= option.height # option.pos = euclid.Vector3(0,y,0) # count += 1 # for option, val in self.options[idx+1:]: # if count == idx + 1: option.scale = self.intermediate_scale # else: option.scale = self.small_scale # y -= option.height # option.pos = euclid.Vector3(0,y,0) # count += 1 def selection(self, indices, all): if not all: sel = [self.choices[i] for i in indices] if len(sel) == 1: sel = sel[0] return sel else: return [ self.choices[i] for i in range(len(self.choices) - 1, -1, -1) ] def handle_click(self, x, y): choice_list = self.choice_list xpos, ypos, cwidth, cheight = choice_list.x, choice_list.y, choice_list.content_width, choice_list.content_height y += ypos + cheight / 2 if 0 < y <= cheight: num_choices = len(self.choices) return num_choices - int(y // (cheight / num_choices)) - 1 else: return -1 def render_after_transform(self): w, h = self.border * 2 + self.width, self.border * 2 + self.height render_9_part("box4", w, h, x=-w / 2, y=-h / 2) self.prompt.render() self.choice_list.draw()
class Widget(anim.Animable): def pos(): def fget(self): return euclid.Vector3(self._pos.x, self._pos.y, self._pos.z) def fset(self, val): self._pos.x = val.x self._pos.y = val.y self._pos.z = val.z return locals() pos = property(**pos()) visible = anim.Animatable() rotatex = anim.Animatable() rotatey = anim.Animatable() rotatez = anim.Animatable() _scale = anim.Animatable() def scale(): def fget(self): return self._scale def fset(self, value): if isinstance(value, anim.Animator): self._final_scale = value.final() else: self._final_scale = value self._scale = value return locals() scale = property(**scale()) def __init__(self, pos=euclid.Vector3(0, 0, 0)): self._pos = AnimatedVector3(pos) self.visible = anim.animate(0, 1, dt=1.0) self.rotatex = anim.animate(0, 0, dt=1.0) self.rotatey = anim.animate(0, 0, dt=1.0) self.rotatez = anim.animate(0, 0, dt=1.0) self._final_scale = 1.0 self._scale = anim.animate(self._final_scale, self._final_scale, dt=0.25, method="linear") def show(self): self.visible = 1.0 def hide(self): self.visible = 0.0 def render(self): if self.visible > 0: glPushMatrix() glTranslatef(self.pos.x, self.pos.y, self.pos.z) glRotatef(self.rotatex, 1, 0, 0) glRotatef(self.rotatey, 0, 1, 0) glRotatef(self.rotatez, 0, 0, 1) glScalef(self.scale, self.scale, self.scale) self.render_after_transform() glPopMatrix()
class Table(Widget): _redzone_width = anim.Animatable() _render_redzone = anim.Animatable() _highlight_top = anim.Animatable() _highlight_bottom = anim.Animatable() def highlight(): def fset(self, val): if val == "top": self._highlight_top, self._highlight_bottom = 1.0, 0.7 elif val == "bottom": self._highlight_top, self._highlight_bottom = 0.7, 1.0 return locals() highlight = property(**highlight()) def render_redzone(): def fget(self): return self._render_redzone def fset(self, val): if val: self._render_redzone = 1. self._redzone_width = 1.5 else: self._render_redzone = 0. self._redzone_width = 0 return locals() render_redzone = property(**render_redzone()) def __init__(self): self.background = ImageCache.get_texture("matte.png") self._redzone_width = anim.animate(0, 0, dt=0.5, method="linear") self._render_redzone = anim.animate(0, 0, dt=0.5, method="linear") self._highlight_top = anim.animate(0, 0, dt=0.8, method="ease_out") self._highlight_bottom = anim.animate(0, 0, dt=0.8, method="ease_out") self.highlight = "bottom" self.numtiles = 8 self.size = 8 def draw(self): glClearColor(0, 0, 0, 1) glClear(GL_COLOR_BUFFER_BIT) numtiles, size, z = self.numtiles, self.size, 0 length = size * numtiles glNormal3f(.0, 1., .0) playmat = self.background glEnable(playmat.target) glBindTexture(playmat.target, playmat.id) #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #tc = playmat.tex_coords glBegin(GL_QUADS) ht, hb = self._highlight_top, self._highlight_bottom glColor4f(1.0, 1.0, 1.0, hb) #glTexCoord2f(-numtiles, -numtiles) #glVertex3f(-length, z, -length) #glTexCoord2f(numtiles, -numtiles) #glVertex3f(length, z, -length) #glTexCoord2f(numtiles, numtiles) #glVertex3f(length, z, length) #glTexCoord2f(-numtiles, numtiles) #glVertex3f(-length, z, length) glTexCoord2f(-numtiles, 0) glVertex3f(-length, z, 0) glTexCoord2f(numtiles, 0) glVertex3f(length, z, 0) glTexCoord2f(numtiles, numtiles) glVertex3f(length, z, length) glTexCoord2f(-numtiles, numtiles) glVertex3f(-length, z, length) glColor4f(1., 1., 1., ht) glTexCoord2f(-numtiles, -numtiles) glVertex3f(-length, z, -length) glTexCoord2f(numtiles, -numtiles) glVertex3f(length, z, -length) glTexCoord2f(numtiles, 0) glVertex3f(length, z, 0) glTexCoord2f(-numtiles, 0) glVertex3f(-length, z, 0) glEnd() glDisable(self.background.target) z += 0.005 if not self.render_redzone: glLineWidth(5.0) glBegin(GL_LINES) glColor4f(0., 0., 0., 0.7) glVertex3f(-length, z, 0) glVertex3f(length, z, 0) glEnd() else: y = self._redzone_width glEnable(playmat.target) glBindTexture(playmat.target, playmat.id) glColor4f(1.0, 0.0, 0.0, 1.0) glBegin(GL_QUADS) glTexCoord2f(-numtiles, -1) glVertex3f(-length, z, -y) glTexCoord2f(numtiles, -1) glVertex3f(length, z, -y) glTexCoord2f(numtiles, 1) glVertex3f(length, z, y) glTexCoord2f(-numtiles, 1) glVertex3f(-length, z, y) glEnd() glDisable(playmat.target) glLineWidth(2.0) glColor4f(0., 0., 0., .7) glBegin(GL_LINES) glVertex3f(-length, z, -y) glVertex3f(length, z, -y) glVertex3f(-length, z, y) glVertex3f(length, z, y) glEnd()