Ver Mensaje Individual
  #7 (permalink)  
Antiguo 22/01/2009, 21:41
Meithan
 
Fecha de Ingreso: enero-2009
Mensajes: 2
Antigüedad: 15 años, 3 meses
Puntos: 2
Respuesta: Tiro parabolico con pygame

Aqui posteo el codigo medio terminado. Ya tiene forma de jueguito. A ver que les parece.

Código python:
Ver original
  1. # ################ #
  2. #   ballistix.py   #
  3. # ################ #
  4. # by Meithan West  #
  5. # 22 / Jan / 2009  #
  6. # ################ #
  7.  
  8. # Game instructions:
  9. # Shoot the squares that appear on the screen
  10. # LEFT/RIGHT: change turrent angle
  11. # UP/DOWN: increase/decrease power
  12. # SPACE: fire!
  13. # ESCAPE: quit
  14.  
  15. # If the game runs too slow/fast, tweak the variable 'speed'
  16. # in the 'Settings' section below
  17.  
  18. from __future__ import division
  19. from math import *
  20. import pygame
  21. import random
  22. pygame.init()
  23.  
  24. # Definitions
  25. black = (0, 0, 0)
  26. white = (255, 255, 255)
  27. blue = (0, 0, 255)
  28. green = (0, 255, 0)
  29. red = (255, 0, 0)
  30. yellow = (255, 255, 0)
  31. purple = (255, 0, 255)
  32. pi = 3.14159
  33. g = 9.8
  34.  
  35. # Settings
  36. width = 800
  37. height = 550
  38. bgcolor = blue
  39. speed = 1000
  40.  
  41. # ###################### #
  42. # Cannon class definition #
  43. # ###################### #
  44. class Cannon:
  45.  
  46.   # Constructor
  47.   def __init__(self, surface):
  48.     self.surface = surface
  49.     self.x = 15
  50.     self.y = 65
  51.     self.alpha = 30
  52.     self.size = 30
  53.     self.power = 70
  54.     self.fired = False
  55.     self.score = 0
  56.     self.shots = 0
  57.     self.charge = 1000
  58.     self.draw(1)
  59.  
  60.   # Cannon shoots
  61.   def shoot(self):
  62.     self.fired = True
  63.     self.shots += 1
  64.     self.charge = 0
  65.  
  66.   # Keyboard input handler
  67.   def key_event(self,event):
  68.     if event.key == pygame.K_LEFT:
  69.       if self.alpha < 90:
  70.         self.draw(0)
  71.         self.alpha += 1
  72.         self.draw(1)
  73.     elif event.key == pygame.K_RIGHT:
  74.       if self.alpha > 0:
  75.         self.draw(0)
  76.         self.alpha -= 1
  77.         self.draw(1)
  78.     elif event.key == pygame.K_DOWN:
  79.       if self.power > 40:
  80.         self.power -= 1
  81.     elif event.key == pygame.K_UP:
  82.       if self.power < 120:
  83.         self.power += 1
  84.  
  85.   # Drawing function"
  86.   def draw(self,mode):
  87.     size = self.size
  88.     # base
  89.     x1 = scrx(self.x-size/2)
  90.     y1 = scry(self.y+size/2)
  91.     x2 = scrx(self.x-size/2)
  92.     y2 = scry(self.y)
  93.     if mode == 0: color = bgcolor
  94.     else: color = white
  95.     pygame.draw.arc(self.surface, color, (x1,y1,size,size),0,3.2,1)
  96.     pygame.draw.rect(self.surface, color, (x2,y2,size+1,size/2),1)
  97.     # barrel
  98.     x1 = scrx(self.x)
  99.     y1 = scry(self.y)
  100.     x2 = scrx(self.x + size*cos(self.alpha*pi/180))
  101.     y2 = scry(self.y + size*sin(self.alpha*pi/180))
  102.     if mode == 0: color = bgcolor
  103.     else: color = yellow
  104.     pygame.draw.line(self.surface, color, (x1,y1),(x2,y2),1)
  105.  
  106. # ###################### #
  107. # Shell class definition #
  108. # ###################### #
  109. class Shell:
  110.  
  111.   # Constructor
  112.   def __init__(self,surface,alpha,power):
  113.     self.surface = surface
  114.     self.size = 3
  115.     # kinematics
  116.     self.x0 = cannon.x + cannon.size*cos(alpha*pi/180)*1.1
  117.     self.y0 = cannon.y + cannon.size*sin(alpha*pi/180)*1.1
  118.     self.vx0 = power*cos(alpha*pi/180)
  119.     self.vy0 = power*sin(alpha*pi/180)
  120.     self.t0 = t
  121.     self.x = self.x0
  122.     self.y = self.y0
  123.     self.vx = self.vx0
  124.     self.vy = self.vy0
  125.  
  126.   # Function to move the shell
  127.   # Uses exact solutions to the kinematic equations
  128.   def move(self):
  129.     self.undraw()
  130.     self.x = self.x0 + self.vx0*(t-self.t0)
  131.     self.y = self.y0 + self.vy0*(t-self.t0) - g/2*(t-self.t0)**2
  132.     self.vx = self.vx0
  133.     self.vy = self.vy0 - g*(t-self.t0)
  134.     if not self.destroyed(): self.draw()
  135.  
  136.   # Check if shell is out of the playing area
  137.   def destroyed(self):
  138.     sx = self.x
  139.     sy = height-self.y
  140.     if sx > width or sy > height-55-self.size:
  141.       return True
  142.     else:
  143.       return False
  144.  
  145.   # Drawing function
  146.   def draw(self):
  147.     # shell
  148.     sx = scrx(self.x)
  149.     sy = scry(self.y)
  150.     pygame.draw.circle(self.surface,red,(sx,sy),self.size,0)
  151.     # trail
  152.     alpha = atan(self.vy/self.vx)
  153.     cosa = cos(alpha)
  154.     sina = sin(alpha)
  155.     sx = scrx(self.x-self.size*cosa*1.3)
  156.     sy = scry(self.y-self.size*sina*1.3)
  157.     self.surface.set_at((sx,sy),red)
  158.  
  159.   # Erasing function
  160.   def undraw(self):
  161.     sx = scrx(self.x)
  162.     sy = scry(self.y)
  163.     pygame.draw.circle(self.surface,bgcolor,(sx,sy),self.size,0)
  164.  
  165.   # Utility function to return the shell position
  166.   def pos(self):
  167.     return self.x, self.y
  168.  
  169. # ####################### #
  170. # Target class definition #
  171. # ####################### #
  172.  
  173. class Target:
  174.  
  175.   # Constructor
  176.   def __init__(self,surface):
  177.     self.x = random.randint(50, width-10)
  178.     self.y = random.randint(10, height-50)
  179.     self.size = 10
  180.     self.surface = surface
  181.     self.draw()
  182.    
  183.   # Drawing function
  184.   def draw(self):
  185.     sx = scrx(self.x)
  186.     sy = scry(self.y)
  187.     pygame.draw.rect(self.surface,yellow,(sx,sy,self.size,self.size),0)
  188.  
  189.   # Erasing function
  190.   def undraw(self):
  191.     sx = scrx(self.x)
  192.     sy = scry(self.y)
  193.     pygame.draw.rect(self.surface,bgcolor,(sx,sy,self.size,self.size),0)
  194.  
  195.   # Checks if the target was hit by a shell
  196.   def hit(self,(x,y),rad):
  197.     if x > (self.x-rad) and \
  198.        x < (self.x+self.size+rad) and \
  199.        y > (self.y-self.size-rad) and \
  200.        y < (self.y+rad):
  201.       return True
  202.     else: return False
  203.  
  204. # ###################### #
  205. # Miscelaneous functions #
  206. # ###################### #
  207.  
  208. # Draws the scoring board
  209. def drawboard():
  210.   pygame.draw.rect(screen,bgcolor,(0,height-49,width,49),0)
  211.   printos(screen, "Power = " + str(cannon.power), 2, height-40, white, font)
  212.   printos(screen, "Angle = " + str(cannon.alpha), 2, height-20, white, font)
  213.   printos(screen, "Score = " + str(cannon.score), width/2-20, height-40, white, font)
  214.   printos(screen, "Score = " + str(cannon.score), width/2-20, height-40, white, font)
  215.   if cannon.shots == 0:
  216.     printos(screen, "Accuracy = 0%", width/2-20, height-20, white, font)
  217.   else:
  218.     printos(screen, "Accuracy = " + str(int(cannon.score/cannon.shots*100)) + "%", width/2-20, height-20, white, font)
  219.   # Reload indicator
  220.   if cannon.charge == 1000:
  221.     printos(screen, "Cannon: ", 100, height-40, white, font)
  222.     printos(screen, "Ready", 160, height-40, green, font)
  223.     pygame.draw.rect(screen,white,(100,height-21,100,10),1)
  224.     pygame.draw.rect(screen,green,(101,height-20,cannon.charge/10-2,8),0)
  225.   else:
  226.     printos(screen, "Cannon: ", 100, height-40, white, font)
  227.     printos(screen, "Reloading", 160, height-40, red, font)
  228.     pygame.draw.rect(screen,white,(100,height-21,100,10),1)
  229.     pygame.draw.rect(screen,red,(101,height-20,cannon.charge/10-2,8),0)
  230.  
  231. # Functions to convert game coordinates to screen coordinates
  232. def scrx(x):
  233.   return int(x)
  234. def scry(y):
  235.   return int(height-y)
  236.  
  237. # Generic screen printing function
  238. def printos(surface, text, x, y, color, font):
  239.   new = font.render(text, 1, color)
  240.   surface.blit(new, (x, y))
  241.  
  242. # ################## #
  243. # Main program start #
  244. # ################## #
  245.  
  246. # Initialization
  247. screen = pygame.display.set_mode((width,height))
  248. clock = pygame.time.Clock()
  249. pygame.key.set_repeat(25)
  250. pygame.font.init()
  251. font = pygame.font.Font(None, 20)
  252. screen.fill(bgcolor)
  253. pygame.draw.line(screen, white, (0,height-50),(width,height-50), 1)
  254. t=0
  255. cannon = Cannon(screen)
  256. target = Target(screen)
  257. shell_list = []
  258. drawboard()
  259. running = True
  260.  
  261. # Main game loop
  262. while running:
  263.  
  264.   # Event handler
  265.   for event in pygame.event.get():
  266.     if event.type == pygame.QUIT:
  267.       print "Thanks for playing!"
  268.       running = False
  269.     # Keyboard input
  270.     elif event.type == pygame.KEYDOWN:
  271.       # ESCAPE exits the game
  272.       if event.key == pygame.K_ESCAPE:
  273.         print "Thanks for playing!"
  274.         running = False
  275.       # SPACE shoots
  276.       elif event.key == pygame.K_SPACE:
  277.         if cannon.charge == 1000:
  278.           cannon.shoot()
  279.           shell_list.append(Shell(screen,cannon.alpha,cannon.power))
  280.       # All other key events are handled by the Cannon class
  281.       else:
  282.         cannon.key_event(event)
  283.  
  284.   # For each shell
  285.   if len(shell_list) > 0:
  286.     for index,shell in enumerate(shell_list):
  287.       shell.move()
  288.       if shell.destroyed():
  289.         shell_list.pop(index)
  290.       if target.hit(shell.pos(),shell.size):
  291.         cannon.score += 1
  292.         shell.undraw()
  293.         shell_list.pop(index)
  294.         target.undraw()
  295.         target = Target(screen)
  296.  
  297.   # Recharge cannon
  298.   if cannon.charge < 1000: cannon.charge+=2
  299.  
  300.   # Draw frame
  301.   drawboard()
  302.   pygame.display.flip()
  303.  
  304.   # Update time
  305.   t += 0.01
  306.   clock.tick(speed)