目录
- 前言
- 代码教学
- 最终代码
前言
这次,我们要用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()