最近想自己写pygame版的坦克大战,今晚已经完成如下功能:
1,我方坦克,可手动移动;敌方坦克,自动转方向与移动
2,坦克颜色随机,坦克形态大小可调。
3,双方坦克速度可调。
4,刷新坦克的位置随机。
5,坦克不会出界。
6,游戏窗口大小可调。
目前存在的问题:
1,表示坦克方向的列表,还未放到类里。
2,坦克会重叠(碰撞检测)。
3,炮弹类还未写。
4,......
# !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan import pygame import random from pygame.locals import * pygame.init() FPS = pygame.time.Clock() fps = 10 screen_x = 640 screen_y = 480 # 退出标识符 done = False fill_color = 0, 0, 0 # 黑色 surface = pygame.display.set_mode((screen_x, screen_y)) pygame.display.set_caption("Draw a tank") # 小方块边长,一辆坦克是是7*7个小方块组成的 blockage = 5 tank_u = [1, 0, 0, 3, 0, 0, 1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 1] tank_d = [1, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 3, 2, 2, 1, 1, 2, 2, 3, 2, 2, 1, 1, 0, 0, 3, 0, 0, 1] tank_l = [1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 3, 3, 3, 3, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1] tank_r = [1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 3, 3, 3, 3, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1] def get_one_color(): ''' 随机得到一种颜色 :return: 颜色R,G,B值 ''' r = random.randint(0, 255) g = random.randint(0, 255) b = random.randint(0, 255) color = (r, g, b) return color class Tank(pygame.sprite.Sprite): '坦克类' def __init__(self): self.direction = random.choice([tank_u, tank_d, tank_l, tank_r]) self.color_1 = get_one_color() self.color_2 = get_one_color() self.color_3 = get_one_color() self.pos_x = random.randrange(0, screen_x - 7 * blockage + 1, 7) self.pos_y = random.randrange(0, screen_y - 7 * blockage + 1, 7) self.rect = [self.pos_x, self.pos_y, blockage, blockage] self.speed = 0.5 def get_speed(self): return self.speed def get_direction(self): return self.direction def get_color_1(self): return self.color_1 def get_color_2(self): return self.color_2 def get_color_3(self): return self.color_3 def get_rect(self): return self.rect def draw_tank(self): ''' 根据列表中的数字,对应的涂上颜色 ''' list0 = self.get_direction() color1 = self.get_color_1(), color2 = self.get_color_2(), color3 = self.get_color_3(), rect = self.get_rect() # 先计算每一项的起点坐标 def get_pos(index): ''' 给定下标序号,计算每该项的起点坐标 :param index: 下标 :return: 该项的起点坐标 ''' # 行号,列号 row = index // 7 column = index % 7 return (row, column) for i in range(len(list0)): cur_pos = get_pos(i) cur_rect = (rect[0] + cur_pos[1] * blockage, rect[1] + cur_pos[0] * blockage, rect[2], rect[3]) if list0[i] == 0: pass # 跳过,不画 elif list0[i] == 1: cur_color = color1 pygame.draw.rect(surface, cur_color, cur_rect) elif list0[i] == 2: cur_color = color2 pygame.draw.rect(surface, cur_color, cur_rect) elif list0[i] == 3: cur_color = color3 pygame.draw.rect(surface, cur_color, cur_rect) else: print("出错,坦克列表中的值只能是0、1、2或者3") pygame.quit() # 防止加入速度变量后,有时会小部分出界 if rect[0] < 0: rect[0] = 0 elif rect[1] < 0: rect[1] = 0 elif rect[0] > screen_x - 7 * blockage: rect[0] = screen_x - 7 * blockage elif rect[1] > screen_y - 7 * blockage: rect[1] = screen_y - 7 * blockage def move(self): temp = random.randint(1, 40) if temp == 1: # 向上 # 先判断当前方向是否向上,如果是,则向上走,否则,先把方向调整向上,其他方向同理 if self.direction == tank_u: # 判断是否出界 if self.rect[1] > 0: self.rect[1] -= int(blockage * self.speed) else: self.direction = tank_u elif temp == 2: # 向下 if self.direction == tank_d: if self.rect[1] < screen_y - 7 * blockage: self.rect[1] += int(blockage * self.speed) else: self.direction = tank_d elif temp == 3: # 向左 if self.direction == tank_l: if self.rect[0] > 0: self.rect[0] -= int(blockage * self.speed) else: self.direction = tank_l elif temp == 4: # 向右 if self.direction == tank_r: if self.rect[0] < screen_x - 7 * blockage: self.rect[0] += int(blockage * self.speed) else: self.direction = tank_r else: # 一直向前 if self.direction == tank_u: if self.rect[1] > 0: self.rect[1] -= int(blockage * self.speed) elif self.direction == tank_d: if self.rect[1] < screen_y - 7 * blockage: self.rect[1] += int(blockage * self.speed) elif self.direction == tank_l: if self.rect[0] > 0: self.rect[0] -= int(blockage * self.speed) else: if self.rect[0] < screen_x - 7 * blockage: self.rect[0] += int(blockage * self.speed) class MyTank(Tank): def __init__(self): Tank.__init__(self) self.speed = 1 def move(self): key = pygame.key.get_pressed() if key[K_w] or key[K_UP]: # 先判断当前方向是否向上,如果是,则向上走,否则,先把方向调整向上,其他方向同理 if self.direction == tank_u: # 判断是否出界 if self.rect[1] > 0: self.rect[1] -= int(blockage * self.speed) else: self.direction = tank_u elif key[K_s] or key[K_DOWN]: if self.direction == tank_d: if self.rect[1] < screen_y - 7 * blockage: self.rect[1] += int(blockage * self.speed) else: self.direction = tank_d elif key[K_a] or key[K_LEFT]: if self.direction == tank_l: if self.rect[0] > 0: self.rect[0] -= int(blockage * self.speed) else: self.direction = tank_l elif key[K_d] or key[K_RIGHT]: if self.direction == tank_r: if self.rect[0] < screen_x - 7 * blockage: self.rect[0] += int(blockage * self.speed) else: self.direction = tank_r self.draw_tank() class EnemyTank(Tank): def __init__(self): Tank.__init__(self) self.speed = 2 def move(self): Tank.move(self) Tank.draw_tank(self) my_tank = MyTank() other_tank_1 = EnemyTank() other_tank_2 = EnemyTank() other_tank_3 = EnemyTank() other_tank_4 = EnemyTank() other_tank_5 = EnemyTank() other_tank_6 = EnemyTank() other_tank_7 = EnemyTank() other_tank_8 = EnemyTank() other_tank_9 = EnemyTank() other_tank_10 = EnemyTank() while not done: FPS.tick(fps) for event in pygame.event.get(): if event.type == QUIT: done = True surface.fill(fill_color) my_tank.move() other_tank_1.move() other_tank_2.move() other_tank_3.move() other_tank_4.move() other_tank_5.move() other_tank_6.move() other_tank_7.move() other_tank_8.move() other_tank_9.move() other_tank_10.move() pygame.display.flip() pygame.quit()