Las imágenes que se utilizan son las siguientes. Para descargarlas: botón derecho del ratón y a "guardar imagen como..." en la misma carpeta que esté el código. Son libres (de copia, modificación y distribución), siendo yo el creador.


Las imágenes tiene la característica de que donde estaría el eje de rotación se sitúa en el centro de la imagen.
- Código: Seleccionar todo
# -*- coding: utf-8 -*-
#
# Autor: David Ramírez
# Licencia: GPL 3
import pygame
from pygame import *
from math import *
resolucion = (500, 300)
color = (255, 240, 220)
class Antiaereo ( sprite.Sprite):
def __init__(self, centro):
#El antiaéreo se compone por un cañón que gira sobre el eje de una base
sprite.Sprite.__init__(self)
# Se crea la imagen de la base y su rectángulo
self.img_base = pygame.image.load("base.png").convert()
color_transparente = self.img_base.get_at((0,0))
self.img_base.set_colorkey(color_transparente)
self.rect_base = self.img_base.get_rect()
# Se crea la imagen del cañón y su rectángulo
self.img_canyon = pygame.image.load("cañon.png").convert()
color_transparente = self.img_canyon.get_at((0, 0))
self.img_canyon.set_colorkey(color_transparente)
self.rect_canyon = self.img_canyon.get_rect()
# Se crea la imagen del antiaéreo, su rectángulo y se sitúa
self.image = Surface((self.rect_canyon.width, self.rect_canyon.height)).convert()
self.image.set_colorkey((255,0,255))
self.rect = self.image.get_rect()
self.rect.center = centro
self.centro = float(centro[0]), float(centro[1])
def update(self, pos_rat):
# Se borra la imagen del antiaéreo y se dibuja, sobre ella, el cañón
# girado y la base. Coincidiendo los 3 centros de las superficies en
# la coordenada "centro"
self.image.fill((255,0,255))
self.canyon_g = self.mover_canyon(self.img_canyon, pos_rat)
self.rect_canyon = self.canyon_g.get_rect()
self.image.blit(self.img_base, ((self.rect.width / 2) - (self.rect_base.width / 2),
(self.rect.height / 2) - (self.rect_base.height / 2)))
self.image.blit(self.canyon_g, ((self.rect.width / 2) - (self.rect_canyon.width / 2),
(self.rect.height / 2) - (self.rect_canyon.height / 2)))
def mover_canyon(self, img_canyon, pos_rat):
# Se devuelve la superficie del cañón girado, dependiendo de la
# posición del ratón.
# Para ello, hace falta saber el angulo exacto del centro a la posición
# del ratón. Teniendo en cuenta que tan(ángulo) == tan(ángulo + pi).
if (pos_rat[0] - self.centro[0]) == 0:
if pos_rat[1] > self.centro[1]:
a = pi / 2
else:
a = -pi / 2
else:
if pos_rat[0] > self.centro[0]:
a = atan((self.centro[1] - pos_rat[1]) / (self.centro[0] - pos_rat[0]))
else:
a = pi + atan((self.centro[1] - pos_rat[1]) / (self.centro[0] - pos_rat[0]))
canyon_girado = transform.rotate(img_canyon, degrees(-a))
return canyon_girado
def main():
# Se crea la pantalla con la resolución determinada
screen = pygame.display.set_mode(resolucion)
# Se crea el conjunto de artillería y se añaden varios antiaéreos
# en distintas posiciones.
artilleria = pygame.sprite.Group()
for a in range(1, 9):
artilleria.add(Antiaereo(( -15 + a * 60, 60 + sin(a) * 40)))
while True:
for event in pygame.event.get():
if event.type == QUIT:
# Finaliza el programa si hay un evento de cerrar
return
screen.fill(color) # Se pinta la pantalla
pos = mouse.get_pos() # Se obtiene la posición del ratón
artilleria.update(pos) # Se actualizan la artillería dependiendo de "pos"
artilleria.draw(screen) # Se dibuja la artillería
display.update() # Se actualiza la pantalla
if __name__ == '__main__':
main()
Espero que disfrutéis con él. Lo siento si hay algún error, no he podido dedicarle mucho tiempo. En caso de ver alguno, agradecería un aviso para que lo pueda rectificar.
Saludos.