Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.84 KB | None | 0 0
  1. # Separate this file into modules if the project succeeds
  2.  
  3. import sys
  4. import operator
  5. import math
  6.  
  7. import pygame
  8.  
  9. # Variables
  10. TILE_SIZE = 32
  11. S_SIZE = S_WIDTH,S_HEIGHT = TILE_SIZE*20,TILE_SIZE*12
  12. FPSMAX = 60
  13. CAPTION = 'Dwarf'
  14. BMB_DELAY = 3000 # 3 seconds
  15. BMB_ID = 0
  16.  
  17. # Initialize
  18. pygame.init()
  19.  
  20. pygame.display.set_caption(CAPTION)
  21.  
  22. #   Game entities
  23. screen = pygame.display.set_mode(S_SIZE)
  24. clock = pygame.time.Clock()
  25.  
  26. bombs = []
  27. wastebasket = []
  28.  
  29. #   Images
  30. floor = pygame.image.load('res/sprites/map/floor.jpg').convert()
  31. dwarf = pygame.image.load('res/sprites/player/dwarf.png').convert_alpha()
  32.  
  33. PREFIX_BS = 'res/sprites/bomb/'
  34. bomb_sprite = {
  35.     '''NOMENCLATURE
  36.    Bomb
  37.        The bomb sprite...
  38.    Explosion parts (exp)
  39.        e: end
  40.        m: middle
  41.        v: vertical
  42.            t: top
  43.            b: bottom
  44.        h: horizontal
  45.            l: left
  46.            r: right
  47.    '''
  48.     # There is an unknown reason why not having an item before bomb makes it
  49.     # unusable from the main loop :^S
  50.     'nothing' : None, \
  51.     # Bomb
  52.     'bomb' : pygame.image.load(PREFIX_BS+'bomb.png').convert_alpha(), \
  53.     # Explosions
  54.     'exp_cnt' : pygame.image.load(PREFIX_BS+'exp_cent.png').convert_alpha(), \
  55.     #   Vertical parts
  56.     'exp_vte' : pygame.image.load(PREFIX_BS+'exp_vte.png').convert_alpha(), \
  57.     'exp_vtm' : pygame.image.load(PREFIX_BS+'exp_vtm.png').convert_alpha(), \
  58.     'exp_vbm' : pygame.image.load(PREFIX_BS+'exp_vbm.png').convert_alpha(), \
  59.     'exp_vbe' : pygame.image.load(PREFIX_BS+'exp_vbe.png').convert_alpha(), \
  60.     #   Horizontal parts
  61.     'exp_hle' : pygame.image.load(PREFIX_BS+'exp_hle.png').convert_alpha(), \
  62.     'exp_hlm' : pygame.image.load(PREFIX_BS+'exp_hlm.png').convert_alpha(), \
  63.     'exp_hrm' : pygame.image.load(PREFIX_BS+'exp_hrm.png').convert_alpha(), \
  64.     'exp_hre' : pygame.image.load(PREFIX_BS+'exp_hre.png').convert_alpha()
  65. }
  66.  
  67. # Functions
  68. def coords_round(coords):
  69.     x,y = coords
  70.     x = math.ceil(x/TILE_SIZE)*TILE_SIZE
  71.     y = math.ceil(y/TILE_SIZE)*TILE_SIZE
  72.     return x,y
  73.  
  74. # Classes
  75. class Bomb:
  76.     def __init__(self, pos, planter=None, time=BMB_DELAY):
  77.         # Give bomb a unique id
  78.         global BMB_ID
  79.         BMB_ID += 1
  80.         self.id = BMB_ID
  81.         self.index = None
  82.         self.planter = planter
  83.        
  84.         self.pos = pos
  85.         self.time = time
  86.  
  87.         self.hitbox = pygame.Rect(pos,(TILE_SIZE,TILE_SIZE))
  88.         self.range = 2
  89.         self.aoe = self.upd_aoe()
  90.  
  91.         # Alias
  92.         self.upd_index = self.get_index
  93.         return
  94.  
  95.     def destroy(self):
  96.         self.upd_index()
  97.         wastebasket.append(self)
  98.         print 'appended'
  99.         return
  100.  
  101.     def get_index(self):
  102.         '''Gets the index of the bomb in the list'''
  103.         for bomb in bombs:
  104.             if bomb.id == self.id:
  105.                 self.index = bombs.index(bomb)
  106.         return self.index
  107.  
  108.     def explode(self):
  109.         global bombs
  110.         '''Explodes the bomb and its neighbors.
  111.        It can be optimized because the loop checks various times if several
  112.        bombs collide, as a natural deffect.
  113.        A possible solution would be to set a global master to control all
  114.        this tasks and control the bombs explosions and whatnot.'''
  115.         r = self.range
  116.         # Check for explosion collisions
  117.  
  118.         # Solution to problem below:
  119.         # Find a method to copy a list without letting a link between them
  120.         # exist.
  121.         bombs_others = []
  122.         for bomb in bombs:
  123.             if bomb.id != self.id:
  124.                 bombs_others.append(bomb)
  125.        
  126.         #bombs_others.pop(self.get_index()) <-- error, modifying a list which
  127.         # has been set to another, modifyies the other as well. See solution
  128.         # in the comment above.
  129.         '''
  130.        if len(bombs_others) > 0:
  131.            for bomb in bombs_others:
  132.                if self.aoe[0].colliderect(bomb.hitbox) or \
  133.                        self.aoe[1].colliderect(bomb.hitbox):
  134.                    bomb.explode()
  135.        '''
  136.         for bomb in bombs:
  137.             if bomb.id != self.id:
  138.                 try:
  139.                     print self.aoe[0].colliderect(bomb.hitbox)[0]
  140.                 except:
  141.                     print 'bomb hitbox:',bomb.hitbox.__class__
  142.                     print 'self h aoe:',self.aoe[0].__class__
  143.                     print 'self v aoe:',self.aoe[1].__class__
  144.                     #sys.exit()
  145.                 if self.aoe[0].colliderect(bomb.hitbox) or \
  146.                         self.aoe[1].colliderect(bomb.hitbox):
  147.                     bomb.explode()
  148.        
  149.         if self.aoe[0].colliderect(dwarfo.hitbox) or \
  150.                 self.aoe[1].colliderect(dwarfo.hitbox):
  151.             print 'Ouch!'
  152.  
  153.         # Draw explosion waves
  154.         self.draw_exp()
  155.        
  156.         pygame.time.wait(100)
  157.        
  158.         return
  159.  
  160.     def upd_aoe(self):
  161.         '''Updates the area of effect of a bomb when its created and whenever its
  162.        range changes'''
  163.         r = self.range
  164.         expansion = 2*r*TILE_SIZE
  165.        
  166.         hor = self.hitbox.inflate(expansion,0)
  167.         vrt = self.hitbox.inflate(0,expansion)
  168.         self.aoe = hor,vrt
  169.        
  170.         return self.aoe
  171.  
  172.     def draw(self):
  173.         global bomb_sprite
  174.         screen.blit(bomb_sprite['bomb'], self.pos)
  175.         return
  176.  
  177.     def draw_exp(self):
  178.         global bomb_sprite
  179.  
  180.         # Draw explosion center
  181.         screen.blit(bomb_sprite['exp_cnt'], self.pos)
  182.  
  183.         # Draw end explosion waves
  184.         screen.blit(bomb_sprite['exp_hle'], \
  185.                     (self.pos[0]-self.range*TILE_SIZE, self.pos[1]))
  186.         screen.blit(bomb_sprite['exp_hre'], \
  187.                     (self.pos[0]+self.range*TILE_SIZE, self.pos[1]))
  188.  
  189.         screen.blit(bomb_sprite['exp_vte'], \
  190.                     (self.pos[0], self.pos[1]-self.range*TILE_SIZE))
  191.         screen.blit(bomb_sprite['exp_vbe'], \
  192.                     (self.pos[0], self.pos[1]+self.range*TILE_SIZE))
  193.  
  194.         # Draw middle explosion waves
  195.         if self.range > 1:
  196.             for i in range(self.range)[1:]:
  197.                 screen.blit(bomb_sprite['exp_vtm'], \
  198.                             (self.pos[0], self.pos[1]-i*TILE_SIZE))
  199.                 screen.blit(bomb_sprite['exp_vbm'], \
  200.                             (self.pos[0], self.pos[1]+i*TILE_SIZE))
  201.  
  202.                 screen.blit(bomb_sprite['exp_hlm'], \
  203.                             (self.pos[0]-i*TILE_SIZE,self.pos[1]))
  204.                 screen.blit(bomb_sprite['exp_hrm'], \
  205.                             (self.pos[0]+i*TILE_SIZE,self.pos[1]))
  206.  
  207.         # Update the modified tiles
  208.         pygame.display.update(self.aoe)
  209.  
  210.         return
  211.  
  212.  
  213. class Player:
  214.     def __init__(self, pos, sprite=dwarf):
  215.         self.pos = [pos[0], pos[1]]
  216.         self.hitbox = pygame.Rect(self.pos, (TILE_SIZE,TILE_SIZE))
  217.  
  218.         self.step_factor = 1 # Multiplied by TILE_SIZE
  219.         self.step_size = self.get_stepsize()
  220.  
  221.         self.sprite = sprite
  222.  
  223.         self.bombs = [] # for kill credit
  224.         # Alias
  225.         self.get_hitbox = self.upd_hitbox
  226.  
  227.     def upd_hitbox(self):
  228.         self.hitbox = pygame.Rect( self.pos, (TILE_SIZE, TILE_SIZE) )
  229.         return self.hitbox
  230.  
  231.     def get_stepsize(self):
  232.         self.step_size = self.step_factor*TILE_SIZE
  233.         return self.step_size
  234.  
  235.     def listen(self, key):
  236.         # Movement
  237.         if key == pygame.K_UP:
  238.             self.move_up()
  239.         elif key == pygame.K_DOWN:
  240.             self.move_down()
  241.         elif key == pygame.K_LEFT:
  242.             self.move_left()
  243.         elif key == pygame.K_RIGHT:
  244.             self.move_right()
  245.         # Actions
  246.         elif key == pygame.K_SPACE:
  247.             self.bomb()
  248.    
  249.     def move_up(self):
  250.         self.pos[1] -= self.step_size
  251.         self.upd_hitbox()
  252.         return
  253.  
  254.     def move_down(self):
  255.         self.pos[1] += self.step_size
  256.         self.upd_hitbox()
  257.         return
  258.        
  259.     def move_left(self):
  260.         self.pos[0] -= self.step_size
  261.         self.upd_hitbox()
  262.         return
  263.  
  264.     def move_right(self):
  265.         self.pos[0] += self.step_size
  266.         self.upd_hitbox()
  267.         return
  268.  
  269.     def bomb(self):
  270.         pos = coords_round((self.hitbox.centerx, \
  271.                             self.hitbox.centery))
  272.         # Create bomb
  273.         newbomb = Bomb(pos, self)
  274.         # Check if space is available for bombs, via hitbox collision
  275.         placebomb = True
  276.         for bomb in bombs:
  277.             if newbomb.hitbox == bomb.hitbox:
  278.                 placebomb = False
  279.         # Decide bomb placement accordingly
  280.         if placebomb:
  281.             self.bombs.append(newbomb)
  282.             bombs.append(newbomb)
  283.             self.upd_bombs()
  284.             print 'bomb planted!!!',len(self.bombs),'total :)'
  285.         return
  286.  
  287.     def upd_bombs(self):
  288.         for bomb in self.bombs:
  289.             if bomb not in bombs:
  290.                 self.bombs.remove(bomb)
  291.         return
  292.                    
  293.     def draw(self):
  294.         screen.blit(self.sprite, self.pos)
  295.         return
  296.  
  297. # Tests
  298. #print range(S_WIDTH/10 + 1)
  299. dwarfo = Player((S_WIDTH/2, S_HEIGHT/2))
  300.  
  301. while 1:
  302.     putbomb = 0
  303.     # Set framerate
  304.     tick = clock.tick(FPSMAX)
  305.     #print 'tick'
  306.  
  307.     # Read events
  308.     for event in pygame.event.get():
  309.        
  310.         if event.type == pygame.QUIT:
  311.             pygame.quit()
  312.             sys.exit()
  313.         elif event.type == pygame.MOUSEBUTTONDOWN:
  314.             putbomb = 1
  315.         elif event.type == pygame.KEYDOWN:
  316.             dwarfo.listen(event.key)
  317.             if event.key == pygame.K_c:
  318.                 print pygame.mouse.get_pos()
  319.  
  320.     # Put bomb
  321.     if putbomb:
  322.         pos = coords_round( pygame.mouse.get_pos() )
  323.         bombs.append( Bomb(pos) )
  324.         #bombs.sort( key=operator.itemgetter(1) ) # Sorts the bombs according to y coordinate before blit
  325.  
  326.     # Put floor (make into function later)
  327.     for w in range(S_WIDTH/10):
  328.         for h in range(S_HEIGHT/10):
  329.             screen.blit(floor,(w*TILE_SIZE,h*TILE_SIZE))
  330.     #pygame.display.update()
  331.  
  332.     # Explode bombs (make into function later), Add this to a master controller
  333.     # entity,
  334.     for bomb in bombs:
  335.         if bomb.time <= 0:
  336.             bomb.explode()
  337.             # Wait three more frames
  338.             # Remove bomb from array
  339.             bomb.destroy()
  340.         else:
  341.             # Draw ticking bombs
  342.             bomb.time -= tick
  343.             bomb.draw()
  344.  
  345.     if len(wastebasket) > 0:
  346.         print len(wastebasket),'bombs found in wastebasket...'
  347.         for bomb in wastebasket:
  348.             try:
  349.                 bombs.pop(bomb.index)
  350.             except:
  351.                 print 'bombs registered:',len(bombs)
  352.                 print 'bomb index:',bomb.index
  353.             print 'bomb removed'
  354.         wastebasket = []
  355.  
  356.     # Draw the dwarf, just for fun
  357.     dwarfo.draw()
  358.    
  359.     # Show drawn objects
  360.     pygame.display.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement