美文网首页
手把手教你用Python实现“坦克大战”,附详细代码!

手把手教你用Python实现“坦克大战”,附详细代码!

作者: Python新视界 | 来源:发表于2020-01-07 16:51 被阅读0次

    小时候玩的“坦克大战”,你还记得吗?

    满满的回忆

    今天,我们使用Python以及强大的第三方库来实现一个简单的坦克大战游戏。

    整体效果

    环境依赖

    python3.7

    pygame1.9.6

    urllib

    内置库,如random、sys、time、os等

    pygame介绍

    Pygame被设计用来写游戏的python模块集合,基于SDL库开发。使用python可以导入pygame来开发具有全部特性的游戏和多媒体软件,Pygame是极度轻便的并且可以运行在几乎所有的平台和操作系统上。

    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. 通用加载函数

    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模块,官方文档上说这个模块是轻量级的,在游戏开发中也未必要使用。

    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# 参数初始化

    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# 参数初始化

    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# 不同的坦克击中的次数不一样

    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. 定义坦克大战类

      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()

    执行界面

    相关文章

      网友评论

          本文标题:手把手教你用Python实现“坦克大战”,附详细代码!

          本文链接:https://www.haomeiwen.com/subject/dvnractx.html