サッカーゲーム

講師から一言
CPUの動きがよく考えられていますね。ボールに近づくように座標を設定し、ボールとネコが衝突した際はボールを左向きに移動させることでサッカーの動きをリアルに再現できています。

単純にx座標を移動させるだけでなく、y座標も少しだけ移動させることでよりリアルなドリブルさばきが実現されています。
ネコの向きを制御するロジックにif文による制御を加えれば、不自然な向きの変更が解消されると思います。
大変、よくできています。

少しコードを修正して理解度確認テストに採用させてもらいますね。


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

#pygameの初期化
pygame.init()

#変数定義
レフトフラグ=False #左向き状態を表す
アップフラグ=False #上向き状態を表す
シュートフラグ=False #ボールの形を表す
ゴール1フラグ=False #ゴール1にゴールを決めたことを表す
ゴール2フラグ=False #ゴール2にゴールを決めたことを表す
得点1=0 #ポコニャンズ(オレンジネコのチーム)
得点2=0 #にゃんこFC(ブルーネコのチーム)
n=0 #シュートしたボールの形変更に使用
a=0 #オレンジネコのコスチューム変更に使用
b=0 #ボールのコスチューム変更に使用
c=0 #オレンジネコのコスチューム変更に使用

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

#フォントのアップロード
font = pygame.font.Font("font\日本語フォント.ttf",30)

#画像アップロード
背景=pygame.image.load("image\背景.png")
ネコ1_右=pygame.image.load("image\ネコ1.png")
ネコ1_右2=pygame.image.load("image\ネコ2.png")
青ネコ1_右=pygame.image.load("image\青ネコ1.png")
青ネコ1_右2=pygame.image.load("image\青ネコ2.png")
ボール1=pygame.image.load("image\ボール1.png")
ボール2=pygame.image.load("image\ボール2.png")
ボール3=pygame.image.load("image\ボール3.png")
ゴール1=pygame.image.load("image\ゴール1.png")
ゴール2=pygame.image.load("image\ゴール2.png")
エンディング=pygame.image.load("image\エンディング.png")

#音声ファイルのダウンロード
BGM=pygame.mixer.Sound("sound\BGM.wav")
ゴール=pygame.mixer.Sound("sound\ゴール.wav")
シュート=pygame.mixer.Sound("sound\シュート.wav")
ドリブル=pygame.mixer.Sound("sound\ドリブル.mp3")
ホイッスル=pygame.mixer.Sound("sound\ホイッスル.wav")

#BGM
BGM.play(-1)

#ボールの変形処理
ボール4=pygame.transform.scale(ボール1,(45,10))

#壁データ
壁=[pygame.Rect(0,0,650,20), #ネコ1_rect⇒(280,180,-20,30)を参考に計算する
   pygame.Rect(0,0,20,434),
   pygame.Rect(630,0,-50,434),
   pygame.Rect(0,414,650,-30)]

#画像の加工
ネコ1_左=pygame.transform.flip(ネコ1_右,True,False)#オレンジネコ
ネコ1_左2=pygame.transform.flip(ネコ1_右2,True,False)#オレンジネコ
青ネコ1_左=pygame.transform.flip(青ネコ1_右,True,False)#青ネコ
青ネコ1_左2=pygame.transform.flip(青ネコ1_右2,True,False)#青ネコ

#コスチューム切り替え用のリスト
ネコ1リスト右=[ネコ1_右,ネコ1_右2]#オレンジネコ
ネコ1リスト左=[ネコ1_左,ネコ1_左2]#オレンジネコ
青ネコ1リスト右=[青ネコ1_右,青ネコ1_右2]#青ネコ
青ネコ1リスト左=[青ネコ1_左,青ネコ1_左2]#青ネコ
ボールリスト=[ボール1,ボール2,ボール3]#ボール

#画像の初期位置と大きさを定義
ネコ1_rect=pygame.Rect(280,180,-20,30)#オレンジネコ
青ネコ1_rect=pygame.Rect(340,180,-20,30)#青ネコ
ボール_rect=pygame.Rect(314,210,-30,-10)#ボール
ゴール1_rect=pygame.Rect(45,105,10,200) #左にあるゴール
ゴール2_rect=pygame.Rect(550,105,-10,200) #右にあるゴール

#メイン処理
def main_proc():
    global レフトフラグ,アップフラグ,シュートフラグ,ゴール1フラグ,ゴール2フラグ
    global a,b,n,得点1,得点2,文字1,文字2
    #ネコ1の位置用変数
    cx=0
    cy=0
    bx=random.randint(5,50)
    by=random.randint(5,50)
    #カウント用
    n=n+1
    #ユーザからの入力を調べる
    key= pygame.key.get_pressed()
    #得点をずっと表示させる処理
    文字1 = font.render("ポコニャンズ:"+str(得点1)+"点",True,"orange")
    文字2 = font.render("にゃんこFC:"+str(得点2)+"点",True,"blue")
    #キーが押されたときの処理
    if key[pygame.K_RIGHT]:#右向矢印キーがおされた時
        cx=3 #ネコ1の移動量
        レフトフラグ=False
        a=a+1 #コスチューム変更
              
    if key[pygame.K_LEFT]:#左向矢印キーがおされた時
        cx=-3 #ネコ1の移動量
        レフトフラグ=True
        a=a+1 #コスチューム変更
        
    if key[pygame.K_UP]:#上向矢印キーがおされた時
        cy=-3 #ネコ1の移動量
        アップフラグ=True
        a=a+1 #コスチューム変更
 
    if key[pygame.K_DOWN]:#下向矢印キーがおされた時
        cy=3 #ネコ1の移動量
        アップフラグ=False
        a=a+1 #コスチューム変更

    if key[pygame.K_LSHIFT]:#左向矢印キーがおされた時
        ボール_rect.x=314
        ボール_rect.y=210

    #ネコ1の移動量
    ネコ1_rect.x = ネコ1_rect.x +cx 
    ネコ1_rect.y = ネコ1_rect.y +cy
    #ボールの衝突
    #ネコ1が左から衝突
    if ボール_rect.colliderect(ネコ1_rect) and レフトフラグ==True:
        if key[pygame.K_SPACE]: #シュート
            ボール_rect.x = ボール_rect.x-bx*3
            b=b+1 #コスチューム変更
            シュートフラグ=True
            シュート.play()
        else: #ドリブル
            ドリブル.play()
            ボール_rect.x = ボール_rect.x +bx*-1
            b=b+1 #コスチューム変更
        
    #ネコ1が右から衝突    
    if ボール_rect.colliderect(ネコ1_rect) and レフトフラグ==False:
        if key[pygame.K_SPACE] : #シュート
            ボール_rect.x = ボール_rect.x+bx*3
            b=b+1 #コスチューム変更
            シュートフラグ=True
            シュート.play()
        else: #ドリブル
            ドリブル.play()
            ボール_rect.x = ボール_rect.x +bx
            b=b+1 #コスチューム変更

    #ネコ1が上から衝突
    if ボール_rect.colliderect(ネコ1_rect) and アップフラグ==True:
        ボール_rect.y = ボール_rect.y -by
        b=b+1 #コスチューム変更
        
    #ネコ1が下から衝突
    if ボール_rect.colliderect(ネコ1_rect) and アップフラグ==False:
        ボール_rect.y = ボール_rect.y +by
        b=b+1 #コスチューム変更

    #ボール(シュート)の描画
    if シュートフラグ==True:
        if レフトフラグ==True:
            screen.blit(背景,(0,0,0,0))
            screen.blit(ボール4,ボール_rect)
            screen.blit(ネコ1リスト左[a%2],ネコ1_rect)
            screen.blit(ゴール1,ゴール1_rect)
            screen.blit(ゴール2,ゴール2_rect)
            screen.blit(文字1,(55,50))
            screen.blit(文字2,(355,50))
        else:
            screen.blit(背景,(0,0,0,0))
            screen.blit(ボール4,ボール_rect)
            screen.blit(ネコ1リスト右[a%2],ネコ1_rect)
            screen.blit(ゴール1,ゴール1_rect)
            screen.blit(ゴール2,ゴール2_rect)
            screen.blit(文字1,(55,50))
            screen.blit(文字2,(355,50))
    elif シュートフラグ==False:
        if レフトフラグ==True:
            screen.blit(背景,(0,0,0,0))
            screen.blit(ボールリスト[b%3],ボール_rect)
            screen.blit(ネコ1リスト左[a%2],ネコ1_rect)
            screen.blit(ゴール1,ゴール1_rect)
            screen.blit(ゴール2,ゴール2_rect)
            screen.blit(文字1,(55,50))
            screen.blit(文字2,(355,50))
        else:
            screen.blit(背景,(0,0,0,0))
            screen.blit(ボールリスト[b%3],ボール_rect)
            screen.blit(ネコ1リスト右[a%2],ネコ1_rect)
            screen.blit(ゴール1,ゴール1_rect)
            screen.blit(ゴール2,ゴール2_rect)
            screen.blit(文字1,(55,50))
            screen.blit(文字2,(355,50))

    #ボールの形が戻る時間の調整用
    if n%60==0:
        シュートフラグ=False

    #ボールとネコ1が壁にぶつかったときの処理
    if ボール_rect.collidelist(壁) !=-1:
        ボール_rect.x=314
        ボール_rect.y=210
    elif ネコ1_rect.collidelist(壁) !=-1:
        ネコ1_rect.x = ネコ1_rect.x -cx 
        ネコ1_rect.y = ネコ1_rect.y -cy
        
    #ボールとゴール1の衝突
    if ゴール1_rect.colliderect(ボール_rect):
        if ゴール1フラグ==False and シュートフラグ==False:
            得点2=得点2+1
            ゴール1フラグ=True
            ボール_rect.x=314 #ボールを元の位置に戻す
            ボール_rect.y=210 #ボールを元の位置に戻す
            ネコ1_rect.x=280 #オレンジネコを元の位置に戻す
            ネコ1_rect.y=180 #オレンジネコを元の位置に戻す
            青ネコ1_rect.x=340 #青ネコを元の位置に戻す
            青ネコ1_rect.y=180 #青ネコを元の位置に戻す
            ゴール.play() #ゴール音を鳴らす
            time.sleep(2) #2秒待つ
            レフトフラグ=False #オレンジネコを左向きにする
        else:
           ゴール1フラグ=False

    #ボールとゴール2の衝突
    if ゴール2_rect.colliderect(ボール_rect):
        if ゴール2フラグ==False and シュートフラグ==False:
            得点1=得点1+1
            ゴール2フラグ=True
            ボール_rect.x=314
            ボール_rect.y=210
            ネコ1_rect.x=280 #オレンジネコを元の位置に戻す
            ネコ1_rect.y=180 #オレンジネコを元の位置に戻す
            青ネコ1_rect.x=340 #青ネコを元の位置に戻す
            青ネコ1_rect.y=180 #青ネコを元の位置に戻す
            time.sleep(2) #2秒待つ
            ゴール.play() #ゴール音を鳴らす
            レフトフラグ=False #オレンジネコを左向きにする
        else:
            ゴール2フラグ=False

def 青ネコ処理():
    global c
    c=c+1
    ax=0
    ay=0
    #ボールを追いかける処理
    if 青ネコ1_rect.x < ボール_rect.x:
        ax=1
    else:
        ax=-1
    if 青ネコ1_rect.y < ボール_rect.y:
        ay=1
    else:
        ay=-1
    青ネコ1_rect.x=青ネコ1_rect.x+ax
    青ネコ1_rect.y=青ネコ1_rect.y+ay
    
    #青ネコの向き
    if  ax>0:
        screen.blit(青ネコ1リスト右[c%2],青ネコ1_rect)
    else:
        screen.blit(青ネコ1リスト左[c%2],青ネコ1_rect)

    #青ネコ1がボールと衝突
    if ボール_rect.colliderect(青ネコ1_rect):
        ボール_rect.x = ボール_rect.x-random.randint(1,5)
        ボール_rect.y = ボール_rect.y-random.randint(-20,20)

#終了処理(画面を閉じるボタンで閉じる処理)
def 終了():
    ホイッスル.play() #終了のホイッスル
    screen.blit(エンディング,(0,0,0,0)) #エンディング画面表示
    文字1 = font.render("ポコニャンズ:"+str(得点1)+"点",True,"orange") #得点更新用
    文字2 = font.render("にゃんこFC:"+str(得点2)+"点",True,"blue") #得点更新用
    screen.blit(文字1,(55,50)) #得点更新用
    screen.blit(文字2,(355,50)) #得点更新用
    pygame.display.update() #得点更新用
    while True:#メイン処理のbreak後に閉じるボタンで閉じるための処理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

#ループ
while True:
    main_proc()
    青ネコ処理()
    #ディスプレイのアップデート
    pygame.display.update()
    pygame.time.Clock().tick(150)
    #終了処理
    if 得点1==5 or 得点2==5:
            終了() #閉じるボタンで閉じれるように関数を実行
            break
    #閉じるボタンの処理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()