Python+Pygame编写一个Pong游戏

Python
274
0
0
2023-07-17
标签   Python游戏
目录
  • 前言
  • 代码教学
  • 最终代码

前言

这次,我们要用Pygame写一个Pong游戏

先看看效果:

需要的模块:Pygame

在python文件同目录下新建resources文件夹,在文件夹中新建Pong文件夹,文件夹中放入两个音频文件

代码教学

导入需要的模块

import pygame
from pygame.locals import *
import random
import sys

定义常量

COUNTDOWN=USEREVENT+
path="resources/Pong/"

定义Class类,初始化函数内的代码:

pygame.init()
self.screen=pygame.display.set_mode((,800))
pygame.display.set_caption("Pong")
 
self.mode="welcome"
self.ball=None
self.xspeed=
self.yspeed=
self.r=
self.p=None
self.p=None
self.py=0
self.py=0
self.boardWidth=
self.boardHeight=
self.countdown=
self.pscore=0
self.pscore=0
self.ballr=None
self.min=
self.max=
self.win=
self.matchpoint=
self.boardSpeed=self.max
self.ding=pygame.mixer.Sound(path+"ding.mp")
self.bo=pygame.mixer.Sound(path+"bo.mp")

定义listen函数

def listen(self):
    for event in pygame.event.get():
        if event.type==QUIT:
            sys.exit()
        elif event.type==KEYDOWN:
            if event.key==K_k and self.mode=="welcome":
                self.mode="playing"
                self.ball=[/2,800/2]
                self.r=
                self.py=100
                self.py=100
                self.boardWidth=
                self.boardHeight=
                self.countdown=
                self.pscore=0
                self.pscore=0
                self.ballr=Rect(,100,1,1)
                pygame.time.set_timer(COUNTDOWN,)
        elif event.type==COUNTDOWN:
            self.countdown-=
            if self.countdown==:
                self.countdown=
                pygame.time.set_timer(COUNTDOWN,)
                self.xspeed=random.randint(self.min,self.max) if random.randint(,1)==0 else random.randint(-self.max,-self.min)
                self.yspeed=random.randint(self.min,self.max) if random.randint(,1)==0 else random.randint(-self.max,-self.min)
            else:
                self.ding.play()

 定义draw函数,用于屏幕显示,进入游戏时的ui:

if self.mode=="welcome":
    self.screen.fill((,0,0))
    ts=[
        "Welcome to Pong",
        "This game needs players",
        "Press K to start"
    ]
    y=
    for t in ts:
        to=self.print_text("simhei",,t,(255,255,255))
        self.screen.blit(to,(,y))
        y+=

开始游戏后:

elif self.mode=="playing":
    self.screen.fill((,0,0))
    self.p=pygame.draw.rect(self.screen,(255,255,255),(0,self.p1y,self.boardWidth,self.boardHeight))
    self.p=pygame.draw.rect(self.screen,(255,255,255),(750-self.boardWidth,self.p2y,self.boardWidth,self.boardHeight))
    to=self.print_text("simhei",,"Press WS to move",(255,255,255))
    to=self.print_text("simhei",20,"Press ↑↓ to move",(255,255,255))
    tor=to.get_rect()
    tor=to2.get_rect()
    d=
    tor.bottomleft=d,-d
    tor.bottomright=750-d,800-d
    self.screen.blit(to,tor)
    self.screen.blit(to,tor2)
    to=self.print_text("simhei",,"Match Point!",(255,255,255))
    if self.matchpoint==:
        self.screen.blit(to,(,10))
    elif self.matchpoint==:
        tor=to.get_rect()
        tor.topright=-10,10
        self.screen.blit(to,tor)
    elif self.matchpoint==:
        pygame.time.set_timer(COUNTDOWN,)
        to=self.print_text("simhei",,"Win!",(255,255,255))
        self.screen.blit(to,(,10))
        to=self.print_text("simhei",,"Lose!",(255,255,255))
        tor=to.get_rect()
        tor.topright=-10,10
        self.screen.blit(to,tor)
    elif self.matchpoint==:
        pygame.time.set_timer(COUNTDOWN,)
        to=self.print_text("simhei",,"Lose!",(255,255,255))
        self.screen.blit(to,(,10))
        to=self.print_text("simhei",,"Win!",(255,255,255))
        tor=to.get_rect()
        tor.topright=-10,10
        self.screen.blit(to,tor)
    if not (self.matchpoint== or self.matchpoint==22):
        self.move()
        if not self.countdown:
            pygame.draw.line(self.screen,(,255,255),(750/2,0),(750/2,800),5)
        else:
            to=self.print_text("simhei",,str(self.countdown),(255,255,255))
            tor=to.get_rect()
            tor.midtop=/2,50
            self.screen.blit(to,tor)
    to=self.print_text("simhei",,str(self.p1score),(255,255,255))
    to=self.print_text("simhei",150,str(self.p2score),(255,255,255))
    tor=to.get_rect()
    tor=to2.get_rect()
    tor.midtop=/2/2,50
    tor.midtop=750/2+750/2/2,50
    self.screen.blit(to,tor)
    self.screen.blit(to,tor2)
    self.ballr=pygame.draw.circle(self.screen,(,255,255),tuple(self.ball),self.r)

这里,为了可以显示文字,我们自己写一个print_text函数,用于显示文字

@staticmethod
def print_text(name,size,text,color):
    font=pygame.font.SysFont(name,size)
    image=font.render(text,True,color)
    return image

定义一个move函数,用于移动小球和两个玩家的“板”

def move(self):
    if (not self.countdown) and (not (self.ballr.colliderect(self.p) or self.ballr.colliderect(self.p2))):
        self.ball[]+=self.xspeed
        self.ball[]+=self.yspeed
        if self.ball[]-self.r<=0:
            self.pscore+=1
            self.countdown=
            self.ballr=Rect(,100,1,1)
            self.ball=[/2,800/2]
            pygame.time.set_timer(COUNTDOWN,)
        if self.ball[]+self.r>=750:
            self.pscore+=1
            self.countdown=
            self.ballr=Rect(,100,1,1)
            self.ball=[/2,800/2]
            pygame.time.set_timer(COUNTDOWN,)
        if self.ball[]-self.r<=0 or self.ball[1]+self.r>=800:
            self.yspeed=-self.yspeed
            if self.yspeed<:
                self.yspeed=random.randint(-self.max,-self.min)
            else:
                self.yspeed=random.randint(self.min,self.max)
            self.bo.play()
    elif self.ballr.colliderect(self.p) or self.ballr.colliderect(self.p2):
        self.xspeed=-self.xspeed
        if self.xspeed<:
            self.xspeed=random.randint(-self.max,-self.min)
        else:
            self.xspeed=random.randint(self.min,self.max)
        self.bo.play()
        self.ball[]+=self.xspeed*2
    key=pygame.key.get_pressed()
    if key[K_w]:
        self.py-=self.boardSpeed
    if key[K_s]:
        self.py+=self.boardSpeed
    if key[K_UP]:
        self.py-=self.boardSpeed
    if key[K_DOWN]:
        self.py+=self.boardSpeed
    if self.py<=0:
        self.py=0
    if self.py<=0:
        self.py=0
    if self.py+self.boardHeight>=800:
        self.py=800-self.boardHeight
    if self.py+self.boardHeight>=800:
        self.py=800-self.boardHeight

再定义一个函数,用于检查是否有玩家已经到达赛点

def checkMatchPoint(self):
    self.matchpoint=
    if self.pscore==self.win:
        self.matchpoint=
    if self.pscore==self.win:
        self.matchpoint=
    if self.pscore+1==self.win:
        self.matchpoint=
    if self.pscore+1==self.win:
        self.matchpoint=
    if self.pscore+1==self.win and self.p2score+1==self.win:
        self.win+=

定义用于进入游戏主循环的函数run

def run(self):
    clock=pygame.time.Clock()
    while True:
        clock.tick()
        self.listen()
        if not (self.matchpoint== or self.matchpoint==22):
            self.checkMatchPoint()
        self.draw()
        pygame.display.update()

在类的外面,创建game对象,并进入游戏主循环

game=Game()
game.run()

最终代码

import pygame
from pygame.locals import *
import random
import sys
 
COUNTDOWN=USEREVENT+
path="resources/Pong/"
 
class Game:
    def __init__(self):
        pygame.init()
        self.screen=pygame.display.set_mode((,800))
        pygame.display.set_caption("Pong")
 
        self.mode="welcome"
        self.ball=None
        self.xspeed=
        self.yspeed=
        self.r=
        self.p=None
        self.p=None
        self.py=0
        self.py=0
        self.boardWidth=
        self.boardHeight=
        self.countdown=
        self.pscore=0
        self.pscore=0
        self.ballr=None
        self.min=
        self.max=
        self.win=
        self.matchpoint=
        self.boardSpeed=self.max
        self.ding=pygame.mixer.Sound(path+"ding.mp")
        self.bo=pygame.mixer.Sound(path+"bo.mp")
 
    def listen(self):
        for event in pygame.event.get():
            if event.type==QUIT:
                sys.exit()
            elif event.type==KEYDOWN:
                if event.key==K_k and self.mode=="welcome":
                    self.mode="playing"
                    self.ball=[/2,800/2]
                    self.r=
                    self.py=100
                    self.py=100
                    self.boardWidth=
                    self.boardHeight=
                    self.countdown=
                    self.pscore=0
                    self.pscore=0
                    self.ballr=Rect(,100,1,1)
                    pygame.time.set_timer(COUNTDOWN,)
            elif event.type==COUNTDOWN:
                self.countdown-=
                if self.countdown==:
                    self.countdown=
                    pygame.time.set_timer(COUNTDOWN,)
                    self.xspeed=random.randint(self.min,self.max) if random.randint(,1)==0 else random.randint(-self.max,-self.min)
                    self.yspeed=random.randint(self.min,self.max) if random.randint(,1)==0 else random.randint(-self.max,-self.min)
                else:
                    self.ding.play()
 
    def draw(self):
        if self.mode=="welcome":
            self.screen.fill((,0,0))
            ts=[
                "Welcome to Pong",
                "This game needs players",
                "Press K to start"
            ]
            y=
            for t in ts:
                to=self.print_text("simhei",,t,(255,255,255))
                self.screen.blit(to,(,y))
                y+=
        elif self.mode=="playing":
            self.screen.fill((,0,0))
            self.p=pygame.draw.rect(self.screen,(255,255,255),(0,self.p1y,self.boardWidth,self.boardHeight))
            self.p=pygame.draw.rect(self.screen,(255,255,255),(750-self.boardWidth,self.p2y,self.boardWidth,self.boardHeight))
            to=self.print_text("simhei",,"Press WS to move",(255,255,255))
            to=self.print_text("simhei",20,"Press ↑↓ to move",(255,255,255))
            tor=to.get_rect()
            tor=to2.get_rect()
            d=
            tor.bottomleft=d,-d
            tor.bottomright=750-d,800-d
            self.screen.blit(to,tor)
            self.screen.blit(to,tor2)
            to=self.print_text("simhei",,"Match Point!",(255,255,255))
            if self.matchpoint==:
                self.screen.blit(to,(,10))
            elif self.matchpoint==:
                tor=to.get_rect()
                tor.topright=-10,10
                self.screen.blit(to,tor)
            elif self.matchpoint==:
                pygame.time.set_timer(COUNTDOWN,)
                to=self.print_text("simhei",,"Win!",(255,255,255))
                self.screen.blit(to,(,10))
                to=self.print_text("simhei",,"Lose!",(255,255,255))
                tor=to.get_rect()
                tor.topright=-10,10
                self.screen.blit(to,tor)
            elif self.matchpoint==:
                pygame.time.set_timer(COUNTDOWN,)
                to=self.print_text("simhei",,"Lose!",(255,255,255))
                self.screen.blit(to,(,10))
                to=self.print_text("simhei",,"Win!",(255,255,255))
                tor=to.get_rect()
                tor.topright=-10,10
                self.screen.blit(to,tor)
            if not (self.matchpoint== or self.matchpoint==22):
                self.move()
                if not self.countdown:
                    pygame.draw.line(self.screen,(,255,255),(750/2,0),(750/2,800),5)
                else:
                    to=self.print_text("simhei",,str(self.countdown),(255,255,255))
                    tor=to.get_rect()
                    tor.midtop=/2,50
                    self.screen.blit(to,tor)
            to=self.print_text("simhei",,str(self.p1score),(255,255,255))
            to=self.print_text("simhei",150,str(self.p2score),(255,255,255))
            tor=to.get_rect()
            tor=to2.get_rect()
            tor.midtop=/2/2,50
            tor.midtop=750/2+750/2/2,50
            self.screen.blit(to,tor)
            self.screen.blit(to,tor2)
            self.ballr=pygame.draw.circle(self.screen,(,255,255),tuple(self.ball),self.r)
 
    @staticmethod
    def print_text(name,size,text,color):
        font=pygame.font.SysFont(name,size)
        image=font.render(text,True,color)
        return image
 
    def move(self):
        if (not self.countdown) and (not (self.ballr.colliderect(self.p) or self.ballr.colliderect(self.p2))):
            self.ball[]+=self.xspeed
            self.ball[]+=self.yspeed
            if self.ball[]-self.r<=0:
                self.pscore+=1
                self.countdown=
                self.ballr=Rect(,100,1,1)
                self.ball=[/2,800/2]
                pygame.time.set_timer(COUNTDOWN,)
            if self.ball[]+self.r>=750:
                self.pscore+=1
                self.countdown=
                self.ballr=Rect(,100,1,1)
                self.ball=[/2,800/2]
                pygame.time.set_timer(COUNTDOWN,)
            if self.ball[]-self.r<=0 or self.ball[1]+self.r>=800:
                self.yspeed=-self.yspeed
                if self.yspeed<:
                    self.yspeed=random.randint(-self.max,-self.min)
                else:
                    self.yspeed=random.randint(self.min,self.max)
                self.bo.play()
        elif self.ballr.colliderect(self.p) or self.ballr.colliderect(self.p2):
            self.xspeed=-self.xspeed
            if self.xspeed<:
                self.xspeed=random.randint(-self.max,-self.min)
            else:
                self.xspeed=random.randint(self.min,self.max)
            self.bo.play()
            self.ball[]+=self.xspeed*2
        key=pygame.key.get_pressed()
        if key[K_w]:
            self.py-=self.boardSpeed
        if key[K_s]:
            self.py+=self.boardSpeed
        if key[K_UP]:
            self.py-=self.boardSpeed
        if key[K_DOWN]:
            self.py+=self.boardSpeed
        if self.py<=0:
            self.py=0
        if self.py<=0:
            self.py=0
        if self.py+self.boardHeight>=800:
            self.py=800-self.boardHeight
        if self.py+self.boardHeight>=800:
            self.py=800-self.boardHeight
 
    def checkMatchPoint(self):
        self.matchpoint=
        if self.pscore==self.win:
            self.matchpoint=
        if self.pscore==self.win:
            self.matchpoint=
        if self.pscore+1==self.win:
            self.matchpoint=
        if self.pscore+1==self.win:
            self.matchpoint=
        if self.pscore+1==self.win and self.p2score+1==self.win:
            self.win+=
 
    def run(self):
        clock=pygame.time.Clock()
        while True:
            clock.tick()
            self.listen()
            if not (self.matchpoint== or self.matchpoint==22):
                self.checkMatchPoint()
            self.draw()
            pygame.display.update()
 
game=Game()
game.run()