开发思路
完整项目地址:https://github.com/371854496/...
觉得还ok的话,点下star,作者不易,thank you!
实现方法
1.引入需要的模块,配置图片路径,设置界面宽高背景颜色,创建游戏主入口。
python" id="highlighter_753017">
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
|
#1引入需要的模块
import pygame
import random
#1配置图片地址
image_path = 'imgs/'
#1设置页面宽高
scrrr_width = 800
scrrr_height = 560
#1创建控制游戏结束的状态
gameover = false
#1主程序
class maingame():
#1加载游戏窗口
def init_window( self ):
#1调用显示模块的初始化
pygame.display.init()
#1创建窗口
maingame.window = pygame.display.set_mode([scrrr_width,scrrr_height]) #
#1开始游戏
def start_game( self ):
#1初始化窗口
self .init_window()
#1只要游戏没结束,就一直循环
while not gameover:
#1渲染白色背景
maingame.window.fill(( 255 , 255 , 255 ))
#1实时更新
pygame.display.update()
#1启动主程序
if __name__ = = '__main__' :
game = maingame()
game.start_game()
|
2.文本绘制,创建要动态改变的属性,渲染的位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#2 创建关数,得分,剩余分数,钱数
shaoguan = 1
score = 0
remnant_score = 100
money = 200
#2 文本绘制
def draw_text( self , content, size, color):
pygame.font.init()
font = pygame.font.sysfont( 'kaiti' , size)
text = font.render(content, true, color)
return text
#2 加载帮助提示
def load_help_text( self ):
text1 = self .draw_text( '1.按左键创建向日葵 2.按右键创建豌豆射手' , 26 , ( 255 , 0 , 0 ))
maingame.window.blit(text1, ( 5 , 5 ))
#2 渲染的文字和坐标位置
maingame.window.blit( self .draw_text( '当前钱数$: {}' . format (maingame.money), 26 , ( 255 , 0 , 0 )), ( 500 , 40 ))
maingame.window.blit( self .draw_text(
'当前关数{},得分{},距离下关还差{}分' . format (maingame.shaoguan, maingame.score, maingame.remnant_score), 26 ,
( 255 , 0 , 0 )), ( 5 , 40 ))
self .load_help_text()
|
3.创建地图类,初始化地图和坐标
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
|
#3 创建地图类
class map ():
#3 存储两张不同颜色的图片名称
map_names_list = [image_path + 'map1.png' , image_path + 'map2.png' ]
#3 初始化地图
def __init__( self , x, y, img_index):
self .image = pygame.image.load( map .map_names_list[img_index])
self .position = (x, y)
# 是否能够种植
self .can_grow = true
#3 加载地图
def load_map( self ):
maingame.window.blit( self .image, self .position)
#3 存储所有地图坐标点
map_points_list = []
#3 存储所有的地图块
map_list = []
#3 初始化坐标点
def init_plant_points( self ):
for y in range ( 1 , 7 ):
points = []
for x in range ( 10 ):
point = (x, y)
points.append(point)
maingame.map_points_list.append(points)
print ( "maingame.map_points_list" , maingame.map_points_list)
#3 初始化地图
def init_map( self ):
for points in maingame.map_points_list:
temp_map_list = list ()
for point in points:
# map = none
if (point[ 0 ] + point[ 1 ]) % 2 = = 0 :
map = map (point[ 0 ] * 80 , point[ 1 ] * 80 , 0 )
else :
map = map (point[ 0 ] * 80 , point[ 1 ] * 80 , 1 )
# 将地图块加入到窗口中
temp_map_list.append( map )
print ( "temp_map_list" , temp_map_list)
maingame.map_list.append(temp_map_list)
print ( "maingame.map_list" , maingame.map_list)
#3 将地图加载到窗口中
def load_map( self ):
for temp_map_list in maingame.map_list:
for map in temp_map_list:
map .load_map()
#3 初始化坐标和地图
self .init_plant_points()
self .init_map()
#3 需要反复加载地图
self .load_map()
|
4.创建植物类,图片加载报错处理,加载植物方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#4 图片加载报错处理
log = '文件:{}中的方法:{}出错' . format (__file__,__name__)
#4 植物类
class plant(pygame.sprite.sprite):
def __init__( self ):
super (plant, self ).__init__()
self .live = true
# 加载图片
def load_image( self ):
if hasattr ( self , 'image' ) and hasattr ( self , 'rect' ):
maingame.window.blit( self .image, self .rect)
else :
print (log)
#4 存储所有植物的列表
plants_list = []
|
5.创建向日葵类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#5 向日葵类
class sunflower(plant):
def __init__( self ,x,y):
super (sunflower, self ).__init__()
self .image = pygame.image.load( 'imgs/sunflower.png' )
self .rect = self .image.get_rect()
self .rect.x = x
self .rect.y = y
self .price = 50
self .hp = 100
#5 时间计数器
self .time_count = 0
#5 功能:生成阳光(生产钱)
def produce_money( self ):
self .time_count + = 1
if self .time_count = = 25 :
maingame.money + = 5
self .time_count = 0
#5 向日葵加入到窗口中
def display_sunflower( self ):
maingame.window.blit( self .image, self .rect)
|
6.创建豌豆射手类
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
|
#6 豌豆射手类
class peashooter(plant):
def __init__( self ,x,y):
super (peashooter, self ).__init__()
# self.image 为一个 surface
self .image = pygame.image.load( 'imgs/peashooter.png' )
self .rect = self .image.get_rect()
self .rect.x = x
self .rect.y = y
self .price = 50
self .hp = 200
#6 发射计数器
self .shot_count = 0
#6 增加射击方法
def shot( self ):
#6 记录是否应该射击
should_fire = false
for zombie in maingame.zombie_list:
if zombie.rect.y = = self .rect.y and zombie.rect.x < 800 and zombie.rect.x > self .rect.x:
should_fire = true
#6 如果活着
if self .live and should_fire:
self .shot_count + = 1
# 计数器到25发射一次
if self .shot_count = = 25 :
#6 基于当前豌豆射手的位置,创建子弹
peabullet = peabullet( self )
#6 将子弹存储到子弹列表中
maingame.peabullet_list.append(peabullet)
self .shot_count = 0
#6 将豌豆射手加入到窗口中的方法
def display_peashooter( self ):
maingame.window.blit( self .image, self .rect)
#6 增加豌豆射手发射处理
def load_plants( self ):
for plant in maingame.plants_list:
#6 优化加载植物的处理逻辑
if plant.live:
if isinstance (plant, sunflower):
plant.display_sunflower()
plant.produce_money()
elif isinstance (plant, peashooter):
plant.display_peashooter()
plant.shot()
else :
maingame.plants_list.remove(plant)
#6 调用加载植物的方法
self .load_plants()
|
7.创建子弹类
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
|
#7 豌豆子弹类
class peabullet(pygame.sprite.sprite):
def __init__( self ,peashooter):
self .live = true
self .image = pygame.image.load( 'imgs/peabullet.png' )
self .damage = 50
self .speed = 10
self .rect = self .image.get_rect()
self .rect.x = peashooter.rect.x + 60
self .rect.y = peashooter.rect.y + 15
def move_bullet( self ):
#7 在屏幕范围内,实现往右移动
if self .rect.x < scrrr_width:
self .rect.x + = self .speed
else :
self .live = false
#7 新增,子弹与僵尸的碰撞
def hit_zombie( self ):
for zombie in maingame.zombie_list:
if pygame.sprite.collide_rect( self ,zombie):
#打中僵尸之后,修改子弹的状态,
self .live = false
#僵尸掉血
zombie.hp - = self .damage
if zombie.hp < = 0 :
zombie.live = false
self .nextlevel()
#7闯关方法
def nextlevel( self ):
maingame.score + = 20
maingame.remnant_score - = 20
for i in range ( 1 , 100 ):
if maingame.score = = 100 * i and maingame.remnant_score = = 0 :
maingame.remnant_score = 100 * i
maingame.shaoguan + = 1
maingame.produce_zombie + = 50
def display_peabullet( self ):
maingame.window.blit( self .image, self .rect)
#7 存储所有豌豆子弹的列表
peabullet_list = []
#7 加载所有子弹的方法
def load_peabullets( self ):
for b in maingame.peabullet_list:
if b.live:
b.display_peabullet()
b.move_bullet()
#7 调用子弹是否打中僵尸的方法
b.hit_zombie()
else :
maingame.peabullet_list.remove(b)
#7 调用加载所有子弹的方法
self .load_peabullets()
|
8.事件处理
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
|
#8事件处理
def deal_events( self ):
#8 获取所有事件
eventlist = pygame.event.get()
#8 遍历事件列表,判断
for e in eventlist:
if e. type = = pygame.quit:
self .gameover()
elif e. type = = pygame.mousebuttondown:
# print('按下鼠标按键')
print (e.pos)
# print(e.button)#左键1 按下滚轮2 上转滚轮为4 下转滚轮为5 右键 3
x = e.pos[ 0 ] / / 80
y = e.pos[ 1 ] / / 80
print (x, y)
map = maingame.map_list[y - 1 ][x]
print ( map .position)
#8 增加创建时候的地图装填判断以及金钱判断
if e.button = = 1 :
if map .can_grow and maingame.money > = 50 :
sunflower = sunflower( map .position[ 0 ], map .position[ 1 ])
maingame.plants_list.append(sunflower)
print ( '当前植物列表长度:{}' . format ( len (maingame.plants_list)))
map .can_grow = false
maingame.money - = 50
elif e.button = = 3 :
if map .can_grow and maingame.money > = 50 :
peashooter = peashooter( map .position[ 0 ], map .position[ 1 ])
maingame.plants_list.append(peashooter)
print ( '当前植物列表长度:{}' . format ( len (maingame.plants_list)))
map .can_grow = false
maingame.money - = 50
#8 调用事件处理的方法
self .deal_events()
|
9.创建僵尸类
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
|
#9 僵尸类
class zombie(pygame.sprite.sprite):
def __init__( self ,x,y):
super (zombie, self ).__init__()
self .image = pygame.image.load( 'imgs/zombie.png' )
self .rect = self .image.get_rect()
self .rect.x = x
self .rect.y = y
self .hp = 1000
self .damage = 2
self .speed = 1
self .live = true
self .stop = false
#9 僵尸的移动
def move_zombie( self ):
if self .live and not self .stop:
self .rect.x - = self .speed
if self .rect.x < - 80 :
#8 调用游戏结束方法
maingame().gameover()
#9 判断僵尸是否碰撞到植物,如果碰撞,调用攻击植物的方法
def hit_plant( self ):
for plant in maingame.plants_list:
if pygame.sprite.collide_rect( self ,plant):
#8 僵尸移动状态的修改
self .stop = true
self .eat_plant(plant)
#9 僵尸攻击植物
def eat_plant( self ,plant):
#9 植物生命值减少
plant.hp - = self .damage
#9 植物死亡后的状态修改,以及地图状态的修改
if plant.hp < = 0 :
a = plant.rect.y / / 80 - 1
b = plant.rect.x / / 80
map = maingame.map_list[a][b]
map .can_grow = true
plant.live = false
#8 修改僵尸的移动状态
self .stop = false
#9 将僵尸加载到地图中
def display_zombie( self ):
maingame.window.blit( self .image, self .rect)
#9 新增存储所有僵尸的列表
zombie_list = []
count_zombie = 0
produce_zombie = 100
#9 新增初始化僵尸的方法
def init_zombies( self ):
for i in range ( 1 , 7 ):
dis = random.randint( 1 , 5 ) * 200
zombie = zombie( 800 + dis, i * 80 )
maingame.zombie_list.append(zombie)
#9将所有僵尸加载到地图中
def load_zombies( self ):
for zombie in maingame.zombie_list:
if zombie.live:
zombie.display_zombie()
zombie.move_zombie()
# v2.0 调用是否碰撞到植物的方法
zombie.hit_plant()
else :
maingame.zombie_list.remove(zombie)
#9 调用初始化僵尸的方法
self .init_zombies()
#9 调用展示僵尸的方法
self .load_zombies()
#9 计数器增长,每数到100,调用初始化僵尸的方法
maingame.count_zombie + = 1
if maingame.count_zombie = = maingame.produce_zombie:
self .init_zombies()
maingame.count_zombie = 0
#9 pygame自己的休眠
pygame.time.wait( 10 )
|
10.游戏结束方法
1
2
3
4
5
6
|
#10 程序结束方法
def gameover( self ):
maingame.window.blit( self .draw_text( '游戏结束' , 50 , ( 255 , 0 , 0 )), ( 300 , 200 ))
pygame.time.wait( 400 )
global gameover
gameover = true
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对服务器之家的支持。
原文链接:https://segmentfault.com/a/1190000019418065