#!/usr/bin/env python3 """ raylib [core][python] example - 3d cmaera split screen https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_split_screen.c The code is a close a possible to the C version, except the loop uses itertools.product """ from itertools import product import pyray as pr SCREEN_WIDTH = 800 SCREEN_HEIGHT = 450 def main(): # Initialization pr.init_window( SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [core] example - 3d camera split screen" ) camera_player1 = pr.Camera3D( pr.Vector3(0, 1, -3), pr.Vector3(0, 1), pr.Vector3(0, 1), 45, ) screen_player1 = pr.load_render_texture(SCREEN_WIDTH // 2, SCREEN_HEIGHT) # Setup player two camera and screen camera_player2 = pr.Camera3D( pr.Vector3(-3, 3), pr.Vector3(0, 3), pr.Vector3(0, 1), 45, ) screen_player2 = pr.load_render_texture(SCREEN_WIDTH // 2, SCREEN_HEIGHT) # Build a flipped rectangle the size of the split view to use for drawing later split_screen_rect = pr.Rectangle( 0, 0, screen_player1.texture.width, -screen_player1.texture.height, ) # Grid data count = 5 spacing = 4 # Set our game to run at 60 frames-per-second pr.set_target_fps(60) # Main game loop while not pr.window_should_close(): # Detect window close button or ESC key # Update # If anyone moves this frame, how far will they move based on the time since the last frame # this moves things at 10 world units per second, regardless of the actual FPS offset_this_frame = 10.0 * pr.get_frame_time() # Move Player1 forward and backwards (no turning) if pr.is_key_down(pr.KEY_W): camera_player1.position.z += offset_this_frame camera_player1.target.z += offset_this_frame elif pr.is_key_down(pr.KEY_S): camera_player1.position.z -= offset_this_frame camera_player1.target.z -= offset_this_frame # Move Player2 forward and backwards (no turning) if pr.is_key_down(pr.KEY_UP): camera_player2.position.x += offset_this_frame camera_player2.target.x += offset_this_frame elif pr.is_key_down(pr.KEY_DOWN): camera_player2.position.x -= offset_this_frame camera_player2.target.x -= offset_this_frame # Draw Player1 view to the render texture pr.begin_texture_mode(screen_player1) pr.clear_background(pr.SKYBLUE) pr.begin_mode_3d(camera_player1) # Draw scene: grid of cube trees on a plane to make a "world" # Simple world plane pr.draw_plane( pr.Vector3(0, 0, 0), pr.Vector2(50, 50), pr.BEIGE, ) xz_iter = product( range(-count * spacing, count * spacing, spacing), range(-count * spacing, count * spacing, spacing), ) # for x in range(-count*spacing, count*spacing, spacing): # for z in range(-count*spacing, count*spacing, spacing): for x, z in xz_iter: pr.draw_cube(pr.Vector3(x, 1.5, z), 1, 1, 1, pr.LIME) pr.draw_cube(pr.Vector3(x, 0.5, z), 0.25, 1, 0.25, pr.BROWN) # Draw a cube at each player's position pr.draw_cube(camera_player1.position, 1, 1, 1, pr.RED) pr.draw_cube(camera_player2.position, 1, 1, 1, pr.BLUE) pr.end_mode_3d() pr.draw_rectangle( 0, 0, pr.get_screen_width() // 2, 40, pr.fade(pr.RAYWHITE, 0.8) ) pr.draw_text("PLAYER1: W/S to move", 10, 10, 20, pr.MAROON) pr.end_texture_mode() # Draw Player2 view to the render texture pr.begin_texture_mode(screen_player2) pr.clear_background(pr.SKYBLUE) pr.begin_mode_3d(camera_player2) # Draw scene: grid of cube trees on a plane to make a "world" # Simple world plane pr.draw_plane( pr.Vector3(0, 0, 0), pr.Vector2(50, 50), pr.BEIGE, ) xz_iter = product( range(-count * spacing, count * spacing, spacing), range(-count * spacing, count * spacing, spacing), ) # for x in range(-count*spacing, count*spacing, spacing): # for z in range(-count*spacing, count*spacing, spacing): for x, z in xz_iter: pr.draw_cube( pr.Vector3(x, 1.5, z), 1, 1, 1, pr.LIME, ) pr.draw_cube(pr.Vector3(x, 0.5, z), 0.25, 1, 0.25, pr.BROWN) # Draw a cube at each player's position pr.draw_cube(camera_player1.position, 1, 1, 1, pr.RED) pr.draw_cube(camera_player2.position, 1, 1, 1, pr.BLUE) pr.end_mode_3d() pr.draw_rectangle( 0, 0, pr.get_screen_width() // 2, 40, pr.fade(pr.RAYWHITE, 0.8) ) pr.draw_text("PLAYER2: UP/DOWN to move", 10, 10, 20, pr.DARKBLUE) pr.end_texture_mode() # Draw both views render textures to the screen side by side pr.begin_drawing() pr.clear_background(pr.BLACK) pr.draw_texture_rec( screen_player1.texture, split_screen_rect, pr.Vector2(0, 0), pr.WHITE ) pr.draw_texture_rec( screen_player2.texture, split_screen_rect, pr.Vector2(SCREEN_WIDTH / 2.0, 0), pr.WHITE, ) pr.draw_rectangle( pr.get_screen_width() // 2 - 2, 0, 4, pr.get_screen_height(), pr.LIGHTGRAY ) pr.end_drawing() # De-Initialization pr.unload_render_texture(screen_player1) # Unload render texture pr.unload_render_texture(screen_player2) # Unload render texture pr.close_window() # Close window and OpenGL context if __name__ == "__main__": main()