欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pygame的一个小问题,未解决

程序员文章站 2022-05-18 14:16:22
...

说明:这是python编程从入门到实践中255页说明的程序的一个自己的改编。

rain相当于书中的alien(外星人),rains(就是外星人群),spider相当于ship其余的和书中类似。

代码自己改编了一部分。自己瞎写的。 

#bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
    def __init__(self,screen,spider,settings):
        super(Bullet,self).__init__()
        self.screen = screen
        self.spider = spider
        self.rect = pygame.Rect(0,0,settings.bullet_width,settings.bullet_height)

        self.rect.top = self.spider.rect.top
        self.rect.centerx = self.spider.rect.centerx
        self.settings = settings
        self.y = float(self.rect.y)

    def update(self):
        self.y -= self.settings.bullet_speed_factor
        self.rect.y = self.y
    def draw_bullet(self):
        pygame.draw.rect(self.screen,self.settings.bullet_color,self.rect)







#game_functions.py
import pygame
import sys
from rain import Rain
from bullet import Bullet
from time   import sleep

def check_key_events(role,screen,spider,settings,bullets):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,role,screen,spider,settings,bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,role)

def check_keydown_events(event,role,screen,spider,settings,bullets):
    if event.key == pygame.K_q:
        sys.exit()
    elif event.key == pygame.K_LEFT:
        role.moving_left = True
    elif event.key == pygame.K_RIGHT:
        role.moving_right = True
    elif event.key == pygame.K_UP:
        role.moving_up = True
    elif event.key == pygame.K_DOWN:
        role.moving_down = True
    elif event.key == pygame.K_SPACE:
        bullet = Bullet(screen,spider,settings)
        bullets.add(bullet)


def check_keyup_events(event,role):
    if event.key == pygame.K_LEFT:
        role.moving_left = False
    elif event.key == pygame.K_RIGHT:
        role.moving_right = False
    elif event.key == pygame.K_UP:
        role.moving_up = False
    elif event.key == pygame.K_DOWN:
        role.moving_down = False
def update_bullets(bullets,rains):
    bullets.update()
    collision_ = pygame.sprite.groupcollide(bullets,rains,True,True)

        
def update_screen(settings,screen,rains,role,bullets):
    screen.fill(settings.color)
    rains.draw(screen)
    role.blitme()
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    pygame.display.flip()

def get_available_space_x(settings,rain):
    available_space_x = settings.screen_width - 4 * rain.rect.width
    return available_space_x
def get_rain_numbers_x(settings,rain):
    available_space_x = get_available_space_x(settings,rain)
    rain_numbers = int(available_space_x / (2 * rain.rect.width))
    return rain_numbers
def get_available_space_y(settings,rain):
    available_space_y = settings.screen_height - (4 * rain.rect.height)
    return available_space_y
def get_rain_rows(settings,rain):
    available_space_y = get_available_space_y(settings,rain)
    rain_rows = int(available_space_y / (2 * rain.rect.height))
    return rain_rows
def create_rain_drop(screen,settings,row_number,rain_number_x,rain,rains):
    rain_width = rain.rect.width
    rain_height = rain.rect.height

    rain_drop =Rain(screen,settings) 
    rain_drop.x = rain_width + 2 * rain_width * rain_number_x
    rain_drop.y = rain_height + 2 * rain_height * row_number

    rain_drop.rect.x = rain_drop.x
    rain_drop.rect.y = rain_drop.y
    rains.add(rain_drop)

def create_rain_sets(settings,rain,screen,rains):
    rain_width = rain.rect.width
    rain_height = rain.rect.height
    
    row_numbers = get_rain_rows(settings,rain)
    rain_numbers_x = get_rain_numbers_x(settings,rain)

    for row_number in range(row_numbers):
        for rain_number in range(rain_numbers_x):
            create_rain_drop(screen,settings,row_number,rain_number,rain,rains)

def update_rains(rains,rain,settings,screen,role,stats,bullets):
    rains.update()
    if pygame.sprite.spritecollideany(role,rains):    
        ship_hit(settings,stats,screen,rains,bullets,role,rain)
    """
    for rain in rains.copy():
        if rain.is_out():
            rains.remove(rain)       
            print("spider hit!!!")
    """
    if len(rains) == 0 and stats.ships_left > 0:
        create_rain_sets(settings,rain,screen,rains)
        role.center_ship()
        #暂停
        sleep(0.5)
    check_aliens_bottom(settings,stats,screen,role,rains,bullets,rain)

    #下面这行代码不能缩进,不能依赖for循环的执行,因为
    #for循环可能不会执行
def ship_hit(settings,stats,screen,rains,bullets,role,rain):
    if  stats.ships_left > 0: 
            stats.ships_left -= 1
            rains.empty()
            bullets.empty()
            #为何没有下面一句飞机蜘蛛完了还能移动呢?
            #而且,即时没有下一句,底下的大蜘蛛role碰撞了rains后,rains并不消失,屏幕上
            #还有许多的rains
            create_rain_sets(settings,rain,screen,rains)
            role.center_ship()
    else:
        stats.game_active = False
        
def check_aliens_bottom(settings,stats,screen,role,rains,bullets,rain):
    screen_rect = screen.get_rect()
    for rain in rains.sprites():
        if rain.rect.bottom >= screen_rect.bottom:
            ship_hit(settings,stats,screen,rains,bullets,role,rain)
            break

        



#game.py
from pygame.sprite import Group
import sys
import pygame
from settings import Settings
import game_functions as gf
from rain import Rain
from role import Role
from game_stats import GameStats

def run_game():
    pygame.init()
    my_set = Settings()
    screen = pygame.display.set_mode((my_set.screen_width,my_set.screen_height))
    pygame.display.set_caption(my_set.caption)
    my_rain = Rain(screen,my_set)
    rains = Group()
    gf.create_rain_sets(my_set,my_rain,screen,rains)
    stats = GameStats(my_set)
    my_role = Role(screen,my_set)
    bullets = Group()
    while True:
        gf.check_key_events(my_role,screen,my_role,my_set,bullets)
        if stats.game_active:
            gf.update_rains(rains,my_rain,my_set,screen,my_role,stats,bullets)
            my_role.update()
            gf.update_bullets(bullets,rains)
        gf.update_screen(my_set,screen,rains,my_role,bullets)
        print(stats.game_active)
        print(stats.ships_left)
run_game()       







#game_stats.py
class GameStats():
    def __init__(self,settings):
        """init the stats information"""
        self.game_active = True
        self.settings = settings
        self.reset_stats()
    def reset_stats(self):
        self.ships_left = self.settings.ship_limit


from pygame.sprite import Sprite
import pygame
import sys
from random import randint
class Rain(Sprite):
    def __init__(self,screen,settings):
        super(Rain,self).__init__()
        self.screen = screen
        self.image = pygame.image.load("role/1234.bmp")
        self.rect = self.image.get_rect()
        self.screen_rect = self.screen.get_rect()
        
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.y = float(self.rect.y)
        self.x = float(self.rect.x)
        self.settings = settings
        
    def blitme(self):
        self.screen.blit(self.image,self.rect)
    def update(self):
        #上下左右随机运动
        r = randint(1,4)
        mod = r % 4
        if mod == 0:
            self.y -= self.settings.bullet_speed_factor
        elif mod == 1:
            self.y += self.settings.bullet_speed_factor
        elif mod == 2:
            self.x -= self.settings.bullet_speed_factor
        elif mod == 3:
            self.x += self.settings.bullet_speed_factor
        self.rect.x = self.x
        self.rect.y = self.y
    def is_out(self):
        if self.rect.bottom < self.screen_rect.top:
            return True
        elif self.rect.top > self.screen_rect.bottom:
            return True
        elif self.rect.right < 0:
            return True
        elif self.rect.left > self.screen_rect.right:
            return True
        else:
            return False
            










#role.py
import pygame
class Role():
    def __init__(self,screen,settings):
        self.image = pygame.image.load("role/spider.bmp")
        self.rect = self.image.get_rect()

        self.screen = screen
        self.screen_rect = self.screen.get_rect()
        self.rect.bottom = self.screen_rect.bottom
        self.rect.centerx = self.screen_rect.centerx

        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False

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

        self.settings = settings

    def blitme(self):
        self.screen.blit(self.image,self.rect)
    def update(self):
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.settings.role_speed_factor
        elif self.moving_left and self.rect.left > 0:
            self.x -= self.settings.role_speed_factor
        elif self.moving_up and self.rect.top > self.screen_rect.top:
            self.y -= self.settings.role_speed_factor
        elif self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.y += self.settings.role_speed_factor
        self.rect.x = self.x
        self.rect.y = self.y
    def center_ship(self):
        #以下两句代码不管用
        #原因在于每次
        #self.rect.centerx = self.screen_rect.centerx
        #self.rect.bottom  = self.screen_rect.bottom
        self.x = self.screen_rect.centerx
        self.x -= 0.5 * float(self.rect.width)
        self.y = self.screen_rect.bottom - 40
        self.rect.x = self.x
        self.rect.y = self.y





#settings.py
class Settings():
    def __init__(self):
        self.rain_drop_speed  = 0.2

        self.screen_width = 1000
        self.screen_height = 800
        self.caption   = 'rain_drop'
        self.color = (255,255,255)

        self.role_speed_factor = 1.5

        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_speed_factor = 2
        #红色子弹
        self.bullet_color = 255,0,0    
        self.ship_limit = 5





问题,game_functions.py中的一个问题,已经卸载game_functions.py中了。