Download Documentation API Reference Samples Asset Store Donate


Pong
https://github.com/pokepetter/ursina/blob/master/samples/pong.py


from ursina import * app = Ursina() window.color = color.black camera.orthographic = True camera.fov = 1 left_paddle = Entity(scale=(1/32,6/32), x=-.75, model='quad', origin_x=.5, collider='box') right_paddle = duplicate(left_paddle, x=left_paddle.x*-1, rotation_z=left_paddle.rotation_z+180) floor = Entity(model='quad', y=-.5, origin_y=.5, collider='box', scale=(2,10), visible=False) ceiling = duplicate(floor, y=.5, rotation_z=180, visible=False) left_wall = duplicate(floor, x=-.5*window.aspect_ratio, rotation_z=90, visible=True) right_wall = duplicate(floor, x=.5*window.aspect_ratio, rotation_z=-90, visible=True) # Score variables left_score = 0 right_score = 0 max_score = 5 game_paused = False # Added variable to track the game's paused state collision_cooldown = .15 ball = Entity(model='circle', scale=.05, collider='box', speed=0, collision_cooldown=collision_cooldown) # Score text score_text = Text(text=f"{left_score} : {right_score}", position=(0, .45), scale=2, origin=(0, 0)) def update(): global left_score, right_score, game_paused if game_paused: return # Stop all updates if the game is paused ball.collision_cooldown -= time.dt ball.position += ball.right * time.dt * ball.speed left_paddle.y += (held_keys['w'] - held_keys['s']) * time.dt * 1 right_paddle.y += (held_keys['up arrow'] - held_keys['down arrow']) * time.dt * 1 if ball.collision_cooldown > 0: return hit_info = ball.intersects() if hit_info.hit: ball.collision_cooldown = collision_cooldown if hit_info.entity in (left_paddle, right_paddle): ball.rotation_z += 180 * (-1 if hit_info.entity == left_paddle else 1) ball.rotation_z -= (hit_info.entity.world_y - ball.y) * 20 * 32 * (-1 if hit_info.entity == left_paddle else 1) ball.speed *= 1.1 elif hit_info.entity == right_wall: left_score += 1 update_score() elif hit_info.entity == left_wall: right_score += 1 update_score() # Particle effect on collision particle = Entity(model='quad', position=hit_info.world_point, scale=0, texture='circle', add_to_scene_entities=False) particle.animate_scale(.2, .5, curve=curve.out_expo) particle.animate_color(color.clear, duration=.5, curve=curve.out_expo) destroy(particle, delay=.5) # Ball bounces off top and bottom of the screen if ball.y > ceiling.y - ball.scale_y/2 or ball.y < floor.y + ball.scale_y/2: ball.rotation_z = -ball.rotation_z # Reverse vertical direction def update_score(): global left_score, right_score, game_paused score_text.text = f"{left_score} : {right_score}" if left_score >= max_score or right_score >= max_score: winner_text = Text(f"{'Left' if left_score >= max_score else 'Right'} Player Wins!", y=0, scale=2, origin=(0, 0)) ball.speed = 0 game_paused = True # Pause the game after a win invoke(destroy, winner_text, delay=3) else: reset() def reset(): ball.position = (0, 0, 0) ball.rotation = (0, 0, 0) ball.speed = 10 for paddle in (left_paddle, right_paddle): paddle.collision = True paddle.y = 0 info_text = Text("press space to play", y=-.45) def input(key): global game_paused if key == 'space' and not game_paused: # Prevent restarting when the game is paused info_text.enabled = False reset() app.run()