More core examples (#13)

* Added core_input_keys example

* Added core_basic_window example

* Added core_input_mouse example

* Added core_input_mouse_wheel example

* Added Rectangle struct

* Added core_input_gestures example to utilize the Rectangle struct

* Removed unused imports

* Used the right draw function for the example

* PEP8 fixes

* Added core 2d camera examples

* Added core 2d camera examples
This commit is contained in:
Matt Lebrun 2020-09-19 16:02:17 +08:00 committed by GitHub
parent 6854ec4a3e
commit 6a3be55fe2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 462 additions and 10 deletions

View file

@ -0,0 +1,137 @@
"""
raylib [core] example - 2d camera
"""
from raylib.pyray import PyRay
from raylib.colors import (
RAYWHITE,
DARKGRAY,
RED,
GREEN,
SKYBLUE,
BLUE,
BLACK,
)
pyray = PyRay()
# Initialization
MAX_BUILDINGS = 100
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 450
pyray.init_window(SCREEN_WIDTH, SCREEN_HEIGHT,
'raylib [core] example - 2d camera')
player = pyray.Rectangle(400, 280, 40, 40)
buildings = []
build_colors = []
spacing = 0
for i in range(MAX_BUILDINGS):
width = pyray.get_random_value(50, 200)
height = pyray.get_random_value(100, 800)
y = SCREEN_HEIGHT - 130 - height
x = -6000 + spacing
buildings.append(pyray.Rectangle(x, y, width, height))
spacing += width
build_colors.append(pyray.Color(
pyray.get_random_value(200, 240),
pyray.get_random_value(200, 240),
pyray.get_random_value(200, 250),
255
))
camera = pyray.Camera2D()
camera.target = pyray.Vector2(player.x + 20, player.y + 20)
camera.offset = pyray.Vector2(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)
camera.rotation = 0.0
camera.zoom = 1.0
pyray.set_target_fps(60) # Set our game to run at 60 frames-per-second
# Main game loop
while not pyray.window_should_close(): # Detect window close button or ESC key
# Update
# Player movement
if pyray.is_key_down(pyray.KEY_RIGHT):
player.x += 2
elif pyray.is_key_down(pyray.KEY_LEFT):
player.x -= 2
# Camera target follows player
camera.target = pyray.Vector2(player.x + 20, player.y + 20)
# Camera rotation controls
if pyray.is_key_down(pyray.KEY_A):
camera.rotation -= 1
elif pyray.is_key_down(pyray.KEY_S):
camera.rotation += 1
# Limit camera rotation to 80 degrees (-40 to 40)
if camera.rotation > 40:
camera.rotation = 40
elif camera.rotation < -40:
camera.rotation = -40
# Camera zoom controls
camera.zoom += pyray.get_mouse_wheel_move() * 0.05
if camera.zoom > 3.0:
camera.zoom = 3.0
elif camera.zoom < 0.1:
camera.zoom = 0.1
# Camera reset (zoom and rotation)
if pyray.is_key_pressed(pyray.KEY_R):
camera.zoom = 1.0
camera.rotation = 0.0
# Draw
pyray.begin_drawing()
pyray.clear_background(RAYWHITE)
pyray.begin_mode_2d(camera)
pyray.draw_rectangle(-6000, 320, 13000, 8000, DARKGRAY)
for i in range(MAX_BUILDINGS):
pyray.draw_rectangle_rec(buildings[i], build_colors[i])
pyray.draw_rectangle_rec(player, RED)
x = int(camera.target.x)
y = int(camera.target.y)
pyray.draw_line(x, -SCREEN_HEIGHT * 10, x, SCREEN_HEIGHT * 10, GREEN)
pyray.draw_line(-SCREEN_WIDTH * 10, y, SCREEN_WIDTH * 10, y, GREEN)
pyray.end_mode_2d()
pyray.draw_text('SCREEN AREA', 640, 10, 20, RED)
pyray.draw_rectangle(0, 0, SCREEN_WIDTH, 5, RED)
pyray.draw_rectangle(0, 5, 5, SCREEN_HEIGHT - 10, RED)
pyray.draw_rectangle(SCREEN_WIDTH - 5, 5, 5, SCREEN_HEIGHT - 10, RED)
pyray.draw_rectangle(0, SCREEN_HEIGHT - 5, SCREEN_WIDTH, 5, RED)
pyray.draw_rectangle(10, 10, 250, 113, pyray.fade(SKYBLUE, 0.5))
pyray.draw_rectangle_lines(10, 10, 250, 113, BLUE)
pyray.draw_text('Free 2d camera controls:', 20, 20, 10, BLACK)
pyray.draw_text('- Right/Left to move Offset', 40, 40, 10, DARKGRAY)
pyray.draw_text('- Mouse Wheel to Zoom in-out', 40, 60, 10, DARKGRAY)
pyray.draw_text('- A / S to Rotate', 40, 80, 10, DARKGRAY)
pyray.draw_text('- R to reset Zoom and Rotation', 40, 100, 10, DARKGRAY)
pyray.end_drawing()
# De-Initialization
pyray.close_window() # Close window and OpenGL context

View file

@ -0,0 +1,314 @@
"""
raylib [core] example - 2d camera platformer
"""
from math import sqrt
from raylib.pyray import PyRay
from raylib.colors import (
DARKGRAY,
RED,
BLACK,
GRAY,
LIGHTGRAY,
)
pyray = PyRay()
# Initialization
global g_evening_out, g_even_out_target
g_evening_out = False
G = 400
PLAYER_JUMP_SPD = 350.0
PLAYER_HOR_SPD = 200.0
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 450
pyray.init_window(SCREEN_WIDTH, SCREEN_HEIGHT,
'raylib [core] example - 2d camera')
# Raylib Math
def vector2_subtract(v1, v2):
return pyray.Vector2(v1.x - v2.x, v1.y - v2.y)
def vector2_add(v1, v2):
return pyray.Vector2(v1.x + v2.x, v1.y + v2.y)
def vector2_length(v):
return sqrt((v.x * v.x) + (v.y * v.y))
def vector2_scale(v, scale):
return pyray.Vector2(v.x * scale, v.y * scale)
class Player:
def __init__(self, position, speed, can_jump):
self.position = position
self.speed = speed
self.can_jump = can_jump
class EnvItem:
def __init__(self, rect, blocking, color):
self.rect = rect
self.blocking = blocking
self.color = color
def update_player(player, env_items, delta):
if pyray.is_key_down(pyray.KEY_LEFT):
player.position.x -= PLAYER_HOR_SPD * delta
if pyray.is_key_down(pyray.KEY_RIGHT):
player.position.x += PLAYER_HOR_SPD * delta
if pyray.is_key_down(pyray.KEY_SPACE) and player.can_jump:
player.speed = -PLAYER_JUMP_SPD
player.can_jump = False
hit_obstacle = False
for ei in env_items:
p = player.position
if (
ei.blocking and
ei.rect.x <= p.x and
ei.rect.x + ei.rect.width >= p.x and
ei.rect.y >= p.y and
ei.rect.y < p.y + player.speed * delta
):
hit_obstacle = True
player.speed = 0.0
p.y = ei.rect.y
if not hit_obstacle:
player.position.y += player.speed * delta
player.speed += G * delta
player.can_jump = False
else:
player.can_jump = True
def update_camera_center(
camera, player, env_items, delta, width, height
):
camera.offset = pyray.Vector2(width / 2, height / 2)
camera.target = player.position
def update_camera_center_inside_map(
camera, player, env_items, delta, width, height
):
camera.target = player.position
camera.offset = pyray.Vector2(width / 2, height / 2)
minX = 1000
minY = 1000
maxX = -1000
maxY = -1000
for ei in env_items:
minX = min(ei.rect.x, minX)
maxX = max(ei.rect.x + ei.rect.width, maxX)
minY = min(ei.rect.y, minY)
maxY = max(ei.rect.y + ei.rect.height, maxY)
wmax = pyray.get_world_to_screen_2d(pyray.Vector2(maxX, maxY), camera)
wmin = pyray.get_world_to_screen_2d(pyray.Vector2(minX, minY), camera)
if wmax.x < width:
camera.offset.x = width - (wmax.x - width / 2)
if wmax.y < height:
camera.offset.y = height - (wmax.y - height / 2)
if wmin.x > 0:
camera.offset.x = width / 2 - wmin.x
if wmin.y > 0:
camera.offset.y = height / 2 - wmin.y
def update_camera_center_smooth_follow(
camera, player, env_items, delta, width, height
):
min_speed = 30
min_effect_length = 10
fraction_speed = 0.8
camera.offset = pyray.Vector2(width / 2, height / 2)
diff = vector2_subtract(player.position, camera.target)
length = vector2_length(diff)
if length > min_effect_length:
speed = max(fraction_speed * length, min_speed)
camera.target = vector2_add(
camera.target, vector2_scale(diff, speed * delta / length)
)
def update_camera_even_out_on_landing(
camera, player, env_items, delta, width, height
):
global g_evening_out, g_even_out_target
even_out_speed = 700
camera.offset = pyray.Vector2(width / 2, height / 2)
camera.target.x = player.position.x
if g_evening_out:
if g_even_out_target > camera.target.y:
camera.target.y += even_out_speed * delta
if camera.target.y > g_even_out_target:
camera.target.y = g_even_out_target
g_evening_out = False
else:
camera.target.y -= even_out_speed * delta
if camera.target.y < g_even_out_target:
camera.target.y = g_even_out_target
g_evening_out = False
else:
if (
player.can_jump and
(player.speed == 0) and
(player.position.y != camera.target.y)
):
g_evening_out = True
g_even_out_target = player.position.y
def update_camera_player_bounds_push(
camera, player, env_items, delta, width, height
):
bbox = pyray.Vector2(0.2, 0.2)
bbox_world_min = pyray.get_world_to_screen_2d(
pyray.Vector2((1 - bbox.x) * 0.5 * width,
(1 - bbox.y) * 0.5 * height),
camera
)
bbox_world_max = pyray.get_world_to_screen_2d(
pyray.Vector2((1 + bbox.x) * 0.5 * width,
(1 + bbox.y) * 0.5 * height),
camera
)
camera.offset = pyray.Vector2((1 - bbox.x) * 0.5 * width,
(1 - bbox.y) * 0.5 * height)
if player.position.x < bbox_world_min.x:
camera.target.x = player.position.x
if player.position.y < bbox_world_min.y:
camera.target.y = player.position.y
if player.position.x > bbox_world_max.x:
camera.target.x = (
bbox_world_min.x + (player.position.x - bbox_world_max.x)
)
if player.position.y > bbox_world_max.y:
camera.target.y = (
bbox_world_min.y + (player.position.y - bbox_world_max.y)
)
# Main intialization
player = Player(pyray.Vector2(400, 280), 0, False)
env_items = (
EnvItem(pyray.Rectangle(0, 0, 1000, 400), 0, LIGHTGRAY),
EnvItem(pyray.Rectangle(0, 400, 1000, 200), 1, GRAY),
EnvItem(pyray.Rectangle(300, 200, 400, 10), 1, GRAY),
EnvItem(pyray.Rectangle(250, 300, 100, 10), 1, GRAY),
EnvItem(pyray.Rectangle(650, 300, 100, 10), 1, GRAY),
)
camera = pyray.Camera2D()
camera.target = player.position
camera.offset = pyray.Vector2(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)
camera.rotation = 0.0
camera.zoom = 1.0
pyray.set_target_fps(60) # Set our game to run at 60 frames-per-second
# Store pointers to the multiple update camera functions
camera_updaters = (
update_camera_center,
update_camera_center_inside_map,
update_camera_center_smooth_follow,
update_camera_even_out_on_landing,
update_camera_player_bounds_push,
)
camera_option = 0
camera_updaters_length = len(camera_updaters)
camera_descriptions = (
'Follow player center',
'Follow player center, but clamp to map edges',
'Follow player center smoothed',
('Follow player center horizontally '
'update player center vertically after landing'),
'Player push camera on getting too close to screen edge',
)
# Main game loop
while not pyray.window_should_close(): # Detect window close button or ESC key
# Update
delta_time = pyray.get_frame_time()
update_player(player, env_items, delta_time)
camera.zoom += pyray.get_mouse_wheel_move() * 0.05
if camera.zoom > 3.0:
camera.zoom = 3.0
elif camera.zoom < 0.25:
camera.zoom = 0.25
if pyray.is_key_pressed(pyray.KEY_R):
camera.zoom = 1.0
player.position = pyray.Vector2(400, 280)
if pyray.is_key_pressed(pyray.KEY_C):
camera_option = (camera_option + 1) % camera_updaters_length
# Call update camera function by its pointer
camera_updaters[camera_option](
camera, player, env_items, delta_time,
SCREEN_WIDTH, SCREEN_HEIGHT
)
# Draw
pyray.begin_drawing()
pyray.clear_background(LIGHTGRAY)
pyray.begin_mode_2d(camera)
for env_item in env_items:
pyray.draw_rectangle_rec(env_item.rect, env_item.color)
player_rect = pyray.Rectangle(
int(player.position.x) - 20,
int(player.position.y) - 40,
40, 40
)
pyray.draw_rectangle_rec(player_rect, RED)
pyray.end_mode_2d()
pyray.draw_text('Controls:', 20, 20, 10, BLACK)
pyray.draw_text('- Right/Left to move', 40, 40, 10, DARKGRAY)
pyray.draw_text('- Space to jump', 40, 60, 10, DARKGRAY)
pyray.draw_text('- Mouse Wheel to Zoom in-out, R to reset zoom',
40, 80, 10, DARKGRAY)
pyray.draw_text('- C to change camera mode', 40, 100, 10, DARKGRAY)
pyray.draw_text('Current camera mode:', 20, 120, 10, BLACK)
pyray.draw_text(camera_descriptions[camera_option], 40, 140, 10, DARKGRAY)
pyray.end_drawing()
# De-Initialization
pyray.close_window() # Close window and OpenGL context

View file

@ -3,7 +3,7 @@
raylib [core] example - Input Gestures Detection
"""
from raylib.pyray import PyRay, makeStructHelper
from raylib.pyray import PyRay
from raylib.colors import (
RAYWHITE,
LIGHTGRAY,
@ -73,15 +73,11 @@ while not pyray.window_should_close(): # Detect window close button or ESC key
pyray.draw_rectangle_rec(touch_area, GRAY)
pyray.draw_rectangle(225, 15, SCREEN_WIDTH - 240, SCREEN_HEIGHT - 30,
RAYWHITE)
pyray.draw_text(
'GESTURES TEST AREA',
SCREEN_WIDTH - 270, SCREEN_HEIGHT - 40, 20, pyray.fade(GRAY, 0.5)
)
pyray.draw_rectangle(10, 29, 200, SCREEN_HEIGHT - 50, GRAY)
pyray.draw_text('DETECTED GESTURES', 50, 15, 10, GRAY)
for i, val in enumerate(gesture_strings):
if i % 2 == 0:
pyray.draw_rectangle(
@ -95,11 +91,12 @@ while not pyray.window_should_close(): # Detect window close button or ESC key
else:
pyray.draw_text(val, 35, 36 + 20 * i, 10, MAROON)
pyray.draw_rectangle_lines(10, 29, 200, SCREEN_HEIGHT - 50, GRAY)
pyray.draw_text('DETECTED GESTURES', 50, 15, 10, GRAY)
if current_gesture != pyray.GESTURE_NONE:
pyray.draw_circle_v(touch_position, 30, MAROON)
pyray.end_drawing()

View file

@ -28,10 +28,14 @@ pyray.set_target_fps(60) # Set our game to run at 60 frames-per-second
# Main game loop
while not pyray.window_should_close(): # Detect window close button or ESC key
# Update
if pyray.is_key_down(pyray.KEY_RIGHT): ball_position.x += 2
if pyray.is_key_down(pyray.KEY_LEFT): ball_position.x -= 2
if pyray.is_key_down(pyray.KEY_UP): ball_position.y -= 2
if pyray.is_key_down(pyray.KEY_DOWN): ball_position.y += 2
if pyray.is_key_down(pyray.KEY_RIGHT):
ball_position.x += 2
if pyray.is_key_down(pyray.KEY_LEFT):
ball_position.x -= 2
if pyray.is_key_down(pyray.KEY_UP):
ball_position.y -= 2
if pyray.is_key_down(pyray.KEY_DOWN):
ball_position.y += 2
# Draw
pyray.begin_drawing()