<-- Back to list of examples

pong.py
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# --- Importamos las bibliotecas que usaremos en este programa
import math
import pygame
import random
# Definimos algunos colores
NEGRO = (0, 0, 0)
BLANCO = (255, 255, 255)
# Esta clase representa la pelota
# Se deriva de la clase "Sprite" en Pygame
class Pelota(pygame.sprite.Sprite):
# Constructor. Pasa el color y las posiciones x e y de la pelota.
def __init__(self):
# Llamada al constructor de la clase padre (Sprite)
super().__init__()
# Creamos la imagen de la pelota
self.image = pygame.Surface([10, 10])
# Color de la pelota
self.image.fill((BLANCO))
# Obtenemos un objeto rectángulo para mostrar donde se encuentra nuestra imagen
self.rect = self.image.get_rect()
# Obtenemos los atributos para el alto/largo de la pantalla
self.alto_pantalla = pygame.display.get_surface().get_height()
self.largo_pantalla = pygame.display.get_surface().get_width()
# Velocidad en píxeles por ciclo
self.velocidad = 0
# Representación en coma flotante de la ubicación de la pelota
self.x = 0
self.y = 0
# Rumbo de la pelota en grados
self.rumbo = 0
# Altura y largo de la pelota
self.largo = 10
self.alto = 10
# Definimos la posición y velocidad inicial de la pelota
self.reset()
def reset(self):
self.x = random.randrange(50,750)
self.y = 350.0
self.velocidad = 8.0
# Rumbo de la pelota (en grados)
self.rumbo = random.randrange(-45,45)
# Lanzamos una 'moneda'
if random.randrange(2) == 0 :
# Revertimos el rumbo de la pelota y dejamos que le llegue primero a nuestro compañero.
self.rumbo += 180
self.y = 50
# Esta función hará rebotar la pelota sobre una superficie horizontal (no en una vertical)
def botar(self,diff):
self.rumbo = (180-self.rumbo) % 360
self.rumbo -= diff
# Aceleramos la bola hacia arriba
self.velocidad *= 1.1
# Actualizamos la posición de la pelota
def update(self):
# El Seno y el Coseno funcionan en grados, por eso tenemos
# que convertirlos a radianes
rumbo_radianes = math.radians(self.rumbo)
# Modificamos la posición (x e y) en función de la velocidad y el rumbo
self.x += self.velocidad * math.sin(rumbo_radianes)
self.y -= self.velocidad * math.cos(rumbo_radianes)
if self.y < 0:
self.reset()
if self.y > 600:
self.reset()
# Desplazamos la imagen hacia donde se encuentran x e y.
self.rect.x = self.x
self.rect.y = self.y
# ¿Hemos botado contra el lado izquierdo de la pantalla?
if self.x <= 0:
self.rumbo = (360-self.rumbo)%360
print(self.rumbo)
#self.x=1
# ¿Hemos botado contra el lado derecho de la pantalla?
if self.x > self.largo_pantalla-self.largo:
self.rumbo = (360-self.rumbo)%360
# Esta clase representa la barra inferior que controla el protagonista
class Protagonista(pygame.sprite.Sprite):
# Función constructor
def __init__(self, joystick, y_pos):
# Llamada al constructor padre
super().__init__()
self.largo = 75
self.alto = 15
self.image = pygame.Surface([self.largo, self.alto])
self.image.fill((BLANCO))
self.joystick = joystick
# Hacemos que la esquina superior izquierda sea la ubicación inicial.
self.rect = self.image.get_rect()
self.alto_pantalla = pygame.display.get_surface().get_height()
self.largo_pantalla = pygame.display.get_surface().get_width()
self.rect.x = 0
self.rect.y = y_pos
# Actualizamos al protagonista
def update(self):
# Esto obtiene la posición del eje en el mando de juego
# Devuelve un número entre -1.0 y +1.0
horiz_axis_pos = self.joystick.get_axis(0)
# Desplaza x en función del eje. Multiplicamos por 15 para acelerar el movimiento.
self.rect.x = int(self.rect.x+horiz_axis_pos*15)
# Nos aseguramos que no hemos empujado la pala del protagonista fuera del lado derecho de la pantalla.
if self.rect.x > self.largo_pantalla - self.largo:
self.rect.x = self.largo_pantalla - self.largo
puntuacion1 = 0
puntuacion2 = 0
# Iniciamos Pygame
pygame.init()
# Creamos una pantalla de 800x600
pantalla = pygame.display.set_mode([800, 600])
# Establecemos rl título de la ventana
pygame.display.set_caption('Pong')
# Habilitamos esto para que el ratón desaparezca cuando esté encima de nuestra ventana.
pygame.mouse.set_visible(0)
# Fuente para dibujar el texto en pantalla (tamaño 36)
fuente = pygame.font.Font(None, 36)
# Creamos una superficie sobre la que poder dibujar
imagen_de_fondo = pygame.Surface(pantalla.get_size())
# Creamos la pelota
pelota = Pelota()
# Creamos un grupo de 1 pelota (usada para comprobar colisiones)
pelotas = pygame.sprite.Group()
pelotas.add(pelota)
# Cuenta los joysticks conectados al ordenador
joystick_count = pygame.joystick.get_count()
if joystick_count < 1:
# No hay joysticks!
print ("Error, no he podido encontrar suficientes joysticks.")
pygame.quit()
exit()
else:
# Usamos el joystick #0 y lo inicializamos
joystick1 = pygame.joystick.Joystick(0)
joystick1.init()
joystick2 = pygame.joystick.Joystick(1)
joystick2.init()
# Creamos los objetos pala protagonistas
pala1 = Protagonista(joystick1,580)
pala2 = Protagonista(joystick2,25)
desplazar_sprites = pygame.sprite.Group()
desplazar_sprites.add(pala1)
desplazar_sprites.add(pala2)
desplazar_sprites.add(pelota)
reloj = pygame.time.Clock()
hecho = False
salirdel_programa = False
while not salirdel_programa:
reloj.tick(30)
# Limpiamos la pantalla
pantalla.fill(NEGRO)
for evento in pygame.event.get():
if evento.type == pygame.QUIT:
salirdel_programa = True
# Detenemos el juego si hay una diferencia de 3 puntos
if abs(puntuacion1 - puntuacion2) > 3:
hecho = True
if not hecho:
# Actualizamos las posiciones de las palas y la pelota
pala1.update()
pala2.update()
pelota.update()
# Si hemos acabado, mostramos el mensaje 'game over'
if hecho:
texto = fuente.render("Game Over", 1, (200, 200, 200))
textopos = text.get_rect(centerx=imagen_de_fondo.get_width()/2)
textopos.top = 50
pantalla.blit(texto, textopos)
# Observamos si la pelota golpea la pala.
if pygame.sprite.spritecollide(pala1, pelotas, False):
# El 'diff' te permite botar la pelota, a la izquierda o derecha, dependiendo conque parte de la pala la golpeaste.
diff = (pala1.rect.x + pala1.largo/2) - (pelota.rect.x+pelota.largo/2)
# Establecemos la posición y de la pelota en caso la golpeemos con el borde de la pala.
pelota.y = 570
pelota.botar(diff)
puntuacion1 += 1
# Observamos si la pelota golpea la pala.
if pygame.sprite.spritecollide(pala2, pelotas, False):
# El 'diff' te permite botar la pelota, a la izquierda o derecha, dependiendo conque parte de la pala la golpeaste.
diff = (pala2.rect.x + pala2.largo/2) - (pelota.rect.x+pelota.largo/2)
# Establecemos la posición y de la pelota en caso la golpeemos con el borde de la pala.
pelota.y = 40
pelota.botar(diff)
puntuacion2 += 1
# Imprimimos la puntuación
imprimir_puntuacion = "Protagonista 1: " + str(puntuacion1)
texto = fuente.render(imprimir_puntuacion, 1, BLANCO)
textopos = (0,0)
pantalla.blit(texto, textopos)
imprimir_puntuacion = "Protagonista 2: " + str(puntuacion2)
texto = fuente.render(imprimir_puntuacion, 1, BLANCO)
textopos = (300,0)
pantalla.blit(texto, textopos)
#Dibujamos todo
desplazar_sprites.draw(pantalla)
# Actualizamos la pantalla
pygame.display.flip()
reloj.tick(30)
pygame.quit()