Skip to content

Commit

Permalink
Merge pull request #717 from SuperZekes/master
Browse files Browse the repository at this point in the history
Add scoring to the pong sample
  • Loading branch information
pokepetter committed Sep 18, 2024
2 parents c0f14b1 + 4bf684a commit 0208cb9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 66 deletions.
76 changes: 43 additions & 33 deletions samples/pong.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from ursina import *


app = Ursina()

window.color = color.black
Expand All @@ -15,76 +14,87 @@
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:
# after a collision, wait a little while before another collision can occur.
# this is to prevent the ball from colliding multiple times with the same wall because
# it hasn't got time to be moved away from it yet.
return

hit_info = ball.intersects()
if hit_info.hit:
ball.collision_cooldown = collision_cooldown

if hit_info.entity in (left_paddle, right_paddle, left_wall, right_wall):
hit_info.entity.collision = False
invoke(setattr, hit_info.entity, 'collision', False, delay=.1)
direction_multiplier = 1
if hit_info.entity == left_paddle:
direction_multiplier = -1

left_paddle.collision = False # disable collision for the current paddle so it doesn't collide twice in a row
right_paddle.collision = True
else:
right_paddle.collision = False
left_paddle.collision = True

ball.rotation_z += 180 * direction_multiplier
ball.rotation_z -= (hit_info.entity.world_y - ball.y) * 20 * 32 * direction_multiplier
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

else: # hit wall
ball.rotation_z *= -abs(hit_info.world_normal.normalized()[1])
elif hit_info.entity == right_wall:
left_score += 1
update_score()

elif hit_info.entity == left_wall:
right_score += 1
update_score()

# create a particle on collision
# 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.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):
if key == 'space':
global game_paused

if key == 'space' and not game_paused: # Prevent restarting when the game is paused
info_text.enabled = False
reset()

if key == 't':
ball.speed += 5


# TODO: register when the ball exits either side and give points


app.run()
77 changes: 44 additions & 33 deletions samples/pong.py.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
```
from ursina import *


app = Ursina()

window.color = color.black
Expand All @@ -16,77 +15,89 @@ 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:
# after a collision, wait a little while before another collision can occur.
# this is to prevent the ball from colliding multiple times with the same wall because
# it hasn't got time to be moved away from it yet.
return

hit_info = ball.intersects()
if hit_info.hit:
ball.collision_cooldown = collision_cooldown

if hit_info.entity in (left_paddle, right_paddle, left_wall, right_wall):
hit_info.entity.collision = False
invoke(setattr, hit_info.entity, 'collision', False, delay=.1)
direction_multiplier = 1
if hit_info.entity == left_paddle:
direction_multiplier = -1

left_paddle.collision = False # disable collision for the current paddle so it doesn't collide twice in a row
right_paddle.collision = True
else:
right_paddle.collision = False
left_paddle.collision = True

ball.rotation_z += 180 * direction_multiplier
ball.rotation_z -= (hit_info.entity.world_y - ball.y) * 20 * 32 * direction_multiplier
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

else: # hit wall
ball.rotation_z *= -abs(hit_info.world_normal.normalized()[1])
elif hit_info.entity == right_wall:
left_score += 1
update_score()

elif hit_info.entity == left_wall:
right_score += 1
update_score()

# create a particle on collision
# 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.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):
if key == 'space':
global game_paused

if key == 'space' and not game_paused: # Prevent restarting when the game is paused
info_text.enabled = False
reset()

if key == 't':
ball.speed += 5


# TODO: register when the ball exits either side and give points


app.run()

```

0 comments on commit 0208cb9

Please sign in to comment.