ピンボール

ピンボール(小6男子/作)
scratch教材のピンボールゲームをPythonで見事に再現していますね。

CPUの強さ設定が一番、頭を悩ませるところだと思います。「パドルCPU_rect.y=ボール_rect.y」にしてしまうとCPUが無敵になってしまい、ゲームとして成立しません。

そこをscratchで学んだロジック(〇秒かけてボールに近づく)を使って乗り切っていますね。pygameにはdelayという時間を制御する関数がありますが、それを使わずに「timer+=0.1 if timer>5:timer=0」で間に合わせている点がすばらしいと思います。


Pythonで記述したコード
import pygame,sys,random,time

#pygameの初期化
pygame.init()

#スクリーンの作成
screen=pygame.display.set_mode((800,600))

#変数定義
vx=8 #ボールのx座標
vy=8 #ボールのy座標
timer=0 #時間を管理する
player=0 #プレイヤのスコアを管理する
cpu=0 #CPUのスコアを管理する

#画像アップロード
背景=pygame.image.load("image\背景.png")
ボール=pygame.image.load("image\ボール.png")
ボール=pygame.transform.scale(ボール,(30,30))

#フォントアップロード
font=pygame.font.Font("font\日本語フォント.ttf",30)
font1=pygame.font.Font("font\日本語フォント.ttf",80)#ゲーム終了時の文字

#音声ファイルのアップロード
BGM=pygame.mixer.Sound("sound\BGM.wav")
バウンド音=pygame.mixer.Sound("sound\バウンド.wav")
勝利音=pygame.mixer.Sound("sound\Win.wav")
敗北音=pygame.mixer.Sound("sound\Lose.wav")

#BGM
BGM.play(-1)

#ボリューム調整
BGM.set_volume(0.1)
バウンド音.set_volume(0.2)

#画像の初期位置と大きさを定義
パドル_rect=pygame.Rect(50,250,20,100)
パドルCPU_rect=pygame.Rect(700,250,20,100)
ボール_rect=pygame.Rect(400,450,30,30)

#ゲームステージ
def gamestage():
    global vx,vy,py,timer,player,cpu,スコアP,スコアC
    #文字列の画像を作る
    スコアP=font.render("プレイヤ:"+str(player)+"点",True,"red")
    スコアC=font.render("CPU:"+str(cpu)+"点",True,"red")
    
    #背景の転送
    screen.blit(背景,(0,0,0,0))
    
    #文字の転送
    screen.blit(スコアP,(30,30))#プレイヤ
    screen.blit(スコアC,(600,30))#CPU
    
    #ボールの転送
    screen.blit(ボール,ボール_rect)
    
    #パドルの描画
    pygame.draw.rect(screen,pygame.Color("purple"),パドル_rect)
    pygame.draw.rect(screen,pygame.Color("blue"),パドルCPU_rect)
    
    #ユーザからの入力を調べる
    (mx,my)=pygame.mouse.get_pos()
    
    #パドルの移動処理
    パドル_rect.y=my-50
    
    #CPUのタイムラグ
    if 2600-30:
        vy=-vy
        
    #パドルとボールの衝突処理
    if パドル_rect.colliderect(ボール_rect):
        バウンド音.play()
        vx=random.randint(5,10)
        vy=random.randint(-20,20)
    if パドルCPU_rect.colliderect(ボール_rect) :
        バウンド音.play()
        vx=random.randint(-10,-5)
        vy=random.randint(-20,20)
        
    #ボールの移動量
    ボール_rect.x +=vx
    ボール_rect.y +=vy
    
    #CPUパドルのタイムラグ※2~3秒かけてボールに近づかせる
    timer+=0.1
    if timer>5:
        timer=0

    #勝敗の処理
    if ボール_rect.x<0:#負けたとき
        敗北音.play()
        cpu +=1
        スコアC=font.render("CPU:"+str(cpu)+"点",True,"red")
        リプレイ()
        
    if ボール_rect.x>800:#勝ったとき
        勝利音.play()
        player +=1
        スコアP=font.render("プレイヤ:"+str(player)+"点",True,"red")
        リプレイ()
        
def リプレイ():
    global スコアP,スコアC
    ボール_rect.x=380 #ボールを最初の位置に戻す
    ボール_rect.y=280 #ボールを最初の位置に戻す
    パドル_rect.y=250 #プレイヤのパドルを最初の位置に戻す
    パドルCPU_rect.y=250 #CPUのパドルを最初の位置に戻す
    screen.blit(背景,(0,0,0,0)) #背景を転送
    screen.blit(ボール,ボール_rect) #ボールを転送
    pygame.draw.rect(screen,pygame.Color("purple"),パドル_rect)#プレイヤのパドルを描く
    pygame.draw.rect(screen,pygame.Color("blue"),パドルCPU_rect)#CPUのパドルを描く
    screen.blit(スコアP,(30,30))#プレイヤのスコアを転送
    screen.blit(スコアC,(600,30))#CPUのスコアを転送
    pygame.display.update()
    time.sleep(2) #2秒待つ
    vx=random.randint(-10,10)#リプレイ時のボールの向き

def 終了():
    if player>cpu:
        勝ち=font1.render("プレイヤの勝ち",True,"orange")
        screen.blit(勝ち,(100,250))
        pygame.display.update()
    else:
        負け=font1.render("プレイヤの負け",True,"orange")
        screen.blit(負け,(100,250))
        pygame.display.update()

    while True: #×印でウィンドウを閉じる処理              
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
    
while True:
    gamestage()
    pygame.display.update()
    if player == 3 or cpu==3:
        終了()
        break       
    pygame.time.Clock().tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()