def move_to(obj, target, **kwargs): """Move the object to a target position. Can be done using speed, time, or acceleration, but no combination of them. Note: object can still be moved by other applyMovement() calls. :param KX_GameObject obj: The object to move :param 3D Vector target: The world position to move to :keyword number speed: The velocity to move at. In blender units per second :keyword number time: How long you want the object to take to reach its target. In seconds. Speed will be automaticly calculated :keyword number acceleration: How quickly you want the object to accelerate. In blender units per second per second. :keyword number start_speed: (optional) (for acceleration) Initial speed for the object to move at. In blender units per second. :keyword number max_speed: (optional) (for acceleration) Speed at which to stop acceleration. In blender units per second. """ if 'accel' in kwargs: for key in kwargs.keys(): if key not in ('accel', 'start_speed', 'max_speed'): raise TypeError('%s is an invalid keyword argument for this function' % key) accel = kwargs['accel'] current_speed = kwargs['start_speed'] / (logic.getLogicTicRate()+1.0) if 'start_speed' in kwargs else 0.0 max_speed = kwargs['max_speed'] / (logic.getLogicTicRate()+1.0) if 'max_speed' in kwargs else False target = Vector(target) stop_next = False def move_callback(self, id): nonlocal stop_next, current_speed if not stop_next: if max_speed == False or current_speed < max_speed: current_speed += accel / (logic.getLogicTicRate()+1.0) elif current_speed > max_speed: current_speed = max_speed self.applyMovement( self.getVectTo(target)[1] * current_speed ) if self.getDistanceTo(target) - current_speed < 0.0: stop_next = True else: self.worldPosition = target current_speed = 0.0 self.logic_components.remove(id) elif 'speed' in kwargs: for key in kwargs: if key != 'speed': raise TypeError('%s is an invalid keyword argument for this function' % key) speed = kwargs['speed'] return move_to(obj, target, accel=0, start_speed=speed, max_speed=speed) elif 'time' in kwargs: for key in kwargs: if key != 'time': raise TypeError('%s is an invalid keyword argument for this function' % key) speed = obj.getDistanceTo(target) / kwargs['time'] return move_to(obj, target, speed=speed) else: raise TypeError('Second argument must be named "time", "speed", or "accel".') return move_callback
def __init__(self): self.register_signals() WorldInfo.tick_rate = int(logic.getLogicTicRate()) # Copy BGE data self.use_tick_rate = logic.getUseFrameRate() self.animation_rate = logic.getAnimationTicRate() self.use_animation_rate = logic.getRestrictAnimationUpdates() self.network_scene = next(iter(logic.getSceneList())) self.network_scene.post_draw = [self.render_callback] # Create sub systems self.network_system = self.create_network() self.physics_system = PhysicsSystem(self.physics_callback, self.scenegraph_callback) # Timing information self.current_time = 0.0 self.last_sent_time = 0 self.network_tick_rate = 25 self.metric_interval = 0.10 # Profile information self._state = None self.profile = logic.KX_ENGINE_DEBUG_SERVICES self.can_quit = SignalValue(self.check_quit()) # Load world Signal.update_graph() MapLoadedSignal.invoke() print("Network initialised")
def update(self): sssDynamic.update(self) sssDestroyable.update(self) dt = 1.0 / g.getLogicTicRate() if self.reloading > 0.0: self.reloading -= dt return else: self.reloading = 0.0 if not self.aiming: return dpitch = self.getDPitch() max_rot = dt * self.vel_pitch if abs(dpitch) > max_rot: dpitch = copysign(max_rot, dpitch) else: parent_aimed = True try: if self.parent.aim is not None: parent_aimed = False except: pass if parent_aimed: self.aiming = False self.applyRotation(Vector((0.0, dpitch, 0.0)), True)
def update(self): sssDynamic.update(self) sssDestroyable.update(self) # Propeller stoped conditions if not self['march'] or self['HP'] <= 0.0: return # Get the engine power and rotational velocity m = max(-3.0, min(3.0, self['march'])) if m > 0: nu = self['nu_d'] else: nu = self['nu_r'] rpm = self['RPM'] * m / 3.0 dt = 1.0 / g.getLogicTicRate() theta = 2.0 * pi / 60.0 * rpm * dt self.applyRotation(Vector((0.0, 0.0, theta)), True) if self.parent is not None: # Try to correct the factor try: factor = 2.5 * 1.0E6 * self.mass_factor except: factor = FACTOR f = copysign(nu * self['power'] * sqrt(abs(m) / 3.0), m) * factor self.parent.applyForce(self.getAxisVect(Vector((0.0, 0.0, f))), False)
def update(self): # Update the subsystems list, some subsystems could be not mutated # yet, or eventually added/removed self.getSubSystems() added = len(self._guns) - len(self._gun_target) self._gun_target.extend([None] * added) sssFloating.update(self) if self['HP'] <= 0.0: return if self._march is not None: for p in self._propellers: p['march'] = self._march if self._wheel is not None: for r in self._rudders: r['rudder'] = self._wheel if self._waypoint is not None: self.goTo(self._waypoint) for i, gun in enumerate(self._guns): if self._gun_target[i] is None: continue self.setGun(gun, self._gun_target[i]) for s in self._sensors: s.update() # Update the contacts and ghosts dt = 1.0 / g.getLogicTicRate() for obj in self.contacts.keys(): self.contacts[obj]['t'] -= dt if self.contacts[obj]['t'] < 0.0: self.removeContact(obj) for obj in self.ghosts.keys(): self.ghosts[obj]['t'] -= dt if self.ghosts[obj]['t'] < 0.0: self.removeGhost(obj)
def applyMovement(self, movement, *args, per_second=False): """Sets the game object's movement :keyword boolean per_second: Whether or not the movement should be in blender units per second instead of per frame. """ if per_second == True: movement = Vector(movement) / ( logic.getLogicTicRate() + 1 ) super().applyMovement(movement, *args)
def applyMovement(self, movement, *args, per_second=False): """Sets the game object's movement :keyword boolean per_second: Whether or not the movement should be in blender units per second instead of per frame. """ if per_second == True: movement = Vector(movement) / (logic.getLogicTicRate() + 1) super().applyMovement(movement, *args)
def update(self): self.__textOffset = 3 if not self.focused: self.__selection = -1 self.__caret_x = -1 self.__blink_time += (1.0 / BGE_Logic.getLogicTicRate()) if self.__blink_time >= 0.5: self.__blink = not self.__blink self.__blink_time = 0.0
def applyRotation(self, rotation, *args, per_second=False, units="radians"): """Sets the game object's rotation :keyword boolean per_second: Whether or not the movement should be in units per second instead of per frame. Defaults to True. :keyword str units: The units to use for rotation: radians or degrees. Defaults to radians. """ if per_second == True: rotation = Vector(rotation) / ( logic.getLogicTicRate() + 1 ) if units == "degrees": rotation = [ radians(axis) for axis in rotation ] super().applyRotation(rotation, *args)
def Update(): if dict['paused'] == True: scene.suspend() for i in range(1,4): if 'Digit%s' % i in obj and dict['levelClock'] >= 10**(3-i): scene.addObject('Num_%s' % (str(int(dict['levelClock']))[len(str(int(dict['levelClock'])))-(4-i)]),obj,1) if int(dict['levelClock']) == 0: if 'Digit3' in obj: scene.addObject('Num_0', obj,1) dict['levelClock'] += 1.0/(10*logic.getLogicTicRate())
def set_netmode(self, netmode): # Load configuration print("Loading network information from {}".format(DATA_PATH)) file_path = logic.expandPath("//{}".format(DATA_PATH)) # self.configuration_file_names = {path.splitext(f)[0] for f in listdir(file_path)} main_definition_path = path.join(file_path, "main.definition") # Load network information with open(main_definition_path, "r") as file: world_settings = load(file) self.network_update_interval = 1 / world_settings['tick_rate'] self.metric_interval = world_settings['metric_interval'] print("Set netmode", Netmodes[netmode]) self.world = World(netmode, logic.getLogicTicRate(), file_path) logic.world = self.world if netmode == Netmodes.server: port = world_settings['port'] self.world.rules = Rules() else: port = 0 self.network_manager = NetworkManager(self.world, "", port) # Time since last sent self.time_since_sent = 0.0 # Set network as active update function self.on_step = self.step_network self.cleanup = lambda: self.network_manager.stop() self._listeners['METHOD_INVOKE'] = self._on_invoke_method self._listeners['RPC_INVOKE'] = self._on_invoke_rpc self._listeners['PAWN_REASSOCIATE'] = self._on_controller_reassign self._listeners['SELF_MESSAGE'] = self._on_self_message self._listeners['SCENE_MESSAGE'] = self._on_scene_message self._listeners['PAWN_ASSOCIATE'] = self._on_controller_assign self._listeners['TO_NEW_PAWN'] = self._on_new_pawn_message if netmode == Netmodes.client: self._listeners['CONNECT_TO'] = self._on_connect_to # Set network state self._update_network_state() logic.sendMessage(encode_subject("NETWORK_INIT")) print("Network started")
def Update(): if dict['paused'] == True: scene.suspend() for i in range(1, 4): if 'Digit%s' % i in obj and dict['levelClock'] >= 10**(3 - i): scene.addObject( 'Num_%s' % (str(int(dict['levelClock']))[ len(str(int(dict['levelClock']))) - (4 - i)]), obj, 1) if int(dict['levelClock']) == 0: if 'Digit3' in obj: scene.addObject('Num_0', obj, 1) dict['levelClock'] += 1.0 / (10 * logic.getLogicTicRate())
def Update(): if dict['paused'] == True: scene.suspend() #The timer doesn't use the built in text system. Instead I modelled my own pixelated font and use this for loop #to determine which model to pull in for each digit. for i in range(1,4): if 'Digit%s' % i in obj and dict['levelClock'] >= 10**(3-i): scene.addObject('Num_%s' % (str(int(dict['levelClock']))[len(str(int(dict['levelClock'])))-(4-i)]),obj,1) if int(dict['levelClock']) == 0: if 'Digit3' in obj: scene.addObject('Num_0', obj,1) dict['levelClock'] += 1.0/(10*logic.getLogicTicRate())
def applyScale(self, scale, *args, per_second=False): """Sets the game object's scale. :keyword boolean per_second: Whether or not the scaling should be in blender units per second instead of per frame. """ if per_second == True: scale = Vector(scale) / (logic.getLogicTicRate() + 1) if args[0] == True: self.localScale += Vector(scale) else: s = scale scale_matrix = Matrix([[s[0], 0, 0, 0], [0, s[1], 0, 0], [0, 0, s[2], 0], [0, 0, 0, 1]]) self.localTransform += scale_matrix * self.localOrientation.to_4x4( )
def applyRotation(self, rotation, *args, per_second=False, units="radians"): """Sets the game object's rotation :keyword boolean per_second: Whether or not the movement should be in units per second instead of per frame. Defaults to True. :keyword str units: The units to use for rotation: radians or degrees. Defaults to radians. """ if per_second == True: rotation = Vector(rotation) / (logic.getLogicTicRate() + 1) if units == "degrees": rotation = [radians(axis) for axis in rotation] super().applyRotation(rotation, *args)
def move_callback(self, id): nonlocal stop_next, current_speed if not stop_next: if max_speed == False or current_speed < max_speed: current_speed += accel / (logic.getLogicTicRate()+1.0) elif current_speed > max_speed: current_speed = max_speed self.applyMovement( self.getVectTo(target)[1] * current_speed ) if self.getDistanceTo(target) - current_speed < 0.0: stop_next = True else: self.worldPosition = target current_speed = 0.0 self.logic_components.remove(id)
def move_callback(self, id): nonlocal stop_next, current_speed if not stop_next: if max_speed == False or current_speed < max_speed: current_speed += accel / (logic.getLogicTicRate() + 1.0) elif current_speed > max_speed: current_speed = max_speed self.applyMovement(self.getVectTo(target)[1] * current_speed) if self.getDistanceTo(target) - current_speed < 0.0: stop_next = True else: self.worldPosition = target current_speed = 0.0 self.logic_components.remove(id)
def navigate_ship(): if not conveyor.is_iteration_active: conveyor.start_iteration() is_iterated = False while not is_iterated: try: conveyor.iterate(1.0 / logic.getLogicTicRate()) except: conveyor.buffer_controls_complex_population = generate_controls_complex_population( conveyor.controls_optimizers[0].controls_constructing_parameters, conveyor.controls_optimizers[0].controls_evolution_parameters, ) else: is_iterated = True
def update(): """ Update the propellers rotation and bubbles generation @note Call this method each frame """ controller = g.getCurrentController() prop = controller.owner ship = prop.parent emitter = prop.children[0] speed = ship['speed'] w = copysign(2.0 * pi / 60.0 * speed * speed / 9.0 * rpm, speed) # Since is an child object velocity will not work dt = 1.0 / g.getLogicTicRate() theta = w * dt prop.applyRotation(Vector((theta, 0.0, 0.0)), True) emitter.applyRotation(Vector((-theta, 0.0, 0.0)), True) emitter['amount'] = abs(speed)**2
def applyScale(self, scale, *args, per_second=False): """Sets the game object's scale. :keyword boolean per_second: Whether or not the scaling should be in blender units per second instead of per frame. """ if per_second == True: scale = Vector(scale) / ( logic.getLogicTicRate() + 1 ) if args[0] == True: self.localScale += Vector(scale) else: s = scale scale_matrix = Matrix([ [s[0], 0, 0, 0], [ 0,s[1], 0, 0], [ 0, 0,s[2], 0], [ 0, 0, 0, 1] ]) self.localTransform += scale_matrix * self.localOrientation.to_4x4()
def update_bgm(self): fr = ( (1.0 / logic.getLogicTicRate()) * self.bgm_volume) / self.fade_time list = self.bgm_list[:] for b in range(len(list)): bgm = list[b] if bgm['status'] == self.BGM_STATUS_STOPPED: bgm['handle'].stop() self.bgm_list.remove(bgm) if bgm['status'] == self.BGM_STATUS_FADING_IN: bgm['volume'] += fr * self.bgm_volume if bgm['volume'] > self.bgm_volume: bgm['volume'] = self.bgm_volume bgm['status'] = self.BGM_STATUS_PLAYING elif bgm['status'] == self.BGM_STATUS_PLAYING: if b < len(self.bgm_list) - 1: bgm['status'] = self.BGM_STATUS_FADING_OUT # Begin fading out "extra" tracks elif bgm['status'] == self.BGM_STATUS_FADING_OUT: bgm['volume'] -= fr * self.bgm_volume if bgm['volume'] <= 0: self.bgm_list.remove(bgm) bgm['handle'].stop() if bgm['handle'].status == aud.AUD_STATUS_PLAYING: bgm['handle'].volume = bgm['volume']
def update(): """ Update the propellers rotation and bubbles generation @note Call this method each frame """ # Renew the ship instance (several instances of the same ship can be used) controller = g.getCurrentController() prop = controller.owner ship = prop.parent emitter = prop.children[0] # Get the ship data speed = ship['speed'] w = ship['propulsion']*copysign(2.0*pi/60.0 * speed*speed/9.0 * rpm, speed) # Since is an child object velocity will not work dt = 1.0/g.getLogicTicRate() theta = w*dt prop.applyRotation(Vector((theta,0.0,0.0)), True) emitter.applyRotation(Vector((-theta,0.0,0.0)), True) emitter['amount'] = int(ship['propulsion']*abs(speed)**2)
def update_bgm(self): fr = ((1.0 / logic.getLogicTicRate()) * self.bgm_volume ) / self.fade_time list = self.bgm_list[:] for b in range(len(list)): bgm = list[b] if bgm['status'] == self.BGM_STATUS_STOPPED: bgm['handle'].stop() self.bgm_list.remove(bgm) if bgm['status'] == self.BGM_STATUS_FADING_IN: bgm['volume'] += fr * self.bgm_volume if bgm['volume'] > self.bgm_volume: bgm['volume'] = self.bgm_volume bgm['status'] = self.BGM_STATUS_PLAYING elif bgm['status'] == self.BGM_STATUS_PLAYING: if b < len(self.bgm_list) - 1: bgm['status'] = self.BGM_STATUS_FADING_OUT # Begin fading out "extra" tracks elif bgm['status'] == self.BGM_STATUS_FADING_OUT: bgm['volume'] -= fr * self.bgm_volume if bgm['volume'] <= 0: self.bgm_list.remove(bgm) bgm['handle'].stop() if bgm['handle'].status == aud.AUD_STATUS_PLAYING: bgm['handle'].volume = bgm['volume']
def update(): """ Update the propellers rotation and bubbles generation @note Call this method each frame """ # Renew the ship instance (several instances of the same ship can be used) controller = g.getCurrentController() prop = controller.owner ship = prop.parent emitter = prop.children[0] # Get the ship data speed = ship['speed'] w = ship['propulsion'] * copysign( 2.0 * pi / 60.0 * speed * speed / 9.0 * rpm, speed) # Since is an child object velocity will not work dt = 1.0 / g.getLogicTicRate() theta = w * dt prop.applyRotation(Vector((theta, 0.0, 0.0)), True) emitter.applyRotation(Vector((-theta, 0.0, 0.0)), True) emitter['amount'] = int(ship['propulsion'] * abs(speed)**2)
def update(): """Method called each frame while the emitter exist""" cont = g.getCurrentController() obj = cont.owner # Test if we must not work due to the frustrum based culling if not testFrustrum(obj): return # Targeted number of particles and remaining ones to achieve it dt = 1.0/g.getLogicTicRate() obj['pending'] += dt * obj['rate'] while(obj['pending'] >= 1.0): generateParticle(obj) # Test if the object must end lifetime(obj) return
def __init__(self): super().__init__() self.register_signals() WorldInfo.tick_rate = int(logic.getLogicTicRate()) # Copy BGE data self.use_tick_rate = logic.getUseFrameRate() self.animation_rate = logic.getAnimationTicRate() self.use_animation_rate = logic.getRestrictAnimationUpdates() self.network_scene = next(iter(logic.getSceneList())) self.network_scene.post_draw = [self.render_callback] BGEComponentLoader.scene = self.network_scene # Create sub systems self.network_system = self.create_network() self.physics_system = BGEPhysicsSystem(self.physics_callback, self.scenegraph_callback) self.input_manager = BGEInputManager() # Timing information self.last_sent_time = 0 self.current_time = 0 self.network_tick_rate = 25 self.metric_interval = 0.10 # Profile information self._state = None self.profile_category = logic.KX_ENGINE_DEBUG_SERVICES self.pending_exit = False # Load world MapLoadedSignal.invoke() print("Network initialised")
def update(self): sssDynamic.update(self) sssDestroyable.update(self) if self.aim is None: return dyaw = self.getDYaw() yaw = self.localOrientation.to_euler().z - self.yaw0 # Get the sortest way if yaw < -pi: yaw += 2.0 * pi if yaw > pi: yaw -= 2.0 * pi if dyaw < -pi: dyaw += 2.0 * pi if dyaw > pi: dyaw -= 2.0 * pi # Test if we are trying to pass through the forbidden zone # In that case we must change the rotation direction if yaw + dyaw > self.max_yaw: dyaw -= 2.0 * pi if yaw + dyaw < self.min_yaw: dyaw += 2.0 * pi # Test if we are trying to aim out of the bounds if yaw + dyaw > self.max_yaw or yaw + dyaw < self.min_yaw: return dt = 1.0 / g.getLogicTicRate() max_rot = dt * self.vel_yaw if abs(dyaw) > max_rot: dyaw = copysign(max_rot, dyaw) else: # We will be already aimed at the end of this iteration self.aim = None self.applyRotation(Vector((0.0, 0.0, dyaw)), True)
def time_step(self): return 1 / logic.getLogicTicRate()
from bge import logic, events from component_system import update_scene from time import clock accumulator = 0.0 dt = 1 / logic.getLogicTicRate() last_time = clock() running = True while running: now = clock() elapsed = now - last_time last_time = now accumulator += elapsed while accumulator > dt: accumulator -= dt logic.NextFrame() for scene in logic.getSceneList(): update_scene(scene) if logic.getExitKey() in logic.keyboard.active_events: running = False break
def seconds(frames): '''Return frames converted to seconds. ''' return frames / logic.getLogicTicRate()
def frames(seconds): '''Return seconds converted to frames. ''' return seconds * logic.getLogicTicRate()
def SpriteMesh(spriteobj=None): """ Replaces the mesh of the object specified (or the object that the function is performed on) to draw a sprite. The average sprite replacement animation looks like: ['Explosion', 0, 1, 2, 3] Where the first value is the name of the mesh to replace for the sprite, and the later values are the image numbers (going upwards), where each individual sprite mesh is named the first value, then a later one. An example would be that the first sprite of an explosion would be named 'Explosion0'. If the sprite seems to be animating slowly (not on time), it's probably because the Rasterizer is working extra hard to change the meshes. You can see this in the profiler. To fix this, ensure no modifiers are present on the mesh frames to replace. Also, if there's a slight lag between switching sprites, this is because the sprite frames have a lot of polygons, and so loading them into and out of memory is slowing the BGE down. To fix this, place the sprites somewhere in the game scene to keep them around in memory. See SpriteInit function for possible object variables to change. The only argument for this function is: spriteobj = Which sprite's UV-mesh to change; None or omitted = this object """ from bge import logic import math sce = logic.getCurrentScene() cam = sce.active_camera cont = logic.getCurrentController() if spriteobj == None: obj = cont.owner else: obj = spriteobj if spriteobj == None: obj = cont.owner else: obj = spriteobj frequency = cont.sensors[0].frequency + 1 try: if obj[ 'sprcamoptimize']: # Optimization where if the sprite isn't on screen, it won't update every frame if cam.pointInsideFrustum(obj.position): cont.sensors[0].frequency = obj['sprfreqorig'] else: cont.sensors[0].frequency = obj['sprfreqorig'] + 5 if obj[ 'sprfpslock'] == 0: # Without FPS Locking on, the sprite will attempt to speed up when the game slows down and vise versa. fps = logic.getAverageFrameRate() if fps == 0.0: # At the game engine's initializing, getAverageFrameRate may return 0.0 because it samples the FPS over some time fps = logic.getLogicTicRate() else: # With FPS Locking on, the sprite will animate regardless of FPS changes. fps = logic.getLogicTicRate() ## I'll generally only use exact squares (e.g. 4 64x64 subimages on a 256x256 image), ## but I've decided to go with both a width and height variable for uneven images. ## The number for each is obtained by dividing one by the total number of sprite ## frames available on the sprite sheet (the same either way to equal a square ## sheet). For example, if you can fit 4 images on a 64x64 image, and each ## sprite is equal-sized and takes up the most space, then you would end up with ## even 32x32 images, or images whose sizes equal 0.5 each way. sprfps = obj['sprfps'] / fps anim = obj['spranim'] if anim != None: obj['sprpastsubimage'] = obj['sprsubimage'] if obj['sprfps'] != 0.0: # If spritefps == 0, don't advance the subimage obj['sprsubimage'] += round(sprfps, 2) * frequency # GameLogic's logic tic rate is constant, but if FPS drops below the tic rate, the animations will adjust if math.floor(obj['sprsubimage']) > len(anim) - 1: if obj['sprfps'] > 0: while obj['sprsubimage'] > (len(anim) - 1): obj['sprsubimage'] -= (len(anim) - 1) else: obj['sprsubimage'] = 1.0 elif math.floor(obj[ 'sprsubimage']) < 1.0: # Hack that makes sure the subimage is never looking at the animation column for a frame if obj['sprfps'] > 0: obj[ 'sprsubimage'] = 1.0 # Shouldn't really ever happen that the subimage is going up, but somehow goes below 0; if it does, just set it to a healthy 1. else: while obj['sprsubimage'] < (len(anim) - 1): obj['sprsubimage'] += (len(anim) - 1) if obj['sprsubimage'] < 1.0: obj['sprsubimage'] = 1.0 if obj['sprsubimage'] > len(anim): obj['sprsubimage'] = len(anim) - 1 subi = math.floor(obj['sprsubimage']) frame = anim[0] + str(anim[subi]) if str(obj.meshes[ 0]) != frame: # Only replace the mesh if the object's current mesh isn't equal to the one to use (if it's equal, then the mesh was replaced earlier) obj.replaceMesh(frame) ori = obj.worldOrientation.to_euler() if obj['sprflipx']: ori.z += math.pi if obj['sprflipy']: ori.x += math.pi if obj[ 'sprrotate'] != None: # If you set the rotate value, then you're saying that you'll handle it, so be aware of that ori.y += obj['sprrotate'] obj.worldOrientation = ori except KeyError: # Initialize the sprite object if it hasn't been initialized SpriteInit(obj)
def update(self): if self.enabled: self.time += (1.0 / logic.getLogicTicRate()) * (self.delay + 1.0)
def Sprite(spriteobj=None): """ Animates the UV-coordinates of the object specified (or the object that the function is performed on) to draw a sprite. The average animation looks like: [0, 0, 1, 2, 3] Where the first value is the position of the animation's column, and the later ones are the frame numbers (going upwards) The only argument for this function is: spriteobj = Which sprite's UV-mesh to change; None or omitted = this object """ sce = logic.getCurrentScene() cam = sce.active_camera cont = logic.getCurrentController() if spriteobj == None: obj = cont.owner else: obj = spriteobj frequency = cont.sensors[0].frequency + 1 try: #obj['anim'] = [0, 0, 1, 0, 3] # A test animation using the first column of the spritesheet, with the first, second, and fourth sprite sheet cells being used if obj[ 'sprcamoptimize']: # Optimization where if the sprite isn't on screen, it won't update every frame if cam.pointInsideFrustum(obj.position): cont.sensors[0].frequency = obj['sprfreqorig'] else: cont.sensors[0].frequency = obj['sprfreqorig'] + 5 if obj[ 'sprfpslock'] == 0: # Without FPS Locking on, the sprite will attempt to speed up when the game slows down and vise versa. fps = logic.getAverageFrameRate() if fps == 0.0: # At the game engine's initializing, getAverageFrameRate may return 0.0 because it samples the FPS over some time fps = logic.getLogicTicRate() else: # With FPS Locking on, the sprite will animate regardless of FPS changes. fps = logic.getLogicTicRate() ## I'll generally only use exact squares (e.g. 4 64x64 subimages on a 256x256 image), ## but I've decided to go with both a width and height variable for uneven images. ## The number for each is obtained by dividing one by the total number of sprite ## frames available on the sprite sheet (the same either way to equal a square ## sheet). For example, if you can fit 4 images on a 64x64 image, and each ## sprite is equal-sized and takes up the most space, then you would end up with ## even 32x32 images, or images whose sizes equal 0.5 each way. sprfps = obj['sprfps'] / fps anim = obj['spranim'] if anim != None: obj['sprpastsubimage'] = obj['sprsubimage'] if obj['sprfps'] != 0.0: # If spritefps == 0, don't advance the subimage obj['sprsubimage'] += round(sprfps, 2) * frequency # GameLogic's logic tic rate is constant, but if FPS drops below the tic rate, the animations won't adjust if math.floor(obj['sprsubimage']) > len(anim) - 1: if obj['sprfps'] > 0: while obj['sprsubimage'] > (len(anim) - 1): obj['sprsubimage'] -= (len(anim) - 1) else: obj['sprsubimage'] = 1.0 elif math.floor(obj[ 'sprsubimage']) < 1.0: # Hack that makes sure the subimage is never looking at the animation column for a frame if obj['sprfps'] > 0: obj[ 'sprsubimage'] = 1.0 # Shouldn't really ever happen that the subimage is going up, but somehow goes below 0; if it does, just set it to a healthy 1. else: while obj['sprsubimage'] < (len(anim) - 1): obj['sprsubimage'] += (len(anim) - 1) if obj['sprsubimage'] < 1.0: obj['sprsubimage'] = 1.0 if obj['sprsubimage'] > len(anim): obj['sprsubimage'] = len(anim) - 1 subi = math.floor(obj['sprsubimage']) ## This below is pretty much the only way to get the info from the vertices ## When viewing a plane so that the sprite appears straight on: ## Vertex 0 = Top-Right ## Vertex 1 = Top-Left ## Vertex 2 = Bottom-Left ## Vertex 3 = Bottom-Right ## I believe this has to do with culling, which apparently takes place ## counter-clockwise here (?) vertex = [None, None, None, None] for a in range(4): vertex[a] = obj.meshes[obj['sprmat']].getVertex(obj['sprmesh'], a) # The sprite object's vertices; used only by the Sprite() function if obj['sprflipx'] == 0 and obj['sprflipy'] == 0: vertex[0].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[1].setUV([obj['sprh'] * anim[0], obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[2].setUV([obj['sprh'] * anim[0], obj['sprw'] * anim[subi]]) vertex[3].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] * anim[subi]]) elif obj['sprflipx'] == 0 and obj['sprflipy'] == 1: vertex[3].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[2].setUV([obj['sprh'] * anim[0], obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[1].setUV([obj['sprh'] * anim[0], obj['sprw'] * anim[subi]]) vertex[0].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] * anim[subi]]) elif obj['sprflipx'] == 1 and obj['sprflipy'] == 0: vertex[1].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[0].setUV([obj['sprh'] * anim[0], obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[3].setUV([obj['sprh'] * anim[0], obj['sprw'] * anim[subi]]) vertex[2].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] * anim[subi]]) else: vertex[2].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[3].setUV([obj['sprh'] * anim[0], obj['sprw'] + (obj['sprw'] * anim[subi])]) vertex[0].setUV([obj['sprh'] * anim[0], obj['sprw'] * anim[subi]]) vertex[1].setUV([obj['sprh'] + (obj['sprh'] * anim[0]), obj['sprw'] * anim[subi]]) if obj[ 'sprrotate'] != None: # If you don't set the rotate value, then you're saying that you'll handle it. ori = obj['sprori'].copy() ori.y += obj['sprrotate'] obj.orientation = ori except KeyError: # Initialize the sprite object if it hasn't been initialized SpriteInit(obj)
def update(self, frequency=0): if self.on: self.time += (1.0 / logic.getLogicTicRate()) * (frequency + 1)
def play(self, anim_name, reset_subimage_on_change=True): if not anim_name in self.anim_dict: print("ERROR: SpriteMap owner " + self.obj.name + " has no animation named " + anim_name + ".") return False elif len(self.anim_dict[anim_name]['animation']) < 2: print("ERROR: SpriteMap owner " + self.obj.name + "'s animation " + anim_name + " does not contain data " "for at least one frame of " "animation.") return False self.current_animation = anim_name if self.current_animation != self.prev_animation: self.on_animation_change(self, self.current_animation, self.prev_animation) # Callback if reset_subimage_on_change: self.subimage = 1.0 if self.adjust_by_sensor_frequency: freq = logic.getCurrentController().sensors[0].frequency + 1 else: freq = 1 if self.fps_lock: scene_fps = logic.getLogicTicRate() else: scene_fps = logic.getAverageFrameRate() if scene_fps == 0.0: scene_fps = logic.getLogicTicRate() if anim_name and anim_name in self.anim_dict: anim = self.anim_dict[anim_name]['animation'] anim_fps = self.anim_dict[anim_name]['fps'] target_fps = anim_fps / scene_fps if len(anim) > 2: # Don't advance if there's only one cell to the animation if target_fps != 0.0: self.subimage += round(target_fps, 2) * freq subi = round(self.subimage, 4) if (self.subimage <= len(anim) - 2 and anim_fps > 0) or (self.subimage > 1.0 and anim_fps < 0): self.is_playing = True if self.anim_dict[anim_name]['loop']: # The animation is to be looped fin = 0 if len(anim) >= 2: while math.floor(subi) > len(anim) - 1: subi -= len(anim) - 1 fin = 1 while math.floor(subi) < 1.0: subi += len(anim) - 1 fin = 1 if fin: self.on_animation_finished(self) # Animation's finished because it's looping self.is_playing = True else: # No loop if subi >= len(anim) - 1 or subi < 1.0: if self.is_playing: self.on_animation_finished(self) # Animation's finished because it's at the end of a # non-looping animation if len(anim) >= 2: subi = min(max(subi, 1.0), len(anim) - 1) else: subi = 1.0 self.is_playing = False if math.floor(subi) != math.floor(self.prev_subimage): self.on_subimage_change(self, math.floor(subi), math.floor(self.prev_subimage)) # Callback for subimage change self.subimage = subi else: print("ERROR: ANIMATION NAME " + anim_name + " NOT IN SPRITEMAP OR NOT STRING.") self.prev_animation = self.current_animation self.prev_subimage = self.subimage if self.obj.invalid: # You did something that killed the object; STOP PRODUCTION! print("ERROR: SPRITE MAP OPERATING ON NON-EXISTENT OBJECT!!!") return False return True
def init(): if settings.looming: scene = GameLogic.getCurrentScene() scene.replace("Looming") GameLogic.Object = {} print("BLENDER: GameLogic object created") GameLogic.Object['closed'] = False GameLogic.Object['lapCounter'] = 0 GameLogic.Object['frameCounter'] = 0 GameLogic.setLogicTicRate(100) GameLogic.setMaxLogicFrame(100) GameLogic.setMaxPhysicsFrame(100) sys.stdout.write("BLENDER: Maximum number of logic frames per render frame: %d\n" % GameLogic.getMaxLogicFrame() ) sys.stdout.write("BLENDER: Logic tic rate: %d\n" % GameLogic.getLogicTicRate() ) sys.stdout.write("BLENDER: Maximum number of physics frames per render frame: %d\n" % GameLogic.getMaxPhysicsFrame() ) sys.stdout.write("BLENDER: Physics update frequency: %d Hz\n" % GameLogic.getPhysicsTicRate() ) # open arduino and pump try: arduino = arduino_serial.SerialPort(settings.arduino_port, 19200) sys.stdout.write("BLENDER: Successfully opened arduino on {0}\n".format(settings.arduino_port)) except OSError: sys.stdout.write("BLENDER: Failed to open arduino\n") arduino = None GameLogic.Object['arduino'] = arduino if arduino is not None: arduino.write(b'd') # Set all valves to low arduino.write(b'6') arduino.write(b'8') arduino.write(b'0') arduino.write(b'f') try: pumppy = serial.Serial(settings.pump_port, 19200, timeout=1) sys.stdout.write("BLENDER: Successfully opened pump\n") gc.setPumpVolume(pumppy, settings.reward_volume) except: sys.stdout.write("BLENDER: Failed to open pump\n") pumppy = None if settings.replay_track is not None: fn_pos = settings.replay_track + '.position' if not os.path.exists(fn_pos): print("BLENDER: Could not find " + fn_pos) settings.replay_track = None else: sys.path.append(os.path.expanduser("~/../cs/py2p/tools")) import training print("BLENDER: Reading replay track from " + fn_pos) GameLogic.Object['replay_pos'] = training.read_pos( fn_pos, 1e9, False, meters=False) posy = GameLogic.Object['replay_pos'][1] evlist, timeev = training.read_events( settings.replay_track + ".events", teleport_times=None) GameLogic.Object['replay_rewards'] = np.array([ ev.time for ev in evlist if ev.evcode == b'RE']) GameLogic.Object['replay_rewards'] = np.sort(GameLogic.Object['replay_rewards']) if settings.replay_rewards_shuffle: intervals = np.diff([0] + GameLogic.Object['replay_rewards'].tolist()) intervals = np.random.permutation(intervals) print(intervals) GameLogic.Object['replay_rewards'] = np.cumsum(intervals) print("Replay reward times: ", GameLogic.Object['replay_rewards']) GameLogic.Object['nreplay'] = 0 if settings.gratings: if not "grating1" in GameLogic.Object.keys(): GameLogic.Object["grating1"] = chooseWalls.grating( ori=settings.verticalGratingAngle, sf=settings.verticalGratingScale) GameLogic.Object["grating2"] = chooseWalls.grating( ori=settings.obliqueGratingAngle, sf=settings.obliqueGratingScale) chooseWalls.initWalls() # for wallkey in ["LW1", "RW1"]: # chooseWalls.set_texture_buffer( # GameLogic.Object["grating1"], wallkey) # for wallkey in ["LW2", "RW2"]: # chooseWalls.set_texture_buffer( # GameLogic.Object["grating2"], wallkey) # if ncl.has_comedi: print("BLENDER: Found comedi library") gOuttrigsubdev = 2 gOuttrigchan = 0 gOutfrchan = 1 gOutleftchan = 2 gOutrightchan = 3 gOutexpchan = 4 gIntrigsubdev = 7 gIntrigchan = 0 gDevrange = 0 # open ni trigger channels devintrigch, fdintrigch, nameintrigch = ncl.open_dev("/dev/comedi0_subd2") devouttrigch, fdouttrigch, nameouttrigch = ncl.open_dev("/dev/comedi0_subd11") intrigch = ncl.nichannel(devintrigch, gIntrigchan, gIntrigsubdev, fdintrigch, gDevrange) outtrigch = ncl.nichannel(devouttrigch, gOuttrigchan, gOuttrigsubdev, fdouttrigch, gDevrange) outfrch = ncl.nichannel(devouttrigch, gOutfrchan, gOuttrigsubdev, fdouttrigch, gDevrange) outleftch = ncl.nichannel(devouttrigch, gOutleftchan, gOuttrigsubdev, fdouttrigch, gDevrange) outrightch = ncl.nichannel(devouttrigch, gOutrightchan, gOuttrigsubdev, fdouttrigch, gDevrange) outexpch = ncl.nichannel(devouttrigch, gOutexpchan, gOuttrigsubdev, fdouttrigch, gDevrange) #MC2015 ncl.init_comedi_dig(intrigch, outtrigch, outfrch, outleftch, outrightch, outexpch #MC2015 ) else: intrigch = None outtrigch = None outfrch = None outleftch = None outrightch = None outexpch = None #MC2015 GameLogic.Object['intrigch'] = intrigch GameLogic.Object['outtrigch'] = outtrigch GameLogic.Object['outfrch'] = outfrch GameLogic.Object['outleftch'] = outleftch GameLogic.Object['outrightch'] = outrightch GameLogic.Object['outexpch'] = outexpch #MC2015 GameLogic.Object['pumppy'] = pumppy GameLogic.Object['left_on'] = False GameLogic.Object['right_on'] = False GameLogic.Object['file_open'] = False GameLogic.Object['train_open'] = False GameLogic.Object['bcstatus'] = False gio.create_data_dir() GameLogic.Object['time0'] = time.time() GameLogic.Object['prevtime'] = time.time() GameLogic.Object['nframes'] = 0 GameLogic.Object['rewcount'] = 0 GameLogic.Object['rewfail'] = 0 GameLogic.Object['puffcount'] = 0 GameLogic.Object['puffthistrial'] = 0 GameLogic.Object['isloom'] = 0 GameLogic.Object['loomcounter']=0 GameLogic.Object['totalLooms'] = 0 GameLogic.Object['loom_first_trial']=0 GameLogic.Object['rewpos'] = [0.98] # 1.0 # np.zeros((16)) GameLogic.Object['boundx'] = 8.0 GameLogic.Object['boundy'] = 158.0 GameLogic.Object['hysteresis'] = 0.5 GameLogic.Object['speed_tracker'] = np.zeros((100)) GameLogic.Object['lapCounter'] = 0 blenderpath = GameLogic.expandPath('//') if not settings.cpp: s1, conn1, addr1, p1 = gc.spawn_process("\0mouse0socket", ['python3', '%s/py/usbclient.py' % blenderpath, '0']) s2, conn2, addr2, p2 = gc.spawn_process("\0mouse1socket", ['python3', '%s/py/usbclient.py' % blenderpath, '1']) else: if settings.readlib=="xinput": mice = xinput.find_mice(model=settings.mouse) for mouse in mice: # xinput.set_owner(mouse) # Don't need this if using correct udev rule xinput.switch_mode(mouse) if settings.usezmq: procname = 'readout_zmq' else: procname = 'readout' if len(mice)>=1: s1, conn1, addr1, p1 = \ gc.spawn_process( "\0mouse0socket", [('%s/cpp/generic-ev/' % blenderpath) + procname, '%d' % mice[0].evno, '0'], usezmq=settings.usezmq) else: s1, conn1, addr1, p1 = None, None, None, None if len(mice)>=3: s2, conn2, addr2, p2 = \ gc.spawn_process( "\0mouse1socket", [('%s/cpp/generic-ev/readout' % blenderpath) + procname, '%d' % mice[2].evno, '1'], usezmq=settings.usezmq) else: s2, conn2, addr2, p2 = None, None, None, None elif settings.readlib=="libusb": s1, conn1, addr1, p1 = \ gc.spawn_process("\0mouse1socket", ['%s/cpp/g500-usb/readout' % blenderpath, '1']) s2, conn2, addr2, p2 = \ gc.spawn_process("\0mouse0socket", ['%s/cpp/g500-usb/readout' % blenderpath, '0']) else: s1, conn1, addr1, p1, s2, conn2, add2, p2 = \ None, None, None, None, None, None, None, None if settings.has_fw: if not settings.fw_local: GameLogic.Object['fwip'] = '' #"128.40.202.203" sfw, connfw, addrfw = gc.spawn_process_net(GameLogic.Object['fwip']) if connfw is None: settings.has_fw = False else: sys.stdout.write("BLENDER: Starting fw... ") sys.stdout.flush() sfw, connfw, addrfw, pfw = \ gc.spawn_process("\0fwsocket", ['%s/cpp/dc1394/dc1394' % blenderpath,], #MC2015 system=False, addenv={"SDL_VIDEO_WINDOW_POS":"\"1280,480\""}) print("done") connfw.send(GameLogic.Object['fw_trunk'].encode('latin-1')) gc.recv_ready(connfw) connfw.setblocking(0) GameLogic.Object['fwconn'] = connfw GameLogic.Object['has_fw'] = settings.has_fw if settings.has_usb3: sys.stdout.write("BLENDER: Starting usb3... ") sys.stdout.flush() susb3, connusb3, addrusb3, pusb3 = \ gc.spawn_process( "\0" + settings.usb3_pupil, ['{0}/cpp/usb3/arv-camera-test'.format(blenderpath), '-n', settings.usb3_pupil], #MC2015 system=False, addenv={"SDL_VIDEO_WINDOW_POS":"\"1280,480\""}) print("done") print("Sending usb3 file name " + GameLogic.Object['fw_trunk']) connusb3.send(GameLogic.Object['fw_trunk'].encode('latin-1')) gc.recv_ready(connusb3) connusb3.setblocking(0) GameLogic.Object['usb3conn'] = connusb3 if settings.usb3_body is not None: s2usb3, conn2usb3, addr2usb3, p2usb3 = \ gc.spawn_process( "\0" + settings.usb3_body, ['{0}/cpp/usb3/arv-camera-test'.format(blenderpath), '-n', settings.usb3_body], #MC2015 system=False, addenv={"SDL_VIDEO_WINDOW_POS":"\"1280,480\""}) print("done") print("Sending usb3 file name " + GameLogic.Object['fw_trunk'] + 'body') conn2usb3.send((GameLogic.Object['fw_trunk'] + 'body').encode('latin-1')) gc.recv_ready(conn2usb3) conn2usb3.setblocking(0) GameLogic.Object['usb3conn2'] = conn2usb3 GameLogic.Object['has_usb3'] = settings.has_usb3 if settings.has_comedi and ncl.has_comedi: scomedi, conncomedi, addrcomedi, pcomedi = \ gc.spawn_process("\0comedisocket", ['python3', '%s/py/nicomedi.py' % blenderpath,]) conncomedi.send(blenderpath.encode('latin-1')) gc.recv_ready(conncomedi) conncomedi.setblocking(0) GameLogic.Object['comediconn'] = conncomedi if settings.has_licksensor: slick, connlick, addrlick, plick = \ gc.spawn_process("\0licksocket", ['python3', '%s/py/licksensor.py' % blenderpath,]) connlick.send(blenderpath.encode('latin-1')) gc.recv_ready(connlick) connlick.setblocking(0) GameLogic.Object['lickconn'] = connlick if settings.has_licksensor_piezo: slickpiezo, connlickpiezo, addrlickpiezo, plickpiezo = \ gc.spawn_process("\0lickpiezosocket", ['python3', '%s/py/licksensorpiezo.py' % blenderpath,]) connlickpiezo.send(blenderpath.encode('latin-1')) gc.recv_ready(connlickpiezo) connlickpiezo.setblocking(0) GameLogic.Object['lickpiezoconn'] = connlickpiezo if settings.cpp: for mconn in [conn1, conn2]: if mconn is not None: mconn.send(b'start') gc.recv_ready(mconn, usezmq=settings.usezmq) if not settings.usezmq: mconn.setblocking(0) if len(mice): GameLogic.Object['m1conn'] = conn1 GameLogic.Object['m2conn'] = conn2 else: GameLogic.Object['m1conn'] = None GameLogic.Object['m2conn'] = None GameLogic.Object['tmprec'] = False GameLogic.Object['trainrec'] = False GameLogic.Object['RewardTicksCounter'] = None GameLogic.Object['RewardChange'] = False GameLogic.Object['WallTouchTicksCounter'] = None GameLogic.Object['OdorTicksCounter'] = None GameLogic.Object['piezolicks'] = 0 GameLogic.Object['piezoframes'] = 0 GameLogic.Object['piezoframepause'] = 0 GameLogic.Object['lapCounter'] = 0 scene = GameLogic.getCurrentScene() if scene.name == "Scene": playerName = 'MovingCube' legName = 'LeftLeg' elif scene.name == "Looming": playerName = 'MovingCube.002' legName = 'LeftLeg.002' else: playerName = 'MovingCube.001' legName = 'LeftLeg.001' rew_sensor = scene.objects[playerName] touch_sensor = scene.objects[legName] rew_sensor.sensors['SReward'].usePosPulseMode = True touch_sensor.sensors['SLeftTouch'].usePosPulseMode = True GameLogic.Object['scene_changed'] = 0 GameLogic.Object['scene_name'] = scene.name GameLogic.Object['reset_pulse'] = False #current injection variables #variables for current injection - MC2015 GameLogic.Object['start_pulse_y'] = 50 GameLogic.Object['inj_amp'] = 50 GameLogic.Object['do_tbs1'] = False GameLogic.Object['do_tbs2'] = False gu.zeroPos() gc.zeroPump()
# ############################################################################### # VSync # from bge import logic as G from bge import render as R from bge import events as GK from random import random from mathutils import Vector, geometry, Color import math as m # change these values G.duration = 60.0 * 10 G.prerollPostroll = 0.5 print(G.getLogicTicRate()) # G.setLogicTicRate(180) print("LogicTicRate: ", G.getLogicTicRate()) print("MaxLogicFrame: ", G.getMaxLogicFrame()) print("MaxPhysicsFrame: ", G.getMaxPhysicsFrame()) # G.setMaxLogicFrame(1) print("MaxLogicFrame: ", G.getMaxLogicFrame()) def init_world(): G.scene = G.getCurrentScene() objects = G.scene.objects R.showMouse(True) G.red = objects["red"]
def move_to(obj, target, **kwargs): """Move the object to a target position. Can be done using speed, time, or acceleration, but no combination of them. Note: object can still be moved by other applyMovement() calls. :param KX_GameObject obj: The object to move :param 3D Vector target: The world position to move to :keyword number speed: The velocity to move at. In blender units per second :keyword number time: How long you want the object to take to reach its target. In seconds. Speed will be automaticly calculated :keyword number acceleration: How quickly you want the object to accelerate. In blender units per second per second. :keyword number start_speed: (optional) (for acceleration) Initial speed for the object to move at. In blender units per second. :keyword number max_speed: (optional) (for acceleration) Speed at which to stop acceleration. In blender units per second. """ if 'accel' in kwargs: for key in kwargs.keys(): if key not in ('accel', 'start_speed', 'max_speed'): raise TypeError( '%s is an invalid keyword argument for this function' % key) accel = kwargs['accel'] current_speed = kwargs['start_speed'] / ( logic.getLogicTicRate() + 1.0) if 'start_speed' in kwargs else 0.0 max_speed = kwargs['max_speed'] / ( logic.getLogicTicRate() + 1.0) if 'max_speed' in kwargs else False target = Vector(target) stop_next = False def move_callback(self, id): nonlocal stop_next, current_speed if not stop_next: if max_speed == False or current_speed < max_speed: current_speed += accel / (logic.getLogicTicRate() + 1.0) elif current_speed > max_speed: current_speed = max_speed self.applyMovement(self.getVectTo(target)[1] * current_speed) if self.getDistanceTo(target) - current_speed < 0.0: stop_next = True else: self.worldPosition = target current_speed = 0.0 self.logic_components.remove(id) elif 'speed' in kwargs: for key in kwargs: if key != 'speed': raise TypeError( '%s is an invalid keyword argument for this function' % key) speed = kwargs['speed'] return move_to(obj, target, accel=0, start_speed=speed, max_speed=speed) elif 'time' in kwargs: for key in kwargs: if key != 'time': raise TypeError( '%s is an invalid keyword argument for this function' % key) speed = obj.getDistanceTo(target) / kwargs['time'] return move_to(obj, target, speed=speed) else: raise TypeError( 'Second argument must be named "time", "speed", or "accel".') return move_callback
def play(self, anim_name, reset_subimage_on_change=True): if not anim_name in self.anim_dict: print("ERROR: SpriteMap owner " + self.obj.name + " has no animation named " + anim_name + ".") return False elif len(self.anim_dict[anim_name]['animation']) < 2: print("ERROR: SpriteMap owner " + self.obj.name + "'s animation " + anim_name + " does not contain data " "for at least one frame of " "animation.") return False self.current_animation = anim_name if self.current_animation != self.prev_animation: self.on_animation_change(self, self.current_animation, self.prev_animation) # Callback if reset_subimage_on_change: self.subimage = 1.0 if self.adjust_by_sensor_frequency: freq = logic.getCurrentController().sensors[0].frequency + 1 else: freq = 1 if self.fps_lock: scene_fps = logic.getLogicTicRate() else: scene_fps = logic.getAverageFrameRate() if scene_fps == 0.0: scene_fps = logic.getLogicTicRate() if anim_name and anim_name in self.anim_dict: anim = self.anim_dict[anim_name]['animation'] anim_fps = self.anim_dict[anim_name]['fps'] target_fps = anim_fps / scene_fps if len( anim ) > 2: # Don't advance if there's only one cell to the animation if target_fps != 0.0: self.subimage += round(target_fps, 2) * freq subi = round(self.subimage, 4) if (self.subimage <= len(anim) - 2 and anim_fps > 0) or (self.subimage > 1.0 and anim_fps < 0): self.is_playing = True if self.anim_dict[anim_name][ 'loop']: # The animation is to be looped fin = 0 if len(anim) >= 2: while math.floor(subi) > len(anim) - 1: subi -= len(anim) - 1 fin = 1 while math.floor(subi) < 1.0: subi += len(anim) - 1 fin = 1 if fin: self.on_animation_finished( self) # Animation's finished because it's looping self.is_playing = True else: # No loop if subi >= len(anim) - 1 or subi < 1.0: if self.is_playing: self.on_animation_finished( self ) # Animation's finished because it's at the end of a # non-looping animation if len(anim) >= 2: subi = min(max(subi, 1.0), len(anim) - 1) else: subi = 1.0 self.is_playing = False if math.floor(subi) != math.floor(self.prev_subimage): self.on_subimage_change(self, math.floor(subi), math.floor(self.prev_subimage)) # Callback for subimage change self.subimage = subi else: print("ERROR: ANIMATION NAME " + anim_name + " NOT IN SPRITEMAP OR NOT STRING.") self.prev_animation = self.current_animation self.prev_subimage = self.subimage if self.obj.invalid: # You did something that killed the object; STOP PRODUCTION! print("ERROR: SPRITE MAP OPERATING ON NON-EXISTENT OBJECT!!!") return False return True
def looming(): init_scale_up = [1.5, 1, 0] init_scale_down = [2, 1, 0] fin_scale = [0, 0, 0] speedscale = 1.0 xuprescale = (2.34)*speedscale yuprescale = (1.56)*speedscale xdownrescale = (1.92)*speedscale ydownrescale = (0.96)*speedscale positions = np.array([(-10, 50, 90), (-10, 50, -15)]) stop = settings.loom_interval-(settings.loom_grow_dur+settings.loom_maintain_dur)# 30000-(grow_dur+maintain_dur) circle = GameLogic.getCurrentScene().objects["Circle"] if ( GameLogic.Object['train_open'] or GameLogic.Object['file_open']) and ( GameLogic.Object['loom_first_trial'] < settings.loom_first_trial_delay): GameLogic.Object['loom_first_trial'] += 1 elif ( GameLogic.Object['train_open'] or GameLogic.Object['file_open']): #print("Start looming stimulus presentation") #print(GameLogic.Object['loomcounter']) if GameLogic.Object['loomcounter'] == 0: tracked_speed = np.median(np.abs(GameLogic.Object['speed_tracker']))*1e2 * GameLogic.getLogicTicRate() if tracked_speed > settings.loom_speed_threshold: # Start trial GameLogic.Object['puffthistrial'] = random.randint(0,1) if settings.isloom_random: GameLogic.Object['isloom'] = random.randint(0,1) else: GameLogic.Object['isloom'] = 1 print("BLENDER: Looming stimulus trial starting - running detected.Puff: "+str(GameLogic.Object['puffthistrial'])) if settings.loom_random: rand_pos_idx = random.randint(0,len(positions)-1) else: rand_pos_idx = 0 GameLogic.Object['rand_pos_idx'] = rand_pos_idx circle.worldPosition = positions[rand_pos_idx] if rand_pos_idx == 0: if GameLogic.Object['isloom']: circle.localScale = init_scale_up else: circle.localScale = fin_scale elif rand_pos_idx == 1: if GameLogic.Object['isloom']: circle.localScale = init_scale_down else: circle.localScale = fin_scale GameLogic.Object['loomcounter'] += 1 elif GameLogic.Object['loomcounter'] < settings.loom_grow_dur + settings.loom_maintain_dur + stop: if GameLogic.Object['loomcounter'] < settings.loom_grow_dur: # Change scale during trial if (GameLogic.Object['rand_pos_idx'] == 0 and GameLogic.Object['isloom']): circle.localScale.x +=(xuprescale) circle.localScale.y +=(yuprescale) elif (GameLogic.Object['rand_pos_idx'] == 1 and GameLogic.Object['isloom']): circle.localScale.x +=(xdownrescale) circle.localScale.y +=(ydownrescale) elif GameLogic.Object['loomcounter'] > settings.loom_grow_dur + settings.loom_maintain_dur: # Stop trial and wait circle.localScale= fin_scale if settings.loom_airpuff_delay is not None: if (settings.puff_random and GameLogic.Object['puffthistrial']== 1) or not settings.puff_random: if GameLogic.Object['loomcounter']%settings.puffint == settings.loom_airpuff_delay and \ GameLogic.Object['puffcount'] < settings.puffnb: airpuff_loom() GameLogic.Object['puffcount']+= 1 else: airpuff_loom_stop() GameLogic.Object['loomcounter'] += 1 else: # Restart GameLogic.Object['loomcounter'] = 0 GameLogic.Object['puffcount'] = 0 else: circle.localScale= fin_scale if GameLogic.Object['train_open'] or GameLogic.Object['file_open']: gio.write_looming(circle)