最简方块射击游戏核心原理_方向.py

"""最简方块射击游戏核心原理_方向.py"""
import pygame
import random
import math
 
# 定义颜色常量
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
 
SCREEN_WIDTH = 700
SCREEN_HEIGHT = 400
 
 
class Block(pygame.sprite.Sprite):
    """ 定义方块类 """
    def __init__(self, color):
        # 调用父类的初始化方法
        super().__init__()
 
        self.image = pygame.Surface([20, 15])
        self.image.fill(color)
 
        self.rect = self.image.get_rect()
 
 
class Player(pygame.sprite.Sprite):
    """ 玩家类 """
 
    def __init__(self):
        """ 当玩家实例化时给它设定image和rect属性. """
        # 调用父类的初始化方法
        super().__init__()
 
        self.image = pygame.Surface([20, 20])
        self.image.fill(RED)
 
        self.rect = self.image.get_rect()
 
 
class Bullet(pygame.sprite.Sprite):
    """ 此类代表子弹. """
 
    def __init__(self, start_x, start_y, dest_x, dest_y):
        """ 它有起点和终点坐标
        """
 
        # 调用父类型初始化方法
        super().__init__()
 
        # 给子弹设置图形对象
        self.image = pygame.Surface([4, 10])
        self.image.fill(BLACK)
 
        self.rect = self.image.get_rect()
 
        # 设置起始坐标
        self.rect.x = start_x
        self.rect.y = start_y
 
        # 由于rect的各个属性值都是整数,对于瞄准不精确,要换成浮点数
        self.floating_point_x = start_x
        self.floating_point_y = start_y
 
        # 根据起点和终点计算发射角度
        x_diff = dest_x - start_x
        y_diff = dest_y - start_y
        angle = math.atan2(y_diff, x_diff);
 
        # 根据角度计算水平和垂直速度
        velocity = 5
        self.change_x = math.cos(angle) * velocity
        self.change_y = math.sin(angle) * velocity
 
    def update(self):
        """ 更新子弹坐标. """
 
        # 浮点数表示更精确
        self.floating_point_y += self.change_y
        self.floating_point_x += self.change_x
 
        # 由于最终显示的时候要用整数,所以要转换回整数
        self.rect.y = int(self.floating_point_y)
        self.rect.x = int(self.floating_point_x)
 
        # 子弹飞出屏幕,杀死它.
        if self.rect.x < 0 or self.rect.x > SCREEN_WIDTH or self.rect.y < 0 or self.rect.y > SCREEN_HEIGHT:
            self.kill()
 
  
 
# 初始化派gei
pygame.init()
 
# 新建屏幕图层 
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("最简方块射击游戏核心原理_方向.py")
 
# 所有的角色列表,包括玩家,方块,当单击鼠标时也会把子弹加到此列表
all_sprites_list = pygame.sprite.Group()
 
# 所有方块列表
block_list = pygame.sprite.Group()
 
# 所有子弹列表
bullet_list = pygame.sprite.Group()
 
# --- 创建方块
 
for i in range(50):
    # 实例化一个方块
    block = Block(BLUE)
 
    # 设定它的一个随机坐标
    block.rect.x = random.randrange(SCREEN_WIDTH)
    block.rect.y = random.randrange(SCREEN_HEIGHT - 50)
 
    # 把它加到方块列表中和所有角色列表中
    block_list.add(block)
    all_sprites_list.add(block)
 
# 创建玩家对象,并添加到所有角色列表
player = Player()
all_sprites_list.add(player)
 
# 此变量用来结束while循环.
done = False
 
# 此变量用来设置帧率即fps(frame per second,每秒显示的帧图数)
clock = pygame.time.Clock()
 
score = 0
 
player.rect.x = SCREEN_WIDTH / 2
player.rect.y = SCREEN_HEIGHT / 2
 
# -------- 游戏主循环 -----------
while not done:
    # --- 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
 
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # 按下鼠标键就开火射击
 
            # 得到鼠标指针坐标
            pos = pygame.mouse.get_pos()
 
            mouse_x = pos[0]
            mouse_y = pos[1]
 
            # 创建子弹,起点就是玩家坐标,根据鼠标指针坐标决定方向
            bullet = Bullet(player.rect.x, player.rect.y, mouse_x, mouse_y)
 
            # 把子弹加到列表中
            all_sprites_list.add(bullet)
            bullet_list.add(bullet) 
     
    # 调用update方法更新所有角色列表
    all_sprites_list.update()
 
    # 遍历每颗子弹,看看有没有碰到方块
    for bullet in bullet_list:
 
        # 检测有没有碰到方块列表中的方块,返回的是一个被击中的方块列表
        block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
 
        # 对每个被击中的方块而言,都要把相应的子弹给从组中移除
        for block in block_hit_list:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
            score += 1
            print(score)
 
        # 飞出屏幕的子弹也要把它从列表中移除
        if bullet.rect.y < -10:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
 
    # --- 接下来是画一帧
 
    # 首先把背景填白
    screen.fill(WHITE)
 
    # 把所有角色画上去
    all_sprites_list.draw(screen)
 
    # 把所画的显示出来
    pygame.display.flip()
 
    # --- 设置帧率为60
    clock.tick(60)
 
pygame.quit()