Python版本极简打飞机

简介

以前的代码了,今天刚好看到,就传上来了,当时是网上看了下python的书,里面讲了打飞机这个游戏,就用python写出来玩了下,使用的是pygame模块

主函数

主函数主要创建子弹,飞机,敌机,调度各功能部件

def run_game():
    #init game and screen
    pygame.init()
    game_settings = settings.Settings()
    screen = pygame.display.set_mode((game_settings.screen_width, game_settings.screen_height))
    pygame.display.set_caption('Plane')

    ship = Ship(game_settings, screen)
    bullets = Group()
    enemys = Group()
    booms = Group()
    gf.create_enemys(game_settings, screen, enemys, ship)

    stats = GameStats(game_settings)
    try:
        with open("./score.txt", "r") as file_score:
            stats.high_score = int(file_score.read())
    except FileNotFoundError:
        pass
    play_button = Button(game_settings, screen, "Play")
    score = Scoreboard(screen, game_settings, stats)

    while True:
        gf.check_events(game_settings, stats, screen, ship, bullets, enemys, booms, play_button, score)
        if stats.game_active:
            ship.update()
            gf.update_bullets(game_settings, stats, screen, bullets, enemys, booms, ship, score)
            gf.update_enemys(game_settings, screen, enemys, ship, bullets, stats, score)
        gf.update_screen(game_settings, stats, screen, ship, bullets, enemys, booms, play_button, score)

if __name__ == '__main__':
    run_game()

配置

主要是生命,速度,击毁敌机得分

class Settings(object):
    """some settings of the game"""
    def __init__(self):
        self.screen_width = 400
        self.screen_height = 600
        self.bg_color = (218, 218, 218)
        self.ship_limit = 3

        #bullet settings 
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = (110, 20, 70)
        self.bullet_allow = 50

        self.speed_up_scale = 1.1
        self.enemy_drop_speed = 0.03
        self.reset_speed_factors()

    def reset_speed_factors(self):
        self.ship_speed_factor = 1
        self.bullet_speed_factor = 1
        self.enemy_speed_factor = 1
        #self.enemy_drop_speed = 0.01
        self.enemy_direction = 1
        self.enemy_score = 50

    def increase_speed(self):
        #self.ship_speed_factor *= self.speed_up_scale
        self.bullet_speed_factor *= self.speed_up_scale
        self.enemy_speed_factor *= self.speed_up_scale
        self.enemy_drop_speed *= self.speed_up_scale
        self.enemy_score *= 2

游戏状态

记录飞机等级,分数,游戏是否暂停

class GameStats(object):
    """stats the game info and score of player"""
    def __init__(self, game_settings):
        self.game_settings = game_settings
        self.reset_stats()
        self.game_active = False
        self.high_score = 0
        self.level = 1

    def reset_stats(self):
        self.ship_left = self.game_settings.ship_limit
        self.score = 0
        self.level = 1

敌机

包含边界检查,绘制,运动

import pygame
from pygame.sprite import Sprite

class Enemy(Sprite):
    """define the behavior of enemy"""

    def __init__(self, game_settings, screen):
        super().__init__()
        self.screen = screen
        self.game_settings = game_settings
        self.image = pygame.image.load("images/enemy.bmp")
        self.rect = self.image.get_rect()

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

    def blitme(self):
        self.screen.blit(self.image, self.rect)

    def update(self):
        self.y += self.game_settings.enemy_drop_speed
        self.rect.y = self.y
        #self.x += (self.game_settings.enemy_speed_factor * self.game_settings.enemy_direction)
        #self.rect.x = self.x

    def check_edges(self):
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True
        else:
            return False

子弹

包含子弹的绘制与运动

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """define the of behavior bullet"""

    def __init__(self, game_settings, screen, ship):
        super().__init__()
        self.screen = screen

        self.rect = pygame.Rect(0, 0, game_settings.bullet_width, game_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top

        self.y = float(self.rect.y)
        self.color = game_settings.bullet_color
        self.speed_factor = game_settings.bullet_speed_factor

    def update(self):
        self.y -= self.speed_factor
        self.rect.y = self.y

    def draw_bullet(self):
        pygame.draw.rect(self.screen, self.color, self.rect)

爆炸效果

碰撞后显示图片,然后擦除,制造爆炸效果

import pygame
from pygame.sprite import Sprite

class Boom(Sprite):
    """description of class"""

    def __init__(self, screen):
        super().__init__()
        self.screen = screen
        self.image = pygame.image.load("images/boom.bmp")
        self.rect = self.image.get_rect()

        self.rect.x = 0
        self.rect.y = 0

        self.earse = 10

    def blitme(self):
        self.screen.blit(self.image, self.rect)
        self.earse -= 1

飞船

实现飞船的绘制与运动

import pygame
from pygame.sprite import Sprite

class Ship(Sprite):
    """Define the ship object"""
    def __init__(self, game_settings, screen):
        #init ship and set the original position
        super().__init__()
        self.screen = screen
        self.game_settings = game_settings
        self.image = pygame.image.load("images/ship.bmp")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
        self.center = float(self.rect.centerx)

        self.move_right = False
        self.move_left = False

    def blitme(self):
        self.screen.blit(self.image, self.rect)

    def update(self):
        if self.move_right and self.rect.right < self.screen_rect.right:
            self.center += self.game_settings.ship_speed_factor

        if self.move_left and self.rect.left > 0:
            self.center -= self.game_settings.ship_speed_factor

        self.rect.centerx = self.center

    def center_ship(self):
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
        self.center = float(self.rect.centerx)

        self.move_right = False
        self.move_left = False

功能模块

实现按键检测,碰撞检测,开火,生成敌机等

import sys
import pygame
import settings
from ship import Ship
from bullet import Bullet
from enemy import Enemy
from time import sleep
from boom import Boom

def check_events(game_settings, stats, screen, ship, bullets, enemys, booms, play_button, score):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            with open("./score.txt", "w") as file_score:
                file_score.write(str(stats.high_score))
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_events_keydown(event, game_settings, stats, screen, ship, bullets, enemys, booms, score)
        elif event.type == pygame.KEYUP:
            check_events_keyup(event, ship)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            check_play_button_click(game_settings, stats, screen, play_button, mouse_x, mouse_y, ship, bullets, 
                                    enemys, booms, score)
            
def check_play_button_click(game_settings, stats, screen, play_button, x, y, ship, bullets, enemys, booms, score):
    if not stats.game_active and play_button.rect.collidepoint(x, y):
        start_game(game_settings, stats, screen, ship, bullets, enemys, booms, score)

def start_game(game_settings, stats, screen, ship, bullets, enemys, booms, score):
    pygame.mouse.set_visible(False)
    game_settings.reset_speed_factors()
    stats.game_active = True
    stats.reset_stats()
    ship.center_ship()
    bullets.empty()
    enemys.empty()
    booms.empty()
    score.prep_images()
    create_enemys(game_settings, screen, enemys, ship)

def check_events_keydown(event, game_settings, stats, screen, ship, bullets, enemys, booms, score):
    if event.key == pygame.K_RIGHT:
        ship.move_right = True
    elif event.key == pygame.K_LEFT:
        ship.move_left = True
    elif event.key == pygame.K_UP:
        pass
    elif event.key == pygame.K_DOWN:
        pass
    elif event.key == pygame.K_SPACE:
        fire_bullet(game_settings, screen, ship, bullets)
    elif event.key == pygame.K_q:
        sys.exit()
    elif event.key == pygame.K_p:
        start_game(game_settings, stats, screen, ship, bullets, enemys, booms, score)

def fire_bullet(game_settings, screen, ship, bullets):
    if len(bullets) < game_settings.bullet_allow:
        new_bullet = Bullet(game_settings, screen, ship)
        new_bullet1 = Bullet(game_settings, screen, ship)
        new_bullet1.rect.centerx -= 5
        new_bullet2 = Bullet(game_settings, screen, ship)
        new_bullet2.rect.centerx += 5
        bullets.add(new_bullet)
        bullets.add(new_bullet1)
        bullets.add(new_bullet2)

def check_events_keyup(event, ship):
    if event.key == pygame.K_RIGHT:
        ship.move_right = False
    elif event.key == pygame.K_LEFT:
        ship.move_left = False
    elif event.key == pygame.K_UP:
        pass
    elif event.key == pygame.K_DOWN:
        pass

def update_screen(setting, stats, screen, ship, bullets, enemys, booms, play_button, score):
    """update the images on screen"""
    screen.fill(setting.bg_color)
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    enemys.draw(screen)

    score.show_images()

    for boom in booms.sprites():
        if boom.earse <= 0:
            booms.remove(boom)
    for boom in booms.sprites():
        boom.blitme()

    if not stats.game_active:
        play_button.draw_button()

    pygame.display.flip()

def update_bullets(game_settings, stats, screen, bullets, enemys, booms, ship, score):
    bullets.update()

    #delete the disappear bullets
    for bullet in bullets.sprites():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
    #print("current numbers of bullets is %d" % len(bullets))
    check_bullet_enemy_collision(bullets, enemys, booms, game_settings, stats, screen, ship, score)

def check_bullet_enemy_collision(bullets, enemys, booms, game_settings, stats, screen, ship, score):
    collisions = pygame.sprite.groupcollide(bullets, enemys, True, True)
    for hit_enemys in collisions.values():
        stats.score += len(hit_enemys) * game_settings.enemy_score
        check_high_score(stats, score)
        score.prep_score()
        for enemy in hit_enemys:
            new_boom = Boom(screen)
            new_boom.rect.x = enemy.rect.x
            new_boom.rect.y = enemy.rect.y
            booms.add(new_boom)
    if len(enemys) == 0:
        bullets.empty()
        booms.empty()
        game_settings.increase_speed()
        stats.level += 1
        score.prep_images()
        create_enemys(game_settings, screen, enemys, ship)

def check_high_score(stats, score):
    if stats.high_score < stats.score:
        stats.high_score = stats.score
        score.prep_high_score()

def update_enemys(game_settings, screen, enemys, ship, bullets, stats, score):
    check_enemys_edge(game_settings, enemys)
    enemys.update()
    #check collision
    if pygame.sprite.spritecollideany(ship, enemys):
        hit_ship(game_settings, screen, enemys, ship, bullets, stats, score)

    check_enemys_bottom(game_settings, screen, enemys, ship, bullets, stats, score)

def hit_ship(game_settings, screen, enemys, ship, bullets, stats, score):
    stats.ship_left -= 1
    if stats.ship_left <= 0:
        stats.game_active = False
        pygame.mouse.set_visible(True)

    score.prep_ships()
    enemys.empty()
    bullets.empty()
    create_enemys(game_settings, screen, enemys, ship)
    ship.center_ship()
    sleep(1)

def check_enemys_bottom(game_settings, screen, enemys, ship, bullets, stats, score):
    for enemy in enemys.sprites():
        if enemy.y >= game_settings.screen_height:
            hit_ship(game_settings, screen, enemys, ship, bullets, stats, score)
            break

def create_enemys(game_settings, screen, enemys, ship):
    enemy = Enemy(game_settings, screen)
    number_enemys = get_number_of_enemys(game_settings.screen_width, enemy.rect.width)
    #rows_enemys = get_rows_of_enemys(game_settings.screen_height, enemy.rect.height, ship.rect.height)
    rows_enemys = 1
    for row_index in range(rows_enemys):
        for enemy_index in range(number_enemys):
            create_enemy(game_settings, screen, enemy_index, row_index, enemys)

def get_number_of_enemys(screen_width, enemy_width):
    available_space_x = screen_width - enemy_width * 2
    number_enemys = int(available_space_x / (enemy_width * 2))
    return number_enemys

def get_rows_of_enemys(screen_height, enemy_height, ship_height):
    available_space_y = screen_height - ship_height - enemy_height * 3
    rows_enemys = int(available_space_y / (enemy_height * 2))
    return rows_enemys

def create_enemy(game_settings, screen, enemy_index, row_index, enemys):
    enemy = Enemy(game_settings, screen)
    enemy.x += enemy_index * enemy.rect.width * 2
    enemy.y += row_index * enemy.rect.height * 2
    enemy.rect.x = enemy.x
    enemy.rect.y = enemy.y
    enemys.add(enemy)

def check_enemys_edge(game_settings, enemys):
    for enemy in enemys.sprites():
        if enemy.check_edges():
            change_enemys_direction(game_settings, enemys)
            break

def change_enemys_direction(game_settings, enemys):
    for enemy in enemys.sprites():
        enemy.y += game_settings.enemy_drop_speed
        enemy.rect.y = enemy.y
    game_settings.enemy_direction *= -1

最终效果

猜你喜欢

转载自blog.csdn.net/t60339/article/details/82779795