Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Separate this file into modules if the project succeeds
- import sys
- import operator
- import math
- import pygame
- # Variables
- TILE_SIZE = 32
- S_SIZE = S_WIDTH,S_HEIGHT = TILE_SIZE*20,TILE_SIZE*12
- FPSMAX = 60
- CAPTION = 'Dwarf'
- BMB_DELAY = 3000 # 3 seconds
- BMB_ID = 0
- # Initialize
- pygame.init()
- pygame.display.set_caption(CAPTION)
- # Game entities
- screen = pygame.display.set_mode(S_SIZE)
- clock = pygame.time.Clock()
- bombs = []
- wastebasket = []
- # Images
- floor = pygame.image.load('res/sprites/map/floor.jpg').convert()
- dwarf = pygame.image.load('res/sprites/player/dwarf.png').convert_alpha()
- PREFIX_BS = 'res/sprites/bomb/'
- bomb_sprite = {
- '''NOMENCLATURE
- Bomb
- The bomb sprite...
- Explosion parts (exp)
- e: end
- m: middle
- v: vertical
- t: top
- b: bottom
- h: horizontal
- l: left
- r: right
- '''
- # There is an unknown reason why not having an item before bomb makes it
- # unusable from the main loop :^S
- 'nothing' : None, \
- # Bomb
- 'bomb' : pygame.image.load(PREFIX_BS+'bomb.png').convert_alpha(), \
- # Explosions
- 'exp_cnt' : pygame.image.load(PREFIX_BS+'exp_cent.png').convert_alpha(), \
- # Vertical parts
- 'exp_vte' : pygame.image.load(PREFIX_BS+'exp_vte.png').convert_alpha(), \
- 'exp_vtm' : pygame.image.load(PREFIX_BS+'exp_vtm.png').convert_alpha(), \
- 'exp_vbm' : pygame.image.load(PREFIX_BS+'exp_vbm.png').convert_alpha(), \
- 'exp_vbe' : pygame.image.load(PREFIX_BS+'exp_vbe.png').convert_alpha(), \
- # Horizontal parts
- 'exp_hle' : pygame.image.load(PREFIX_BS+'exp_hle.png').convert_alpha(), \
- 'exp_hlm' : pygame.image.load(PREFIX_BS+'exp_hlm.png').convert_alpha(), \
- 'exp_hrm' : pygame.image.load(PREFIX_BS+'exp_hrm.png').convert_alpha(), \
- 'exp_hre' : pygame.image.load(PREFIX_BS+'exp_hre.png').convert_alpha()
- }
- # Functions
- def coords_round(coords):
- x,y = coords
- x = math.ceil(x/TILE_SIZE)*TILE_SIZE
- y = math.ceil(y/TILE_SIZE)*TILE_SIZE
- return x,y
- # Classes
- class Bomb:
- def __init__(self, pos, planter=None, time=BMB_DELAY):
- # Give bomb a unique id
- global BMB_ID
- BMB_ID += 1
- self.id = BMB_ID
- self.index = None
- self.planter = planter
- self.pos = pos
- self.time = time
- self.hitbox = pygame.Rect(pos,(TILE_SIZE,TILE_SIZE))
- self.range = 2
- self.aoe = self.upd_aoe()
- # Alias
- self.upd_index = self.get_index
- return
- def destroy(self):
- self.upd_index()
- wastebasket.append(self)
- print 'appended'
- return
- def get_index(self):
- '''Gets the index of the bomb in the list'''
- for bomb in bombs:
- if bomb.id == self.id:
- self.index = bombs.index(bomb)
- return self.index
- def explode(self):
- global bombs
- '''Explodes the bomb and its neighbors.
- It can be optimized because the loop checks various times if several
- bombs collide, as a natural deffect.
- A possible solution would be to set a global master to control all
- this tasks and control the bombs explosions and whatnot.'''
- r = self.range
- # Check for explosion collisions
- # Solution to problem below:
- # Find a method to copy a list without letting a link between them
- # exist.
- bombs_others = []
- for bomb in bombs:
- if bomb.id != self.id:
- bombs_others.append(bomb)
- #bombs_others.pop(self.get_index()) <-- error, modifying a list which
- # has been set to another, modifyies the other as well. See solution
- # in the comment above.
- '''
- if len(bombs_others) > 0:
- for bomb in bombs_others:
- if self.aoe[0].colliderect(bomb.hitbox) or \
- self.aoe[1].colliderect(bomb.hitbox):
- bomb.explode()
- '''
- for bomb in bombs:
- if bomb.id != self.id:
- try:
- print self.aoe[0].colliderect(bomb.hitbox)[0]
- except:
- print 'bomb hitbox:',bomb.hitbox.__class__
- print 'self h aoe:',self.aoe[0].__class__
- print 'self v aoe:',self.aoe[1].__class__
- #sys.exit()
- if self.aoe[0].colliderect(bomb.hitbox) or \
- self.aoe[1].colliderect(bomb.hitbox):
- bomb.explode()
- if self.aoe[0].colliderect(dwarfo.hitbox) or \
- self.aoe[1].colliderect(dwarfo.hitbox):
- print 'Ouch!'
- # Draw explosion waves
- self.draw_exp()
- pygame.time.wait(100)
- return
- def upd_aoe(self):
- '''Updates the area of effect of a bomb when its created and whenever its
- range changes'''
- r = self.range
- expansion = 2*r*TILE_SIZE
- hor = self.hitbox.inflate(expansion,0)
- vrt = self.hitbox.inflate(0,expansion)
- self.aoe = hor,vrt
- return self.aoe
- def draw(self):
- global bomb_sprite
- screen.blit(bomb_sprite['bomb'], self.pos)
- return
- def draw_exp(self):
- global bomb_sprite
- # Draw explosion center
- screen.blit(bomb_sprite['exp_cnt'], self.pos)
- # Draw end explosion waves
- screen.blit(bomb_sprite['exp_hle'], \
- (self.pos[0]-self.range*TILE_SIZE, self.pos[1]))
- screen.blit(bomb_sprite['exp_hre'], \
- (self.pos[0]+self.range*TILE_SIZE, self.pos[1]))
- screen.blit(bomb_sprite['exp_vte'], \
- (self.pos[0], self.pos[1]-self.range*TILE_SIZE))
- screen.blit(bomb_sprite['exp_vbe'], \
- (self.pos[0], self.pos[1]+self.range*TILE_SIZE))
- # Draw middle explosion waves
- if self.range > 1:
- for i in range(self.range)[1:]:
- screen.blit(bomb_sprite['exp_vtm'], \
- (self.pos[0], self.pos[1]-i*TILE_SIZE))
- screen.blit(bomb_sprite['exp_vbm'], \
- (self.pos[0], self.pos[1]+i*TILE_SIZE))
- screen.blit(bomb_sprite['exp_hlm'], \
- (self.pos[0]-i*TILE_SIZE,self.pos[1]))
- screen.blit(bomb_sprite['exp_hrm'], \
- (self.pos[0]+i*TILE_SIZE,self.pos[1]))
- # Update the modified tiles
- pygame.display.update(self.aoe)
- return
- class Player:
- def __init__(self, pos, sprite=dwarf):
- self.pos = [pos[0], pos[1]]
- self.hitbox = pygame.Rect(self.pos, (TILE_SIZE,TILE_SIZE))
- self.step_factor = 1 # Multiplied by TILE_SIZE
- self.step_size = self.get_stepsize()
- self.sprite = sprite
- self.bombs = [] # for kill credit
- # Alias
- self.get_hitbox = self.upd_hitbox
- def upd_hitbox(self):
- self.hitbox = pygame.Rect( self.pos, (TILE_SIZE, TILE_SIZE) )
- return self.hitbox
- def get_stepsize(self):
- self.step_size = self.step_factor*TILE_SIZE
- return self.step_size
- def listen(self, key):
- # Movement
- if key == pygame.K_UP:
- self.move_up()
- elif key == pygame.K_DOWN:
- self.move_down()
- elif key == pygame.K_LEFT:
- self.move_left()
- elif key == pygame.K_RIGHT:
- self.move_right()
- # Actions
- elif key == pygame.K_SPACE:
- self.bomb()
- def move_up(self):
- self.pos[1] -= self.step_size
- self.upd_hitbox()
- return
- def move_down(self):
- self.pos[1] += self.step_size
- self.upd_hitbox()
- return
- def move_left(self):
- self.pos[0] -= self.step_size
- self.upd_hitbox()
- return
- def move_right(self):
- self.pos[0] += self.step_size
- self.upd_hitbox()
- return
- def bomb(self):
- pos = coords_round((self.hitbox.centerx, \
- self.hitbox.centery))
- # Create bomb
- newbomb = Bomb(pos, self)
- # Check if space is available for bombs, via hitbox collision
- placebomb = True
- for bomb in bombs:
- if newbomb.hitbox == bomb.hitbox:
- placebomb = False
- # Decide bomb placement accordingly
- if placebomb:
- self.bombs.append(newbomb)
- bombs.append(newbomb)
- self.upd_bombs()
- print 'bomb planted!!!',len(self.bombs),'total :)'
- return
- def upd_bombs(self):
- for bomb in self.bombs:
- if bomb not in bombs:
- self.bombs.remove(bomb)
- return
- def draw(self):
- screen.blit(self.sprite, self.pos)
- return
- # Tests
- #print range(S_WIDTH/10 + 1)
- dwarfo = Player((S_WIDTH/2, S_HEIGHT/2))
- while 1:
- putbomb = 0
- # Set framerate
- tick = clock.tick(FPSMAX)
- #print 'tick'
- # Read events
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- pygame.quit()
- sys.exit()
- elif event.type == pygame.MOUSEBUTTONDOWN:
- putbomb = 1
- elif event.type == pygame.KEYDOWN:
- dwarfo.listen(event.key)
- if event.key == pygame.K_c:
- print pygame.mouse.get_pos()
- # Put bomb
- if putbomb:
- pos = coords_round( pygame.mouse.get_pos() )
- bombs.append( Bomb(pos) )
- #bombs.sort( key=operator.itemgetter(1) ) # Sorts the bombs according to y coordinate before blit
- # Put floor (make into function later)
- for w in range(S_WIDTH/10):
- for h in range(S_HEIGHT/10):
- screen.blit(floor,(w*TILE_SIZE,h*TILE_SIZE))
- #pygame.display.update()
- # Explode bombs (make into function later), Add this to a master controller
- # entity,
- for bomb in bombs:
- if bomb.time <= 0:
- bomb.explode()
- # Wait three more frames
- # Remove bomb from array
- bomb.destroy()
- else:
- # Draw ticking bombs
- bomb.time -= tick
- bomb.draw()
- if len(wastebasket) > 0:
- print len(wastebasket),'bombs found in wastebasket...'
- for bomb in wastebasket:
- try:
- bombs.pop(bomb.index)
- except:
- print 'bombs registered:',len(bombs)
- print 'bomb index:',bomb.index
- print 'bomb removed'
- wastebasket = []
- # Draw the dwarf, just for fun
- dwarfo.draw()
- # Show drawn objects
- pygame.display.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement