开发思路
完整项目地址: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