def handle_orientation_update(self, delta_angle: float): orientation = self.transform.viewing_direction rorientation = orientation.to_angle() % (pi * 2.0) aorientation = elisa.linalg.rad_to_angle(rorientation) s_angle = 1.0 if delta_angle >= 0 else -1.0 aorientation = aorientation + s_angle * elisa.linalg.rad_to_angle( abs(delta_angle) ) aorientation = aorientation % 360.0 orientation = elisa.linalg.angle_to_rad(aorientation) self.transform.viewing_direction = Vec2.from_angle(orientation)
def update(self, time_delta, entities): if len(entities) < 1: return None pvis = [e for e in entities if e.has_component_type("Collidable")] # for now we just render everyone having a position component # and do not care about the projection from world space coordinates to camera space renderables = [ e for e in entities if e.has_component_type("Renderable") and e.has_component_type("Transform2") ] # clear the backbuffer self.clear_back_buffer() for e in renderables: # get the position of the renderable and draw it - for now we assume that there is only one pos = e.get_of_type("Transform2").position rx = e.get_of_type("Renderable") col = rx.color if rx.shape == Shape.Point: pygame.draw.circle( self.back_buffer, col, (int(pos.x), int(pos.y)), 5, 0 ) elif rx.shape == Shape.Square: pygame.draw.rect( self.back_buffer, SRender.C_DARK_GRAY, (pos.x, pos.y, rx.width, rx.width), 1, ) else: pass fov_entity = [ e for e in entities if e.has_component_type("FieldOfView") and e.has_component_type("Transform2") ] if fov_entity: for e in fov_entity: transform = e.get_of_type("Transform2") fov = e.get_of_type("FieldOfView") pos, dvec = transform.position, transform.viewing_direction view_dist = fov.distance dvec_alpha = dvec.to_angle() fov_angle = fov.angle falpha1, falpha2 = (dvec_alpha - fov_angle / 2.0) % ( 2.0 * pi ), dvec_alpha + fov_angle / 2.0 % (2.0 * pi) N_sample = int(elisa.linalg.rad_to_angle(fov_angle)) v1 = Vec2.from_angle(falpha1) * view_dist v2 = Vec2.from_angle(falpha2) * view_dist dv = (v2 - v1) / N_sample pdvi = v1 pv1, pv2 = pos + v1, pos + v2 pygame.draw.polygon( self.back_buffer, SRender.C_VDARK_GRAY, [(pos.x, pos.y), (pv1.x, pv1.y), (pv2.x, pv2.y)], 0, ) for i in range(N_sample): # perform the collision test ppvi = pos + pdvi pdvi = pdvi + dv rayi = Ray2(origin=pos, direction=pdvi) for vis in pvis: visplanes = vis.get_of_type("Collidable").planes vpos = vis.get_of_type("Transform2").position vrx = vis.get_of_type("Renderable") intersects = False for planei in visplanes: r, t, _ip = elisa.linalg.intersection2(rayi, planei) if ( r and 0 <= t <= pdvi.length and elisa.linalg.inside_square2( vpos.x, vpos.y, vrx.width, _ip ) ): intersects = True break if intersects: pygame.draw.line( self.back_buffer, SRender.C_GRAY, (pos.x, pos.y), (ppvi.x, ppvi.y), 1, ) pygame.draw.rect( self.back_buffer, SRender.C_WHITE, (vpos.x, vpos.y, vrx.width, vrx.width), 1, ) pygame.draw.circle( self.back_buffer, SRender.C_DARK_GRAY, (int(pos.x), int(pos.y)), int(view_dist), 1, ) self.screen_buffer.blit(self.back_buffer, (0, 0)) pygame.display.flip() return None