1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
from __future__ import division
from math import cos, sin, fabs, pi
from random import randint
from sfml import sf
# define some constants
game_size = sf.Vector2(800, 600)
paddle_size = sf.Vector2(25, 100)
ball_radius = 10.
# create the window of the application
w, h = game_size
window = sf.RenderWindow(sf.VideoMode(w, h), "pySFML - Pong")
window.vertical_synchronization = True
# load the sounds used in the game
ball_sound_buffer = sf.SoundBuffer.from_file("data/ball.wav")
ball_sound = sf.Sound(ball_sound_buffer)
# create the left paddle
left_paddle = sf.RectangleShape()
left_paddle.size = paddle_size - (3, 3)
left_paddle.outline_thickness = 3
left_paddle.outline_color = sf.Color.BLACK
left_paddle.fill_color = sf.Color(100, 100, 200)
left_paddle.origin = paddle_size / 2
# create the right paddle
right_paddle = sf.RectangleShape()
right_paddle.size = paddle_size - (3, 3)
right_paddle.outline_thickness = 3
right_paddle.outline_color = sf.Color.BLACK
right_paddle.fill_color = sf.Color(200, 100, 100)
right_paddle.origin = paddle_size / 2
# create the ball
ball = sf.CircleShape()
ball.radius = ball_radius - 3
ball.outline_thickness = 3
ball.outline_color = sf.Color.BLACK
ball.fill_color = sf.Color.WHITE
ball.origin = (ball_radius / 2, ball_radius / 2)
# load the font
font = sf.Font.from_file("data/sansation.ttf")
# initialize the pause message
pause_message = sf.Text()
pause_message.font = font
pause_message.character_size = 40
pause_message.position = (170, 150)
pause_message.color = sf.Color.WHITE
pause_message.string = "Welcome to pySFML pong!\nPress space to start the game"
# define the paddles properties
ai_timer = sf.Clock()
ai_time = sf.seconds(0.1)
paddle_speed = 400.
right_paddle_speed = 0.
ball_speed = 400.
ball_angle = 0. # to be changed later
clock = sf.Clock()
is_playing = False
while window.is_open:
# handle events
for event in window.events:
# window closed or escape key pressed: exit
if type(event) is sf.CloseEvent:
window.close()
# space key pressed: play
if type(event) is sf.KeyEvent and event.pressed and event.code is sf.Keyboard.SPACE:
if not is_playing:
# (re)start the game
is_playing = True
clock.restart()
# reset the position of the paddles and ball
left_paddle.position = (10 + paddle_size.x / 2, game_size.y / 2)
right_paddle.position = (game_size.x - 10 - paddle_size.x / 2, game_size.y / 2)
ball.position = game_size / 2
# reset the ball angle
while True:
# make sure the ball initial angle is not too much vertical
ball_angle = (randint(0, 32767) % 360) * 2 * pi / 360
if not fabs(cos(ball_angle)) < 0.7: break
if is_playing:
delta_time = clock.restart().seconds
# move the player's paddle
if sf.Keyboard.is_key_pressed(sf.Keyboard.UP) and left_paddle.position.y - paddle_size.y / 2 > 5:
left_paddle.move((0, -paddle_speed * delta_time))
elif sf.Keyboard.is_key_pressed(sf.Keyboard.DOWN) and left_paddle.position.y + paddle_size.y / 2 < game_size.y - 5:
left_paddle.position += (0, paddle_speed * delta_time)
# move the computer' paddle
if (right_paddle_speed < 0 and right_paddle.position.y - paddle_size.x / 2 > 5) or (right_paddle_speed > 0 and right_paddle.position.y + paddle_size.y / 2 < game_size.y - 5):
right_paddle.position += (0, right_paddle_speed * delta_time)
# update the computer's paddle direction according to the ball position
if ai_timer.elapsed_time > ai_time:
ai_timer.restart()
if ball.position.y + ball_radius > right_paddle.position.y + paddle_size.y / 2:
right_paddle_speed = paddle_speed
elif ball.position.y - ball_radius < right_paddle.position.y - paddle_size.y / 2:
right_paddle_speed = - paddle_speed
else:
right_paddle_speed = 0
# move the ball
factor = ball_speed * delta_time
ball.move((cos(ball_angle) * factor, sin(ball_angle) * factor))
# check collisions between the ball and the screen
if ball.position.x - ball_radius < 0:
is_playing = False
pause_message.string = "You lost!\nPress space to restart or\nescape to exit"
if ball.position.x + ball_radius > game_size.x:
is_playing = False
pause_message.string = "You won !\nPress space to restart or\nescape to exit"
if ball.position.y - ball_radius < 0:
ball_sound.play()
ball_angle = - ball_angle
ball.position.y = ball_radius + 0.1
if ball.position.y + ball_radius > game_size.y:
ball_sound.play()
ball_angle = - ball_angle
ball.position.y = game_size.y - ball_radius - 0.1
# check the collisions between the ball and the paddles
# left paddle
if ball.position.x - ball_radius < left_paddle.position.x + paddle_size.x / 2 and ball.position.x - ball_radius > left_paddle.position.x and ball.position.y + ball_radius >= left_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= left_paddle.position.y + paddle_size.y / 2:
if ball.position.y > left_paddle.position.y:
ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
else:
ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180
ball_sound.play()
ball.position = (left_paddle.position.x + ball_radius + paddle_size.x / 2 + 0.1, ball.position.y)
# right paddle
if ball.position.x + ball_radius > right_paddle.position.x - paddle_size.x / 2 and ball.position.x + ball_radius < right_paddle.position.x and ball.position.y + ball_radius >= right_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= right_paddle.position.y + paddle_size.y / 2:
if ball.position.y > right_paddle.position.y:
ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
else:
ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180
ball_sound.play()
ball.position = (right_paddle.position.x - ball_radius - paddle_size.x / 2 - 0.1, ball.position.y)
window.clear(sf.Color(50, 200, 50))
if is_playing:
# draw the paddles and the ball
window.draw(left_paddle)
window.draw(right_paddle)
window.draw(ball)
else:
# draw the pause message
window.draw(pause_message)
# display things on screen
window.display()
|