这次,我们要用Pygame写一个Pong游戏
先看看效果:
需要的模块:Pygame
在python文件同目录下新建resources文件夹,在文件夹中新建Pong文件夹,文件夹中放入两个音频文件
导入需要的模块
1 2 3 4 |
import pygame from pygame.locals import * import random import sys |
定义常量
1 2 |
COUNTDOWN=USEREVENT+1 path="resources/Pong/" |
定义Class类,初始化函数内的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 |
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 |
开始游戏后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
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函数,用于显示文字
1 2 3 4 5 |
@staticmethod def print_text(name,size,text,color): font=pygame.font.SysFont(name,size) image=font.render(text,True,color) return image |
定义一个move函数,用于移动小球和两个玩家的“板”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
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 |
再定义一个函数,用于检查是否有玩家已经到达赛点
1 2 3 4 5 6 7 8 9 10 11 12 |
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
1 2 3 4 5 6 7 8 9 |
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对象,并进入游戏主循环
1 2 |
game=Game() game.run() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
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() |