World War II aircraft to achieve an enhanced version of Python
Game description World War II aircraft
Based on an airplane on github Python implementation shooter PythonShootGmae
original version is relatively simple, there is only one enemy. But where the resource folder contains three enemy aircraft pictures and sound, it has been enhanced based on existing resources.
On this basis, an enhanced version adds the following features
- It supports three types of enemy
- Support enemy firing bullets
- Add weapon type of aircraft (bombs, bullets simultaneously transmit multiple lines)
- The enemy can appear from three directions left, above and to the right
- A number of life-support aircraft
- Add props acquisition (can get bombs, bullets and enhancements)
Code Description
There are four file code implementation
- shooter.py: Initialization and circulated game game main function
- gameRole.py: contains additional class definition games enemy bullets, props and heroes (our aircraft) class, and management of these classes
- resource.py: responsible for picture and sound initialization
- config.py: You can set the difficulty of the parameters of the game
gameRole.py
The case here defined enemy, bullets, props and hero classes inherit the pygame sprite class (pygame.sprite.Sprite), because the collision detection use the wizard class support, there are multiple enemies in multiple bullets using wizard class, you can simplify the complexity of the code.
Enemy herein illustrates the relationship class and its associated class EnemyGroup class.
According to the documentation pygame.sprite.Sprite, subclasses need to implement the update function, and to Sprite class member variable of the image, rect assignment.
The base class for visible game objects. Derived classes will want to override the Sprite.update () and assign a Sprite.image and Sprite.rect attributes.
Enemy class
initialization function sets the class member variable image pygame sprite class needs at the time of the drawing, rect, direction of flight, and weapons.
update function will update the location of the enemy, if you have weapons, but also regularly fired bullets.
class Enemy(pygame.sprite.Sprite):
def __init__(self, enemy_surface, enemy_init_pos, direction, weapon_group):
pygame.sprite.Sprite.__init__(self)
self.image = enemy_surface
self.rect = self.image.get_rect()
self.rect.topleft = enemy_init_pos
self.direction = direction
self.down_index = 0
self.damage = 0
self.is_down = 0
self.is_hit = 0
self.ticks = 0
self.weapon_group = weapon_group
def update(self, enemy_surface, hit_surface=0):
def shootWeapon(weapon_group, position, direction):
weapon_group.shootWeapon(position, direction)
#direction[0]:x , direction[1]:y
should_kill = False
self.rect.x += self.direction[0]
self.rect.y += self.direction[1]
if self.rect.x > SCREEN_WIDTH or self.rect.x < -self.image.get_width():
should_kill = True
if self.rect.y > SCREEN_HEIGHT or self.rect.y < -self.image.get_height():
should_kill = True
if should_kill:
self.kill()
else:
if self.ticks >= ENEMY_SHOOT_CYCLE:
self.ticks = 0
if self.is_hit:
self.is_hit -= 1
self.image = hit_surface
elif len(enemy_surface) >= 2:
self.image = enemy_surface[self.ticks//(ENEMY_SHOOT_CYCLE//2)]
else:
self.image = enemy_surface[0]
self.ticks += 1
if self.weapon_group is not None:
if self.ticks % ENEMY_SHOOT_CYCLE == 0:
shootWeapon(self.weapon_group, [self.rect.centerx, self.rect.y + self.image.get_height()], [0, ENEMY_SHOOT_SPEED])
EnemyGroup class
currently supports three types of enemy, the enemy will be set in the initialization function of the type of enemy_type, create a group spirit group, used to store and manage all types generated by the enemy, the enemy has set up weapons.
createEnemy function will create random enemy aircraft appear from a certain direction (left, above, left), and added to the group.
checkBulletCollide function detects if a bullet heroes and launch of this type of enemy aircraft collided with each collision will cause some damage when the enemy's life is less than the cumulative damage, it is judged to be eliminated.
checkBulletCollide function detects whether the hero and this type of enemy, or enemy bullets launch of a collision.
class EnemyGroup():
def __init__(self, surface, hit_surface, down_surface, down_sound, score, health, speed, enemy_type, weapon_group):
self.surface = surface
self.hit_surface = hit_surface
self.down_surface = down_surface
self.group = pygame.sprite.Group()
self.down_group = pygame.sprite.Group()
self.down_sound = down_sound
self.score = score
self.health = health
self.speed = speed
self.enemy_type = enemy_type
self.weapon_group = weapon_group
def createEnemy(self):
def getDirection(surface, speed, enemy_type):
if enemy_type == EnemyType.EnemyType3:
enemy_init_pos = [randint(0, SCREEN_WIDTH - surface.get_width()), -surface.get_height()]
direction = [0, speed]
else:
# enemy can appear from top side, left side, and right side
appearSide = randint(0, 2)
if appearSide == 0: # from top side
enemy_init_pos = [randint(0, SCREEN_WIDTH - surface.get_width()), -surface.get_height()]
direction = [0, speed]
elif appearSide == 1: # from left side
enemy_init_pos = [-surface.get_width(), randint(0, (ENEMY_APPEAR_HEIGHT - surface.get_height()))]
direction = [randint(1, speed), randint(1, speed)]
elif appearSide == 2: # from right side
enemy_init_pos = [SCREEN_WIDTH, randint(0, (ENEMY_APPEAR_HEIGHT - surface.get_height()))]
direction = [randint(-speed, -1), randint(1, speed)]
return (enemy_init_pos, direction)
(enemy_init_pos, direction) = getDirection(self.surface[0], self.speed, self.enemy_type)
enemy = Enemy(self.surface[0], enemy_init_pos, direction, self.weapon_group)
self.group.add(enemy)
def update(self):
self.group.update(self.surface, self.hit_surface)
if self.weapon_group is not None:
self.weapon_group.update()
def draw(self, screen):
self.group.draw(screen)
if self.weapon_group is not None:
self.weapon_group.draw(screen)
def checkBulletCollide(self, bullets, screen, ticks):
score = 0
self.down_group.add(pygame.sprite.groupcollide(self.group, bullets.group, False, True))
for enemy_down in self.down_group:
if enemy_down.is_down:
screen.blit(self.down_surface[enemy_down.down_index], enemy_down.rect)
if ticks % (ANIMATE_CYCLE//2) == 0:
if enemy_down.down_index < (len(self.down_surface)-1):
if enemy_down.down_index == 0:
self.down_sound.play()
enemy_down.down_index += 1
else:
self.down_group.remove(enemy_down)
score += self.score
else:
enemy_down.damage += bullets.damage
enemy_down.is_hit = ANIMATE_CYCLE//3
if enemy_down.damage >= self.health:
enemy_down.is_down = 1
self.group.remove(enemy_down)
else:
self.down_group.remove(enemy_down)
return score
def checkHeroCollide(self, hero):
enemy_down_list = pygame.sprite.spritecollide(hero, self.group, False)
collide = False
if len(enemy_down_list) > 0:
for enemy_down in enemy_down_list:
if pygame.sprite.collide_circle_ratio(0.7)(enemy_down, hero):
self.group.remove(enemy_down)
self.down_group.add(enemy_down)
enemy_down.is_down = 1
collide = True
if not collide and self.weapon_group is not None:
bullet_hit_list = pygame.sprite.spritecollide(hero, self.weapon_group.group, False)
if len(bullet_hit_list) > 0:
for bullet_hit in bullet_hit_list:
if pygame.sprite.collide_circle_ratio(0.7)(bullet_hit, hero):
self.weapon_group.group.remove(bullet_hit)
collide = True
return collide
shooter.py
Defines a Game class, which paly () handler is the main game loop, is responsible for updating the background image every so often generate enemy and props, to detect bullets and whether the aircraft collided detect whether the hero and enemy aircraft collision . And call the enemy, the hero of their own class to refresh the drawing.
class Game():
def __init__(self, caption, hero, screen_info):
self.screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption(caption)
self.hero = hero
self.clock = pygame.time.Clock()
self.screen_info = screen_info
self.ticks = 0
self.pause = False
self.backgound_y = SCREEN_HEIGHT - background.get_height() # height of background image must be larger than SCREEN_HEIGHT
def play(self, enemy_groups, gift_groups):
def updateBackground(screen, image_height, current_y):
if current_y <= 0:
screen.blit(background, (0, 0), (0, -current_y, SCREEN_WIDTH, SCREEN_HEIGHT))
elif current_y < SCREEN_HEIGHT:
screen.blit(background, (0, 0), (0, image_height - current_y, SCREEN_WIDTH, current_y))
screen.blit(background, (0, current_y), (0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - current_y))
def checkBulletCollide(enemy_group, bullets_group, screen, ticks):
score = 0
for group in enemy_group:
for bullet_group in bullets_group:
score += group.checkBulletCollide(bullet_group, screen, ticks)
return score
def checkHeroCollide(hero, enemy_group):
collide = False
for group in enemy_group:
if group.checkHeroCollide(hero):
collide = True
break;
return collide
self.clock.tick(FRAME_RATE)
if self.backgound_y == SCREEN_HEIGHT:
self.backgound_y = SCREEN_HEIGHT - background.get_height()
updateBackground(self.screen, background.get_height(), self.backgound_y)
self.backgound_y += 1
if self.ticks >= FRAME_RATE:
self.ticks = 0
self.hero.play()
self.createEnemy(enemy_groups, self.ticks, self.screen_info.getScore())
self.createGift(gift_groups, self.ticks, self.screen_info)
self.screen_info.addScore(checkBulletCollide(enemy_groups, self.hero.weapon_groups, self.screen, self.ticks))
if checkHeroCollide(self.hero, enemy_groups):
if self.hero.isHeroCrash():
game_over_sound.play()
for gift_group in gift_groups:
gift_group.checkHeroCollide(self.hero)
for weapon_group in self.hero.weapon_groups:
weapon_group.draw(self.screen)
for enemy_group in enemy_groups:
enemy_group.update()
enemy_group.draw(self.screen)
for gift_group in gift_groups:
gift_group.update()
gift_group.draw(self.screen)
self.screen.blit(self.hero.image, self.hero.rect)
self.ticks += 1
self.screen_info.displayInfo(self.screen, 0, self.hero.bomb_num, self.hero.life)
The main loop of the game is as follows
- To determine the state of the game
- If the game ends, the end of the display screen
- If the game is paused, do not do the operation
- If the game does not pause, for processing
- Get pygame event, read keyboard input and processing
- If there is a direction key input, the mobile hero
while True:
if myGame.isGameOver():
myGame.showGameOver()
elif not myGame.isPause():
myGame.play(enemy_groups, gift_groups)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# get keyboard input
if event.type == pygame.KEYDOWN:
if event.key in offset:
offset[event.key] = 3
elif event.key == pygame.K_SPACE:
myGame.hero.useBomb()
# press z to pause or resume game
elif event.key == pygame.K_z:
myGame.setPause()
elif event.type == pygame.KEYUP:
if event.key in offset:
offset[event.key] = 0
if not myGame.hero.is_hit:
myGame.hero.move(offset)
Game results
Screenshot game execution is as follows:
The complete code
Complete implementation of the code github link aircraft World War II enhanced version
here is the download link csdn aircraft World War II enhanced version of the
compiler environment
python3.7 + pygame1.9