脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python使用pygame模块实现坦克大战游戏

python使用pygame模块实现坦克大战游戏

2021-06-27 00:28CO-MI Python

这篇文章主要为大家详细介绍了python使用pygame模块实现坦克大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了pygame模块实现坦克大战游戏的具体代码,供大家参考,具体内容如下

首先,第一步,游戏简单素材的准备。

python使用pygame模块实现坦克大战游戏炮弹,python使用pygame模块实现坦克大战游戏python使用pygame模块实现坦克大战游戏python使用pygame模块实现坦克大战游戏python使用pygame模块实现坦克大战游戏炮弹,坦克移动。音乐-开火素材。

其次,思路整理

我们需要几个类,分别是玩家类,敌人类,炮弹类及地图类,开始游戏界面以及结束界面,血条等等。

开始coding。

主函数,new一个对象(java乱入emmm),声明一个对象。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# encoding : utf-8
# anthor : comi
from gameloop import *
from pygame import *
import pygame,sys,time
 
if __name__ == '__main__':
  player = game()  # 声明一个类对象
  player.game_start('keep-going'# 调用开始函数
  while player.playing:  # 进入游戏运行
    player.new()  # 开始游戏
  player.screen.fill(black)
  player.game_start('game-over'# 游戏结束
  time.sleep(1.5# 可以不要

这里可以根据自己的需要进行更改相关代码

接下来 游戏的主循环

?
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
# encoding : utf-8
# author : comi
from setting import *
from pygame import *
from sprite import *
import pygame,sys
vec = pygame.math.vector2
 
 
class game:  # 游戏类 包含循环等
  def __init__(self):  # 初始化
    pygame.init()  # pygame 初始化
    pygame.display.set_caption("keep-going"# 游戏窗口 左上角名称
    self.screen = pygame.display.set_mode((width, height))  # 游戏窗口的大小
    self.fpsclock = pygame.time.clock()  # 设置游戏的刷新率
    self.playing = true  # 进入游戏的状态
    self.running = true  # 游戏运行的状态
    self.waiting = true  # 游戏等待的状态
    self.pblood = 100  # 玩家血量
    self.eblood = 100  # 敌人血量
    self.player = player()  # 声明一个游戏玩家对象
    self.enemy = enemy()  # 声明一个敌人对象
    self.all_groups = pygame.sprite.group()  #  通过pygame自带的 group 来判断碰撞检测
    self.player_groups = pygame.sprite.group()
    self.map_groups = pygame.sprite.group()
    self.enemy_groups = pygame.sprite.group()
 
  def new(self):  # 开始一个游戏
    self.player_groups.add(self.player)  # 将玩家添加到玩家组
    self.all_groups.add(self.player)  # 将玩家添加到 所有组
 
    self.enemy_groups.add(self.enemy)
    self.all_groups.add(self.enemy)
 
    for platfroms in map1:  # 地图
      p = platform(*platfroms)   # 取出所有值
      self.map_groups.add(p)
      self.all_groups.add(p)
 
    self.run()  # 调用函数运行游戏
 
  def game_start(self,text):   # 游戏的开始界面
    self.text_draw(width / 2, height / 4, 64, text) # 文本
    self.text_draw(width / 2, height * 3 / 4, 25,'press any key to continue',) # 文本
    pygame.display.update()  # 更行展示
    while self.waiting:  # 实现 按键等待开始效果
      for event in pygame.event.get():
        if event.type == pygame.quit:
          pygame.quit()
          sys.exit()
        if event.type == pygame.keydown: 
          self.waiting = false
 
  def update(self):  # 画面更新
    self.map_groups.update() 
    self.player_groups.update()
    self.enemy.bullet_groups.update(self.enemy.flag)  # 通过按键判断子弹方向
    self.player.bullet_groups.update(self.player.flag)
    self.enemy_groups.update()
 
    hit = pygame.sprite.groupcollide(self.player.bullet_groups, self.map_groups, true,false)  # 子弹碰墙消失
    hit = pygame.sprite.groupcollide(self.enemy.bullet_groups, self.map_groups, true, false)
 
    pmc = pygame.sprite.spritecollide(self.player,self.map_groups,false,false)   # 撞墙
    if pmc:
      key_pressed = pygame.key.get_pressed()
      if key_pressed[pygame.k_a]:
        self.player.pos.x = self.player.pos.x + gap
      if key_pressed[pygame.k_d]:
        self.player.pos.x = self.player.pos.x - gap
      if key_pressed[pygame.k_w]:
        self.player.pos.y = self.player.pos.y + gap
      if key_pressed[pygame.k_s]:
        self.player.pos.y = self.player.pos.y - gap
 
    emc = pygame.sprite.spritecollide(self.enemy,self.map_groups,false,false)    # 撞墙
    if emc:
      key_pressed = pygame.key.get_pressed()
      if key_pressed[pygame.k_left]:
        self.enemy.pos.x = self.enemy.pos.x + gap
      if key_pressed[pygame.k_right]:
        self.enemy.pos.x = self.enemy.pos.x - gap
      if key_pressed[pygame.k_up]:
        self.enemy.pos.y = self.enemy.pos.y + gap
      if key_pressed[pygame.k_down]:
        self.enemy.pos.y = self.enemy.pos.y - gap
 
  def run(self): 
    while self.running:
      self.fpsclock.tick(fps)  # 设置帧率
      self.events()  # 获取事件
      self.draw_pic()  # 画出图片
      self.update() 
 
      f self.eblood <= 0: # enemy 
        self.screen.fill(black)
        self.game_start('p1 win!')
        time.sleep(1.5)
        self.running = false
        self.playing = false
 
      if self.pblood <= 0: # player
        self.screen.fill(black)
        self.game_start('p2 win!')
        time.sleep(1.5)
        self.running = false
        self.playing = false
 
  def text_draw(self, x, y, size, text):  # 文本展示函数
    self.font = pygame.font.font('freesansbold.ttf', size)  # 字体,大小
    self.text_surf = self.font.render(text, true, red)  # 颜色
    self.text_rect = self.text_surf.get_rect()  # 矩形
    self.text_rect.center = (x, y)  # 位置
    self.screen.blit(self.text_surf, self.text_rect)  # 覆盖展示
 
  def draw_pic(self): 
    self.screen.fill(white)  # 背景
    self.text_draw(900,50,30,"keep"# 文本
    self.text_draw(900, 100, 30, "going")
 
    self.text_draw(820, 150, 20, "p1:")
    self.text_draw(820, 200, 20, "p2:")
    
    self.text_draw(900, 250, 20, "attention!")
    self.text_draw(900,300,20,"the bullet can")
    self.text_draw(900, 350, 20, "be control!")
    self.bar_draw(850, 145, self.pblood)  # 血条
    hit = pygame.sprite.groupcollide(self.enemy.bullet_groups, self.player_groups, true, false)  # 血条减少
    if hit:
      self.pblood = self.pblood - randint(10, 15)
      self.bar_draw(850, 145, self.pblood)
 
    self.bar_draw(850, 195, self.eblood)
    hit = pygame.sprite.groupcollide(self.player.bullet_groups, self.enemy_groups, true, false)
    if hit:
      self.eblood = self.eblood - randint(10, 15)
      self.bar_draw(850, 195, self.eblood)
 
    self.map_groups.draw(self.screen)  # 画出图片
    self.player_groups.draw(self.screen)
    self.enemy_groups.draw(self.screen)
    self.player.bullet_groups.draw(self.screen)
    self.enemy.bullet_groups.draw(self.screen)
 
    pygame.display.update() 
 
  def bar_draw(self, x, y, pct):  # 血条函数
    # draw a bar 
    if pct <= 0:
      pct = 0
    bar_lenth = 100
    bar_height = 10
    fill_lenth = (pct / 100) * bar_lenth
    out_rect = pygame.rect(x, y, bar_lenth, bar_height)
    fill_rect = pygame.rect(x, y, fill_lenth, bar_height)
    pygame.draw.rect(self.screen, green, fill_rect)
    pygame.draw.rect(self.screen, red, out_rect, 2)
 
  def events(self):  # 事件
    for events in pygame.event.get():
      if events.type == pygame.quit:
        self.running = false
        self.playing = false

在主循环内实现了很多功能,文本窗口展示,血条展示,以及整个游戏循环的定义都是可以拿来借鉴的,我也是从油管主上学来的。

接下来,精灵类,包含玩家,敌人。子弹,地图四部分。

?
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
# encoding : utf-8
# antuor : comi
from setting import *
from pygame import *
import pygame,sys,time
from random import *
from math import *
 
vec = pygame.math.vector2  # 运用向量
 
class player(pygame.sprite.sprite):  # 玩家类
  bullet_groups = pygame.sprite.group()
  flag = 1  # 判断方向的flag
  def __init__(self):
    pygame.sprite.sprite.__init__(self)
    self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert()  # 图片的加载
    self.image.set_colorkey(white)  # 设置忽略白色
    self.rect = self.image.get_rect()
    self.rect.midbottom = (115, 130
 
    self.pos = vec(115, 130)
 
    self.last_time = time.time()  #记录上一次时间 用来设置子弹频率等
 
  def update(self): 
    key_pressed = pygame.key.get_pressed()  # 按键获取
    if key_pressed[pygame.k_a]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\left.png').convert()
      self.image.set_colorkey(white)
      self.pos.x -= move_space  # 位置移动
      self.flag = 2
    if key_pressed[pygame.k_d]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\right.png').convert()
      self.image.set_colorkey(white)
      self.pos.x += move_space
      self.flag = 1
    if key_pressed[pygame.k_w]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\up.png').convert()
      self.image.set_colorkey(white)
      self.pos.y -= move_space
      self.flag = 3
    if key_pressed[pygame.k_s]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert()
      self.image.set_colorkey(white)
      self.pos.y += move_space
      self.flag = 4
    if key_pressed[pygame.k_space]:
      self.shoot()
    self.rect.midbottom = self.pos 
 
  def shoot(self):  # 开火
    self.now = time.time()  # 获取现在时间
    if self.now - self.last_time > 0.8# 子弹时间间隔
     # 这里显示错误了,应该在if 语句内 包含以下部分
   pygame.mixer.music.load(r'c:\users\administrator\desktop\keepgoing\sounds\expl.wav')
      pygame.mixer.music.play()  # 音乐加载
      bullet = bullet(self.pos.x, self.pos.y)
      self.bullet_groups.add(bullet) 
      self.last_time = self.now
 
 
class platform(pygame.sprite.sprite):  # 地图创建
  def __init__(self, x, y, w, h):  # x,y,宽,高
    pygame.sprite.sprite.__init__(self)
    self.image = pygame.surface((w, h)) # 砖块大小
    self.image.fill(yellow)  # 砖颜色
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y
 
 
class enemy(pygame.sprite.sprite):  # 与player 相同
  bullet_groups = pygame.sprite.group()
  flag = 1
  def __init__(self):
    pygame.sprite.sprite.__init__(self)
    self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert()
    self.image.set_colorkey(white)
    self.rect = self.image.get_rect()
    self.rect.midbottom = (315, 130)
    self.pos = vec(315, 130)
    self.bar = 100
    self.last_time = time.time()
    self.flag = 1
 
  def update(self):
    key_pressed = pygame.key.get_pressed()
    if key_pressed[pygame.k_left]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\left.png').convert()
      self.image.set_colorkey(white)
      self.pos.x -= move_space
      self.flag = 2
    if key_pressed[pygame.k_right]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\right.png').convert()
      self.image.set_colorkey(white)
      self.pos.x += move_space
      self.flag = 1
    if key_pressed[pygame.k_up]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\up.png').convert()
      self.image.set_colorkey(white)
      self.pos.y -= move_space
      self.flag = 3
    if key_pressed[pygame.k_down]:
      self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert()
      self.image.set_colorkey(white)
      self.pos.y += move_space
      self.flag = 4
    if key_pressed[pygame.k_p]:
      self.shoot()
 
    self.rect.midbottom = self.pos
 
  def shoot(self):
    self.now = time.time()
    if self.now - self.last_time > 0.8:
      pygame.mixer.music.load(r'c:\users\administrator\desktop\keepgoing\sounds\expl.wav')
      pygame.mixer.music.play()
      bullet = bullet(self.pos.x, self.pos.y)
      self.bullet_groups.add(bullet)
      self.bullet_groups.update(self.flag)
      self.last_time = self.now
 
 
class bullet(pygame.sprite.sprite):  # 炮弹组
  def __init__(self, x, y):  # 炮弹该有的位置 玩家周围
    pygame.sprite.sprite.__init__(self)
    self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\dot.png ').convert()
    self.image.set_colorkey(white)
    self.rect = self.image.get_rect()
    self.rect.centerx = x + 10  # 这里是准确的位置,未进行准确更改
    self.rect.bottom = y - 12
    self.speed = 5
 
  def update(self,flag): 
    if flag == 1# right
      self.rect.x += self.speed
    if flag == 2# left
      self.rect.x -= self.speed
    if flag == 3#up
      self.rect.y -= self.speed
    if flag == 4# down
      self.rect.y += self.speed

最后,便是相关的设置文件了

?
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
# encoding : utf-8
# author :comi
width = 1000
height = 600
fps = 60
food = 20
gap = 3
move_space = 1.5
back_space = 5
map1 = [(0, 0, width*2, 10), (0, 10, 10, height * 2),
    (0, height-10, width * 2, 10), (width - 210, 0, 10, height * 2),
    (50,50,100,20),(250,50,100,20),(150,230,100,20),(100,340,200,20),
    (50, 70, 20, 90), (130, 70, 20, 90),(250,70,20,90),(330,70,20,90),
    (130,280,20,70),(250,300,20,50),
    (80,320,20,20),(300,320,20,20),(185,200,30,30),(185,250,30,30),
    (60,300,20,20),(320,300,20,20),
    (40,280,20,20),(340,280,20,20),
    (490,100,160,40),(650,100,40,200),(425,250,150,40),(425,290,40,80),
    (510,365,160,40),(695,460,95,40),(595,454,40,100),(190,460,30,30),
    (300,450,200,40),(100,425,30,130),(200,520,230,25),(725,70,30,30),
    (725,140,30,30),(725,210,30,30),(725,280,30,30),(725,365,30,30)
    # map
# color
 
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255,0)
blue = (0, 0, 255)
yellow = ( 255,200,0)
purple = (128,138,135)

这个坦克大战还有一些小的bug,比如说,当你按下space 开火是,第一发炮弹已经出去了,当你按下相反方向,子弹会按你第二次按下的方向移动。(不打算解决,开始学习游戏ai,和横板游戏的制作)

有想法的同学可以和我交流,欢迎大家留言。

最后,运行效果如下 ,双人操作 p1:w a s d space 开火 p2: 上 下左 右  p 开火

python使用pygame模块实现坦克大战游戏python使用pygame模块实现坦克大战游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_25233621/article/details/82382088

延伸 · 阅读

精彩推荐