python3 編譯器 pycharm
man.py
import pygame from pygame.sprite import Sprite class Mans(Sprite): def __init__(self,screen): super(Mans, self).__init__() self.screen=screen self.image_ori=pygame.image.load(r'images\man.jpg') self.image=pygame.transform.smoothscale(self.image_ori,(40,60)) self.rect=self.image.get_rect() self.screen_rect=self.screen.get_rect() self.rect.centerx=self.screen_rect.centerx self.rect.bottom=self.screen_rect.bottom self.moving_right=False self.moving_left=False self.x=float(self.rect.centerx) 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+=0.5 if self.moving_left and self.rect.left>0: self.x-=0.5 self.rect.x=self.x
class Settings(): def __init__(self): self.bg_color=(230,230,230) self.caption='ball game' self.available_times=3 self.game_active=True
ball.py
import pygame from random import randint from pygame.sprite import Sprite class Balls(Sprite): def __init__(self,screen): super(Balls, self).__init__() self.screen=screen self.image_ori=pygame.image.load(r'images\ball.jpg') self.image=pygame.transform.smoothscale(self.image_ori,(30,30)) self.screen_rect=self.screen.get_rect() self.rect=self.image.get_rect() self.rect.top=self.screen_rect.top self.left=self.rect.width self.right=self.screen_rect.width-self.rect.width self.rect.centerx=randint(self.left,self.right) self.y=float(self.rect.y) def blitme(self): self.screen.blit(self.image,self.rect) def update(self): self.y+=0.2 self.rect.y=self.y
get_fun.py
import sys import pygame from pygame.sprite import Sprite from ball import Balls def check_keydown_event(event,man): if event.key==pygame.K_RIGHT: man.moving_right=True elif event.key==pygame.K_LEFT: man.moving_left=True def check_keyup_event(event,man): if event.key==pygame.K_RIGHT: man.moving_right=False elif event.key==pygame.K_LEFT: man.moving_left=False def check_event(man): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type==pygame.KEYDOWN: check_keydown_event(event, man) elif event.type==pygame.KEYUP: check_keyup_event(event,man) def update_ball(ball,human,screen,ai_settings): ball.update() collisions=pygame.sprite.groupcollide(human,ball,False,True) for b in ball.copy(): if b.rect.top>=b.screen_rect.bottom: ball.remove(b) ai_settings.available_times-=1 if ai_settings.available_times==0: ai_settings.game_active=False if len(ball)==0 : b=Balls(screen) ball.add(b) def update_screen(screen,man,ball,bg_color): screen.fill(bg_color) ball.draw(screen) man.blitme() pygame.display.flip()
catch.py
import pygame from man import Mans from ball import Balls import get_fun as gf from pygame.sprite import Group from settings import Settings def catch(): pygame.init() screen=pygame.display.set_mode((400,600)) ai_settings=Settings() pygame.display.set_caption(ai_settings.caption) man=Mans(screen) ball=Balls(screen) balls=Group() balls.add(ball) human=Group() human.add(man) while True: gf.check_event(man) if ai_settings.game_active: gf.update_ball(balls,human,screen,ai_settings) human.update() gf.update_screen(screen,man,balls,ai_settings.bg_color) catch()
這個程序可以完整的模擬出接球、球消失的情形併產生新的球,並對接不到球三次進行處理。
但在編程過程中,遇到了幾個問題。
一、是對balls和human這兩個Group的調用,讓他們移動的函數名只能設置爲update,如過換成其他函數名,就會報錯。
如將human.py裏的update函數改爲move,主函數裏同樣修改,報錯如下:
AttributeError: 'Group' object has no attribute 'move'
原因未知,求指教。
二、是處理三次借不到球的計算。
該問題的處理是在get_fun.py的update_ball中完成的,該函數最初設計的樣子如下
def update_ball(ball,human,screen,ai_settings): ball.update() collisions=pygame.sprite.groupcollide(human,ball,False,True) touch=False for b in ball.sprites(): if b.rect.top>b.screen_rect.bottom: touch=True ai_settings.available_times-=1 else:touch=False if ai_settings.available_times==0: ai_settings.game_active=False if len(ball)==0 or touch: b=Balls(screen) ball.add(b)
這裏本意是用一個bool來控制到達底邊的情況,但是由於,沒有將原來的Ball中的ball刪去,因此這個程序運行了一次球掉到底端後,Ball中會有兩個精靈,造成第二個球掉下來的時候,還有一個球在bottom以下,因此在第二個球掉了一個像素之後,ai_settings.available_times就減到0了。要注意刪除無用的精靈。