Python+Pygame编写一个Pong游戏
Leleprogrammer 人气:0前言
这次,我们要用Pygame写一个Pong游戏
先看看效果:
需要的模块:Pygame
在python文件同目录下新建resources文件夹,在文件夹中新建Pong文件夹,文件夹中放入两个音频文件
代码教学
导入需要的模块
import pygame from pygame.locals import * import random import sys
定义常量
COUNTDOWN=USEREVENT+1 path="resources/Pong/"
定义Class类,初始化函数内的代码:
pygame.init() self.screen=pygame.display.set_mode((750,800)) pygame.display.set_caption("Pong") self.mode="welcome" self.ball=None self.xspeed=0 self.yspeed=0 self.r=0 self.p1=None self.p2=None self.p1y=0 self.p2y=0 self.boardWidth=0 self.boardHeight=0 self.countdown=0 self.p1score=0 self.p2score=0 self.ballr=None self.min=2 self.max=7 self.win=11 self.matchpoint=0 self.boardSpeed=self.max self.ding=pygame.mixer.Sound(path+"ding.mp3") self.bo=pygame.mixer.Sound(path+"bo.mp3")
定义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=[750/2,800/2] self.r=10 self.p1y=100 self.p2y=100 self.boardWidth=10 self.boardHeight=100 self.countdown=5 self.p1score=0 self.p2score=0 self.ballr=Rect(100,100,1,1) pygame.time.set_timer(COUNTDOWN,1000) elif event.type==COUNTDOWN: self.countdown-=1 if self.countdown==0: self.countdown=0 pygame.time.set_timer(COUNTDOWN,0) self.xspeed=random.randint(self.min,self.max) if random.randint(0,1)==0 else random.randint(-self.max,-self.min) self.yspeed=random.randint(self.min,self.max) if random.randint(0,1)==0 else random.randint(-self.max,-self.min) else: self.ding.play()
定义draw函数,用于屏幕显示,进入游戏时的ui:
if self.mode=="welcome": self.screen.fill((0,0,0)) ts=[ "Welcome to Pong", "This game needs 2 players", "Press K to start" ] y=100 for t in ts: to=self.print_text("simhei",35,t,(255,255,255)) self.screen.blit(to,(100,y)) y+=40
开始游戏后:
elif self.mode=="playing": self.screen.fill((0,0,0)) self.p1=pygame.draw.rect(self.screen,(255,255,255),(0,self.p1y,self.boardWidth,self.boardHeight)) self.p2=pygame.draw.rect(self.screen,(255,255,255),(750-self.boardWidth,self.p2y,self.boardWidth,self.boardHeight)) to=self.print_text("simhei",20,"Press WS to move",(255,255,255)) to2=self.print_text("simhei",20,"Press ↑↓ to move",(255,255,255)) tor=to.get_rect() tor2=to2.get_rect() d=10 tor.bottomleft=d,800-d tor2.bottomright=750-d,800-d self.screen.blit(to,tor) self.screen.blit(to2,tor2) to=self.print_text("simhei",20,"Match Point!",(255,255,255)) if self.matchpoint==1: self.screen.blit(to,(10,10)) elif self.matchpoint==2: tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) elif self.matchpoint==11: pygame.time.set_timer(COUNTDOWN,0) to=self.print_text("simhei",20,"Win!",(255,255,255)) self.screen.blit(to,(10,10)) to=self.print_text("simhei",20,"Lose!",(255,255,255)) tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) elif self.matchpoint==22: pygame.time.set_timer(COUNTDOWN,0) to=self.print_text("simhei",20,"Lose!",(255,255,255)) self.screen.blit(to,(10,10)) to=self.print_text("simhei",20,"Win!",(255,255,255)) tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) if not (self.matchpoint==11 or self.matchpoint==22): self.move() if not self.countdown: pygame.draw.line(self.screen,(255,255,255),(750/2,0),(750/2,800),5) else: to=self.print_text("simhei",72,str(self.countdown),(255,255,255)) tor=to.get_rect() tor.midtop=750/2,50 self.screen.blit(to,tor) to=self.print_text("simhei",150,str(self.p1score),(255,255,255)) to2=self.print_text("simhei",150,str(self.p2score),(255,255,255)) tor=to.get_rect() tor2=to2.get_rect() tor.midtop=750/2/2,50 tor2.midtop=750/2+750/2/2,50 self.screen.blit(to,tor) self.screen.blit(to2,tor2) self.ballr=pygame.draw.circle(self.screen,(255,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.p1) or self.ballr.colliderect(self.p2))): self.ball[0]+=self.xspeed self.ball[1]+=self.yspeed if self.ball[0]-self.r<=0: self.p2score+=1 self.countdown=3 self.ballr=Rect(100,100,1,1) self.ball=[750/2,800/2] pygame.time.set_timer(COUNTDOWN,1000) if self.ball[0]+self.r>=750: self.p1score+=1 self.countdown=3 self.ballr=Rect(100,100,1,1) self.ball=[750/2,800/2] pygame.time.set_timer(COUNTDOWN,1000) if self.ball[1]-self.r<=0 or self.ball[1]+self.r>=800: self.yspeed=-self.yspeed if self.yspeed<0: 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.p1) or self.ballr.colliderect(self.p2): self.xspeed=-self.xspeed if self.xspeed<0: self.xspeed=random.randint(-self.max,-self.min) else: self.xspeed=random.randint(self.min,self.max) self.bo.play() self.ball[0]+=self.xspeed*2 key=pygame.key.get_pressed() if key[K_w]: self.p1y-=self.boardSpeed if key[K_s]: self.p1y+=self.boardSpeed if key[K_UP]: self.p2y-=self.boardSpeed if key[K_DOWN]: self.p2y+=self.boardSpeed if self.p1y<=0: self.p1y=0 if self.p2y<=0: self.p2y=0 if self.p1y+self.boardHeight>=800: self.p1y=800-self.boardHeight if self.p2y+self.boardHeight>=800: self.p2y=800-self.boardHeight
再定义一个函数,用于检查是否有玩家已经到达赛点
def checkMatchPoint(self): self.matchpoint=0 if self.p1score==self.win: self.matchpoint=11 if self.p2score==self.win: self.matchpoint=22 if self.p1score+1==self.win: self.matchpoint=1 if self.p2score+1==self.win: self.matchpoint=2 if self.p1score+1==self.win and self.p2score+1==self.win: self.win+=1
定义用于进入游戏主循环的函数run
def run(self): clock=pygame.time.Clock() while True: clock.tick(60) self.listen() if not (self.matchpoint==11 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+1 path="resources/Pong/" class Game: def __init__(self): pygame.init() self.screen=pygame.display.set_mode((750,800)) pygame.display.set_caption("Pong") self.mode="welcome" self.ball=None self.xspeed=0 self.yspeed=0 self.r=0 self.p1=None self.p2=None self.p1y=0 self.p2y=0 self.boardWidth=0 self.boardHeight=0 self.countdown=0 self.p1score=0 self.p2score=0 self.ballr=None self.min=2 self.max=7 self.win=11 self.matchpoint=0 self.boardSpeed=self.max self.ding=pygame.mixer.Sound(path+"ding.mp3") self.bo=pygame.mixer.Sound(path+"bo.mp3") 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=[750/2,800/2] self.r=10 self.p1y=100 self.p2y=100 self.boardWidth=10 self.boardHeight=100 self.countdown=5 self.p1score=0 self.p2score=0 self.ballr=Rect(100,100,1,1) pygame.time.set_timer(COUNTDOWN,1000) elif event.type==COUNTDOWN: self.countdown-=1 if self.countdown==0: self.countdown=0 pygame.time.set_timer(COUNTDOWN,0) self.xspeed=random.randint(self.min,self.max) if random.randint(0,1)==0 else random.randint(-self.max,-self.min) self.yspeed=random.randint(self.min,self.max) if random.randint(0,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,0)) ts=[ "Welcome to Pong", "This game needs 2 players", "Press K to start" ] y=100 for t in ts: to=self.print_text("simhei",35,t,(255,255,255)) self.screen.blit(to,(100,y)) y+=40 elif self.mode=="playing": self.screen.fill((0,0,0)) self.p1=pygame.draw.rect(self.screen,(255,255,255),(0,self.p1y,self.boardWidth,self.boardHeight)) self.p2=pygame.draw.rect(self.screen,(255,255,255),(750-self.boardWidth,self.p2y,self.boardWidth,self.boardHeight)) to=self.print_text("simhei",20,"Press WS to move",(255,255,255)) to2=self.print_text("simhei",20,"Press ↑↓ to move",(255,255,255)) tor=to.get_rect() tor2=to2.get_rect() d=10 tor.bottomleft=d,800-d tor2.bottomright=750-d,800-d self.screen.blit(to,tor) self.screen.blit(to2,tor2) to=self.print_text("simhei",20,"Match Point!",(255,255,255)) if self.matchpoint==1: self.screen.blit(to,(10,10)) elif self.matchpoint==2: tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) elif self.matchpoint==11: pygame.time.set_timer(COUNTDOWN,0) to=self.print_text("simhei",20,"Win!",(255,255,255)) self.screen.blit(to,(10,10)) to=self.print_text("simhei",20,"Lose!",(255,255,255)) tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) elif self.matchpoint==22: pygame.time.set_timer(COUNTDOWN,0) to=self.print_text("simhei",20,"Lose!",(255,255,255)) self.screen.blit(to,(10,10)) to=self.print_text("simhei",20,"Win!",(255,255,255)) tor=to.get_rect() tor.topright=750-10,10 self.screen.blit(to,tor) if not (self.matchpoint==11 or self.matchpoint==22): self.move() if not self.countdown: pygame.draw.line(self.screen,(255,255,255),(750/2,0),(750/2,800),5) else: to=self.print_text("simhei",72,str(self.countdown),(255,255,255)) tor=to.get_rect() tor.midtop=750/2,50 self.screen.blit(to,tor) to=self.print_text("simhei",150,str(self.p1score),(255,255,255)) to2=self.print_text("simhei",150,str(self.p2score),(255,255,255)) tor=to.get_rect() tor2=to2.get_rect() tor.midtop=750/2/2,50 tor2.midtop=750/2+750/2/2,50 self.screen.blit(to,tor) self.screen.blit(to2,tor2) self.ballr=pygame.draw.circle(self.screen,(255,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.p1) or self.ballr.colliderect(self.p2))): self.ball[0]+=self.xspeed self.ball[1]+=self.yspeed if self.ball[0]-self.r<=0: self.p2score+=1 self.countdown=3 self.ballr=Rect(100,100,1,1) self.ball=[750/2,800/2] pygame.time.set_timer(COUNTDOWN,1000) if self.ball[0]+self.r>=750: self.p1score+=1 self.countdown=3 self.ballr=Rect(100,100,1,1) self.ball=[750/2,800/2] pygame.time.set_timer(COUNTDOWN,1000) if self.ball[1]-self.r<=0 or self.ball[1]+self.r>=800: self.yspeed=-self.yspeed if self.yspeed<0: 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.p1) or self.ballr.colliderect(self.p2): self.xspeed=-self.xspeed if self.xspeed<0: self.xspeed=random.randint(-self.max,-self.min) else: self.xspeed=random.randint(self.min,self.max) self.bo.play() self.ball[0]+=self.xspeed*2 key=pygame.key.get_pressed() if key[K_w]: self.p1y-=self.boardSpeed if key[K_s]: self.p1y+=self.boardSpeed if key[K_UP]: self.p2y-=self.boardSpeed if key[K_DOWN]: self.p2y+=self.boardSpeed if self.p1y<=0: self.p1y=0 if self.p2y<=0: self.p2y=0 if self.p1y+self.boardHeight>=800: self.p1y=800-self.boardHeight if self.p2y+self.boardHeight>=800: self.p2y=800-self.boardHeight def checkMatchPoint(self): self.matchpoint=0 if self.p1score==self.win: self.matchpoint=11 if self.p2score==self.win: self.matchpoint=22 if self.p1score+1==self.win: self.matchpoint=1 if self.p2score+1==self.win: self.matchpoint=2 if self.p1score+1==self.win and self.p2score+1==self.win: self.win+=1 def run(self): clock=pygame.time.Clock() while True: clock.tick(60) self.listen() if not (self.matchpoint==11 or self.matchpoint==22): self.checkMatchPoint() self.draw() pygame.display.update() game=Game() game.run()
加载全部内容