手把手教你用Python實現(xiàn)“坦克大戰(zhàn)”,附詳細代碼!

小時候玩的“坦克大戰(zhàn)”,你還記得嗎?

滿滿的回憶

!

今天,我們使用Python以及強大的第三方庫來實現(xiàn)一個簡單的坦克大戰(zhàn)游戲。

整體效果

環(huán)境依賴

python3.7

pygame1.9.6

urllib

內置庫,如random、sys、time、os等

pygame介紹

Pygame被設計用來寫游戲的python模塊集合,基于SDL庫開發(fā)。使用python可以導入pygame來開發(fā)具有全部特性的游戲和多媒體軟件,Pygame是極度輕便的并且可以運行在幾乎所有的平臺和操作系統(tǒng)上。

1. 導入依賴 & 通用配置

1importrandom

2importsys

3importtime

4fromurllib.requestimporturlretrieve

5importos

6importpygame

7

8

9SCREEN_WIDTH,?SCREEN_HEIGHT?=1200,700#?畫面大小

10MY_BIRTH_LEFT,?MY_BIRTH_TOP?=?SCREEN_WIDTH?/2,?SCREEN_HEIGHT?-60

11DIRECTION?=?[U,?D,?L,?R]?=?[ U , D , L , R ]#?控制鍵

12Tank_IMAGE_POSITION?=r D:/tank_img

13URL?= https://gitee.com/tyoui/logo/raw/master/img/

?2. 通用加載函數(shù)

1#?加載圖片

2defload_img(name_img):

3save?=?Tank_IMAGE_POSITION?+?os.sep?+?name_img?+ .gif

4ifnotos.path.exists(save):

5urlretrieve(URL?+?name_img?+ .gif ,?save)

6returnpygame.image.load(save)

7

8#?加載背景音樂

9defload_music(name_music):

10save?=?Tank_IMAGE_POSITION?+?os.sep?+?name_music?+ .wav

11ifnotos.path.exists(save):

12urlretrieve(URL?+?name_music?+ .wav ,?save)

13pygame.mixer.music.load(save)

14pygame.mixer.music.play()

3. 通用基礎類

1

2* pygame.sprite模塊,官方文檔上說這個模塊是輕量級的,在游戲開發(fā)中也未必要使用。

3*?sprite翻譯為精靈,在游戲動畫一般是指一個獨立運動的畫面元素,在pygame中,

4就可以是一個帶有圖像(Surface)和大小位置(Rect)的對象。

5* pygame.sprite.Sprite是pygame精靈的基類,一般來說,需要寫一個自己的精靈類繼承一下它然后加入自己的代碼。

6

7classBaseItem(pygame.sprite.Sprite):

8def__init__(self):

9super().__init__()

4. 定義bullet類

1classBullet(BaseItem):

2#?參數(shù)初始化

3def__init__(self,?tank,?window):

4super().__init__()

5self.direction?=?tank.direction

6self.speed?=?tank.speed?*3

7self.img?=?load_img( bullet )

8self.rect?=?self.img.get_rect()

9self.window?=?window

10self.live?=True

11ifself.direction?==?U:

12self.rect.left?=?tank.rect.left?+?tank.rect.width?/2-?self.rect.width?/2

13self.rect.top?=?tank.rect.top?-?self.rect.height

14elifself.direction?==?D:

15self.rect.left?=?tank.rect.left?+?tank.rect.width?/2-?self.rect.width?/2

16self.rect.top?=?tank.rect.top?+?tank.rect.height

17elifself.direction?==?L:

18self.rect.left?=?tank.rect.left?-?self.rect.width?/2-?self.rect.width?/2

19self.rect.top?=?tank.rect.top?+?tank.rect.height?/2-?self.rect.height?/2

20else:

21self.rect.left?=?tank.rect.left?+?tank.rect.width

22self.rect.top?=?tank.rect.top?+?tank.rect.height?/2-?self.rect.height?/2

23

24#?子彈顯示

25defdisplay_bullet(self):

26self.window.blit(self.img,?self.rect)

27

28#?通過按鍵控制子彈移動

29defbullet_move(self):

30ifself.direction?==?U:

31ifself.rect.top?>0:

32self.rect.top?-=?self.speed

33return

34elifself.direction?==?D:

35ifself.rect.top?<?SCREEN_HEIGHT:

36self.rect.top?+=?self.speed

37return

38elifself.direction?==?L:

39ifself.rect.left?>0:

40self.rect.left?-=?self.speed

41return

42else:

43ifself.rect.left?<?SCREEN_WIDTH:

44self.rect.left?+=?self.speed

45return

46self.live?=False

47

48#?我方坦克子彈擊中對方坦克

49defhit_enemy_tank(self):

50forenemyinTankGame.enemy_tank_list:

51hit?=?pygame.sprite.collide_rect(self,?enemy)

52ifhit:

53self.live?=False

54ifenemy.click_count?==1:

55enemy.live?=False

56returnNone

57enemy.click_count?-=1

58ifenemy.click_count?==2:

59enemy.load_image?=?enemy.img32

60ifenemy.click_count?==1:

61enemy.load_image?=?enemy.img31

62load_music( hit )

63

64#?對方坦克子彈擊中我方坦克

65defhit_my_tank(self,?tank):

66hit?=?pygame.sprite.collide_rect(self,?tank)

67ifhit:

68self.live?=False

69tank.live?=False

70

71#?子彈擊中圍墻

72defbullet_collide_wall(self):

73forwallinTankGame.wall_list:

74result?=?pygame.sprite.collide_rect(self,?wall)

75ifresult:

76self.live?=False

77ifwall.count?==1:

78wall.live?=False

79else:

80load_music( hit )

81

82#?子彈擊中子彈

83defbullet_collide_bullet(self):

84forbulletinTankGame.enemy_bullet_list:

85ifpygame.sprite.collide_rect(bullet,?self):

86bullet.live?=False

87self.live?=False

5. 定義tank類

1classTank(BaseItem):

2#?參數(shù)初始化

3def__init__(self,?left,?top,?window,?image,?direction,?speed):

4super().__init__()

5self.window?=?window

6self.load_image?=?image

7self.direction?=?direction

8self.img?=?self.load_image[self.direction]

9self.rect?=?self.img.get_rect()

10self.rect.left?=?left

11self.rect.top?=?top

12self.speed?=?speed

13self.tank_width?=?self.rect.width

14self.tank_height?=?self.rect.height

15self.wall_switch?=False

16self.move_stop?=True

17self.live?=True

18self.old_left?=0

19self.old_top?=0

20

21#?開火

22deffire(self):

23returnBullet(self,?self.window)

24

25#?顯示

26defdisplay(self):

27self.img?=?self.load_image[self.direction]

28self.window.blit(self.img,?self.rect)

29

30defwall_not(self,?direction):

31ifdirection?==?U:

32returnself.rect.top?>0

33elifdirection?==?D:

34returnself.rect.top?<=?SCREEN_HEIGHT?-?self.tank_height

35elifdirection?==?L:

36returnself.rect.left?>0

37else:

38returnself.rect.left?<=?SCREEN_WIDTH?-?self.tank_width

39

40defwall_yes(self,?direction):

41ifdirection?==?U:

42ifself.rect.top?<0:

43self.rect.top?=?SCREEN_HEIGHT

44elifdirection?==?D:

45self.rect.top?%=?SCREEN_HEIGHT

46elifdirection?==?L:

47ifself.rect.left?<0:

48self.rect.left?=?SCREEN_WIDTH

49else:

50self.rect.left?%=?SCREEN_WIDTH

51

52defmove(self,?direction):

53self.old_left?=?self.rect.left

54self.old_top?=?self.rect.top

55ifself.wall_switch:

56self.wall_yes(direction)

57elifnotself.wall_not(direction):

58returnNone

59ifdirection?==?U:

60self.rect.top?-=?self.speed

61elifdirection?==?D:

62self.rect.top?+=?self.speed

63elifdirection?==?L:

64self.rect.left?-=?self.speed

65else:

66self.rect.left?+=?self.speed

67

68defstay(self):

69self.rect.left?=?self.old_left

70self.rect.top?=?self.old_top

71

72deftank_collide_wall(self):

73forwallinTankGame.wall_list:

74ifpygame.sprite.collide_rect(self,?wall):

75self.stay()

76

77deftank_collide_tank(self):

78fortankinTankGame.enemy_tank_list:

79ifpygame.sprite.collide_rect(self,?tank):

80self.stay()

6. 定義我方 & 對方tank類

1classMyTank(Tank):

2def__init__(self,?left,?top,?window):

3self.img?=?dict(U=load_img( p2tankU ),?D=load_img( p2tankD ),?L=load_img( p2tankL ),?R=load_img( p2tankR ))

4self.my_tank_speed?=4

5super().__init__(left,?top,?window,?self.img,?U,?self.my_tank_speed)

6

7

8classEnemyTank(Tank):

9def__init__(self,?left,?top,?window):

10self.img1?=?dict(U=load_img( enemy1U ),?D=load_img( enemy1D ),?L=load_img( enemy1L ),?R=load_img( enemy1R ))

11self.img2?=?dict(U=load_img( enemy2U ),?D=load_img( enemy2D ),?L=load_img( enemy2L ),?R=load_img( enemy2R ))

12self.img3?=?dict(U=load_img( enemy3U ),?D=load_img( enemy3D ),?L=load_img( enemy3L ),?R=load_img( enemy3R ))

13self.img31?=?dict(U=load_img( enemy3U_1 ),?D=load_img( enemy3D_1 ),?L=load_img( enemy3L_1 ),

14R=load_img( enemy3R_1 ))

15self.img32?=?dict(U=load_img( enemy3U_2 ),?D=load_img( enemy3D_2 ),?L=load_img( enemy3L_2 ),

16R=load_img( enemy3R_2 ))

17#?不同的坦克擊中的次數(shù)不一樣

18image,?self.click_count,?speed?=?random.choice([(self.img1,1,4),?(self.img3,3,3),?(self.img2,1,5)])

19super().__init__(left,?top,?window,?image,?self.random_direction(),?speed)

20self.step?=100

21

22@staticmethod

23defrandom_direction():

24n?=?random.randint(0,3)

25returnDIRECTION[n]

26

27defrandom_move(self):

28ifself.step?==0:

29self.direction?=?self.random_direction()

30self.step?=?random.randint(10,100)

31else:

32self.move(self.direction)

33self.step?-=1

34

35defrandom_fire(self):

36ifrandom.randint(0,50)?==1andlen(TankGame.enemy_bullet_list)?<30:

37enemy_bullet?=?self.fire()

38TankGame.enemy_bullet_list.append(enemy_bullet)

7. 爆炸動作類

1classExplode(BaseItem):

2def__init__(self,?tank,?window):

3super().__init__()

4self.img?=?[load_img( blast0 ),?load_img( blast1 ),?load_img( blast2 ),?load_img( blast3 ),?load_img( blast4 ),

5load_img( blast5 ),?load_img( blast6 )]

6self.rect?=?tank.rect

7self.stop?=0

8self.window?=?window

9self.rect.left?=?tank.rect.left?-?tank.rect.width?/2

10defdisplay_explode(self):

11load_music( blast )

12whileself.stop?<?len(self.img):

13self.window.blit(self.img[self.stop],?self.rect)

14self.stop?+=1

8. 定義wall類

1classWall(BaseItem):

2def__init__(self,?left,?top,?window):

3super().__init__()

4self.count?=?random.randint(0,1)

5self.img?=?[load_img( steels ),?load_img( walls )][self.count]

6self.rect?=?self.img.get_rect()

7self.rect.left?=?left

8self.rect.top?=?top

9self.window?=?window

10self.live?=True

11

12defdisplay_wall(self):

13self.window.blit(self.img,?self.rect)

9. 定義坦克大戰(zhàn)類

? 1classTankGame:

? 2my_bullet_list?=?list()

? 3enemy_bullet_list?=?list()

? 4enemy_tank_list?=?list()

? 5wall_list?=?list()

? 6

? 7def__init__(self):

? 8ifnotos.path.exists(Tank_IMAGE_POSITION):

? 9os.makedirs(Tank_IMAGE_POSITION)

10pygame.init()

11pygame.font.init()

12self.display?=?pygame.display

13self.window?=?self.display.set_mode([SCREEN_WIDTH,?SCREEN_HEIGHT],?pygame.RESIZABLE,32)

14self.display.set_caption( 坦克世界 )

15self.my_tank?=?MyTank(MY_BIRTH_LEFT,?MY_BIRTH_TOP,?self.window)

16self.creat_enemy_number?=10

17self.my_tank_lift?=3

18self.creat_enemy(self.creat_enemy_number)

19self.creat_walls()

20self.font?=?pygame.font.SysFont( kai_ti ,18)

21self.number?=1

22

23defcreat_enemy(self,?number):

24for_inrange(number):

25left?=?random.randint(0,?SCREEN_WIDTH?-?self.my_tank.tank_width)

26enemy_tank?=?EnemyTank(left,20,?self.window)

27TankGame.enemy_tank_list.append(enemy_tank)

28

29defcreat_walls(self):

30foriinrange(SCREEN_WIDTH?//60+1):

31wall_h?=?random.randint(100,500)

32w?=?Wall(60*?i,?wall_h,?self.window)

33TankGame.wall_list.append(w)

34

35@staticmethod

36defshow_walls():

37forwinTankGame.wall_list:

38ifw.live:

39w.display_wall()

40else:

41TankGame.wall_list.remove(w)

42

43defstart_game(self):

44load_music( start )

45whileTrue:

46self.window.fill([0,0,0])

47self.get_event()

48len_enemy?=?len(TankGame.enemy_tank_list)

49self.window.blit(

50self.draw_text( 敵方坦克*{0},我方生命值*{1},當前{2}關 .format(len_enemy,?self.my_tank_lift,?self.number)),?(10,10))

51iflen_enemy?==0:

52self.creat_enemy_number?+=10

53self.number?+=1

54self.my_tank_lift?+=1

55self.creat_enemy(self.creat_enemy_number)

56self.wall_list.clear()

57self.creat_walls()

58self.show_my_tank()

59self.show_enemy_tank()

60self.show_bullet(TankGame.enemy_bullet_list)

61self.show_bullet(TankGame.my_bullet_list)

62self.show_walls()

63self.display.update()

64time.sleep(0.02)

65

66defshow_my_tank(self):

67ifself.my_tank.live:

68self.my_tank.display()

69self.my_tank.tank_collide_tank()

70self.my_tank.tank_collide_wall()

71else:

72Explode(self.my_tank,?self.window).display_explode()

73delself.my_tank

74ifself.my_tank_lift?==0:

75self.end_game()

76self.my_tank_lift?-=1

77load_music( add )

78self.my_tank?=?MyTank(MY_BIRTH_LEFT,?MY_BIRTH_TOP,?self.window)

79ifnotself.my_tank.move_stop:

80self.my_tank.move(self.my_tank.direction)

81

82defshow_enemy_tank(self):

83foreinTankGame.enemy_tank_list:

84e.random_move()

85e.tank_collide_wall()

86ife.live:

87e.display()

88else:

89TankGame.enemy_tank_list.remove(e)

90Explode(e,?self.window).display_explode()

91e.random_fire()

92

93defshow_bullet(self,?ls):

94forbinls:

95b.bullet_move()

96b.bullet_collide_wall()

97iflsisTankGame.my_bullet_list:

98b.hit_enemy_tank()

99b.bullet_collide_bullet()

100else:

101b.hit_my_tank(self.my_tank)

102ifb.live:

103b.display_bullet()

104else:

105ls.remove(b)

106

107defget_event(self):

108globalSCREEN_WIDTH,?SCREEN_HEIGHT

109event_list?=?pygame.event.get()

110foreventinevent_list:

111ifevent.type?==?pygame.VIDEORESIZE:

112SCREEN_WIDTH,?SCREEN_HEIGHT?=?event.size

113self.window?=?self.display.set_mode([SCREEN_WIDTH,?SCREEN_HEIGHT],?pygame.RESIZABLE,32)

114

115ifevent.type?==?pygame.QUIT:

116self.end_game()

117ifevent.type?==?pygame.KEYDOWN:

118ifevent.key?==?pygame.K_w:

119self.my_tank.direction?=?U

120elifevent.key?==?pygame.K_s:

121self.my_tank.direction?=?D

122elifevent.key?==?pygame.K_a:

123self.my_tank.direction?=?L

124elifevent.key?==?pygame.K_d:

125self.my_tank.direction?=?R

126else:

127returnNone

128self.my_tank.move_stop?=False

129elifevent.type?==?pygame.MOUSEBUTTONDOWN:

130iflen(TankGame.my_bullet_list)?<3:

131bullet?=?self.my_tank.fire()

132load_music( fire )

133TankGame.my_bullet_list.append(bullet)

134elifevent.type?==?pygame.KEYUP:

135self.my_tank.move_stop?=True

136

137defend_game(self):

138self.display.quit()

139sys.exit()

140

141defdraw_text(self,?content):

142text_sf?=?self.font.render(content,True,?[255,0,0])

143returntext_sf

10. 入口

1if__name__?== __main__ :

2g?=?TankGame()

3g.start_game()

執(zhí)行界面

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容