python
主页 > 脚本 > python >

Python+Pygame编写一个Pong游戏

2023-01-07 | 秩名 | 点击:

这次,我们要用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()

原文链接:https://blog.csdn.net/leleprogrammer/article/details/124227987
相关文章
最新更新