def ResolveToRGBA(self, name, mode): c = self.Resolve(name, mode) if c.var: return self.ResolveToRGBA(c.var, mode) result = Color() result.a = self.ResolveOpacity(c) rgb = c if c.rgb_var: rgb = self.ResolveToRGBA(c.RGBVarToVar(), mode) (result.r, result.g, result.b) = (rgb.r, rgb.g, rgb.b) return result
def ResolveToRGBA(self, name, mode): c = self.Resolve(name, mode) if c.rgb_var: result = Color() result.a = c.a rgb = self.ResolveToRGBA(c.RGBVarToVar(), mode) (result.r, result.g, result.b) = (rgb.r, rgb.g, rgb.b) return result elif c.var: return self.ResolveToRGBA(c.var, mode) else: return c
def main(): """Main function, it implements the application loop""" # Initialize pygame, with the default parameters pygame.init() # Define the size/resolution of our window res_x = 1280 res_y = 720 # Create a window and a display surface screen = pygame.display.set_mode((res_x, res_y)) # Create a scene scene = Scene("TestScene") scene.camera = Camera(False, res_x, res_y) # Moves the camera back 2 units scene.camera.position -= Vector3(0, 0, 0) # Creates the terrain meshes and materials terrain_object = create_terrain() scene.add_object(terrain_object) # Game variables # A missile spawns every 2 seconds (this time gets smaller every missile, to # make the game harder with time) missile_spawn_time = 2 # Time until the next missile is shot missile_timer = missile_spawn_time # Storage for all missiles active in the game missiles = [] # Flashing effect Color flash_color = Color(0, 0, 0, 0) # Total time of the current flash total_flash_time = 0 # Time elapsed for the current flash flash_timer = 0 # Minimum time between player shots shot_cooldown = 0.2 # Timer for the shot cooldown shot_timer = 0 # Storage for all the shots active in the game shots = [] # Timer delta_time = 0 prev_time = time.time() # Show mouse cursor pygame.mouse.set_visible(True) # Don't lock the mouse cursor to the game window pygame.event.set_grab(False) # Game loop, runs forever while True: # Process OS events for event in pygame.event.get(): # Checks if the user closed the window if event.type == pygame.QUIT: # Exits the application immediately return elif event.type == pygame.KEYDOWN: # If ESC is pressed exit the application if event.key == pygame.K_ESCAPE: return elif event.type == pygame.MOUSEBUTTONDOWN: # If the user has the mouse button down if shot_timer <= 0: # We're not on cooldown, so we can shoot # Get the mouse position and convert it to NDC (normalized # device coordinates) mouse_pos = pygame.mouse.get_pos() mouse_pos = ((mouse_pos[0] / res_x) * 2 - 1, (mouse_pos[1] / res_y) * 2 - 1) # Create a shot shot = Shot() # Initialize the position and direction of the shot, based on the # mouse position on the screen. For this, we request the scene camera the # ray corresponding to the mouse position shot.position, shot.direction = scene.camera.ray_from_ndc( mouse_pos) # Add the shot to the scene (for rendering) and on the shot storage, for # all other operations scene.add_object(shot) shots.append(shot) # Reset the cooldown shot_timer = shot_cooldown # Clears the screen with a very dark blue (0, 0, 20) screen.fill((0, 0, 0)) # Spawn new missiles missile_timer -= delta_time if missile_timer < 0: # It's time to spawn a new missile # Reduce time until the next missile, but clamp it so we don't have more than # one missile every half a second missile_spawn_time -= 0.025 if missile_spawn_time < 0.5: missile_spawn_time = 0.5 # Reset the timer missile_timer = missile_spawn_time # Create a new missile new_missile = Missile() # Add the missile to the scene (for rendering) and on the missile storage, # for all other operations scene.add_object(new_missile) missiles.append(new_missile) # Animate missiles # We need the following to keep track of all missiles we'll have to destroy, # since we can't change the storage while we're iterating it missiles_to_destroy = [] for missile in missiles: # Update the missile missile.update(delta_time) # Check if the missile is close to the player plane (z < 0.1) if missile.position.z < 0.1: # Check if the missile is close enough to the player to hit him if missile.position.magnitude() < 0.25: # It has hit the player, flash the screen red for one second flash_color = Color(1, 0, 1, 1) total_flash_time = flash_timer = 1 # Destroy missile (remove it from the scene and add it to the destruction # list so we can remove it in a bit) missiles_to_destroy.append(missile) scene.remove_object(missile) # Animate shots # We need the following to keep track of all shots we'll have to destroy, # since we can't change the storage while we're iterating it shots_to_destroy = [] for shot in shots: # Update the shot shot.update(delta_time) # Check if the shot is too far away, and add it to the destruction list, # besides removing it from the scene if shot.position.z > 12: # Destroy shot shots_to_destroy.append(shot) scene.remove_object(shot) # Update shot cooldown shot_timer -= delta_time # Check collisions for shot in shots: # Check each shot with each missile for missile in missiles: # Check the distance between the shot and the missile, it it is below # a threshould (in this case 0.5), destroy the missile and the shot distance = Vector3.distance(shot.position, missile.position) if distance < 0.5: # Add it to the missile destruction list, and remove it from the scene missiles_to_destroy.append(missile) scene.remove_object(missile) # Add it to the shot destruction list, and remove it from the scene shots_to_destroy.append(shot) scene.remove_object(shot) # Flash the screen cyan for 0.5 seconds flash_color = Color(0, 1, 1, 1) total_flash_time = flash_timer = 0.5 # Actually delete objects missiles = [x for x in missiles if x not in missiles_to_destroy] shots = [x for x in shots if x not in shots_to_destroy] # Render scene scene.render(screen) # Render screen flash if flash_timer > 0: flash_timer -= delta_time if flash_timer > 0: flash_color.a = flash_timer / total_flash_time # Render the full screen rectangle, using additive blend screen.fill(flash_color.premult_alpha().tuple3(), None, pygame.BLEND_RGB_ADD) # Swaps the back and front buffer, effectively displaying what we rendered pygame.display.flip() # Updates the timer, so we we know how long has it been since the last frame delta_time = time.time() - prev_time prev_time = time.time()