class Tank(pygame.sprite.Sprite): """Посути сам танк. Танк игрока - красный.""" #список подгруженных изображений(сделано в главном классе) images = [] #количество циклов анимации animcycle = 6 #инициализируем def __init__(self, colour, respawnpoint, algorithm, visible=True): #делаем спрайтом pygame.sprite.Sprite.__init__(self, self.containers) #подгружаем нужную картинку self.image = self.images[colour * 6] #помещаем в прямоугольник self.rect = self.image.get_rect() # в респаун на последнее поля боя с нужным углом x = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][0] + 6 y = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][1] + 4 angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] #ставим танк спомощью move((x, y)) newpos = self.rect.move((x, y)) self.rect = newpos #сохраняем здесь цвет, переданный этому танку-спрайту(может и синий,а может и красный) self.colour = colour #алгоритм self.algorithm = algorithm #делаем видимым self.visible = visible #его ориентация в 2D self.angle = angle #пока он стоит на месте = нулевая передача self.gear = 0 #не стрелял self.bullets = 0 #не умирал self.deaths = 0 #не убивал self.kills = 0 #вначале он отображается и на окне заставки(можно убрать) self.state = 0 #заводим для него очередь команд self.command_queue = [] #распологаем его правильно в респауне, по параметру self.angle ставим спиной к стене self.original = self.image center = self.rect.center rotate = pygame.transform.rotate self.image = rotate(self.original, self.angle) self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top #передача и нагрев для танка self.gun_cooldown = GameData.bulletloadtime self.gear_cooldown = GameData.gearcooldown # отображение танка на панели очков #делаем копию танкатого же цвета self.icon_display = TankCopy(self.colour) #в пустом цикле if pygame.font: #отображаем число смертей и число убитых танков self.kills_display = Score("kills : %d", "orange", 870, 190 + self.colour * 75) self.deaths_display = Score("deaths : %d", "red", 870, 222 + self.colour * 75) # создаём ботов в их респаунах в начале игры #если не красныйтанк if self.colour != GameData.red: #передаём очередь команд self.command_queue = [] #и здесь самый простеший "искусственный интелект" говорящий,как выйти боту из респауна for i in range(0, 20): #вверх self.command_queue.append("up") #стрельни self.command_queue.append("shoot") #стой self.command_queue.append("flush") #перемещение после гибели в респаун, с данными координатами и углом def move_to_respawn_point(self, respawnpoint): self.x = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][0] + 6 self.y = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][1] + 4 self.angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] self.rect.left = self.x self.rect.top = self.y #огонь def shoot(self): #если можно стрелять if (self.bullets < GameData.maxbullets) and (self.gun_cooldown == 0): #огонь! Bullet(self.colour, self.rect.centerx - 3, self.rect.centery - 3, self.angle) #пуль на экране больше на одну self.bullets = self.bullets + 1 #нагрев больше на один self.gun_cooldown = GameData.bulletloadtime #взрыв танка def explode(self): #к смерти + 1 self.deaths += 1 #передачу в ноль self.gear = 0 #передаем оригинал танка self.original = self.image #вводим флаг flag = 0 #рандом ставим в респаун respawnpoint = int(random.random() * 6) while respawnpoint in GameData.respawnlist: respawnpoint = int(random.random() * 6) while len(GameData.respawnlist) > 2: #поп - уточнить dummy = GameData.respawnlist.pop(0) #добавляем в листреспаунов нов точку GameData.respawnlist.append(respawnpoint) #и в эту новую точку танк и помещаем с углом и координатами,передадаём очередь комманд self.move_to_respawn_point(respawnpoint) self.angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] self.rect.left = self.x self.rect.top = self.y self.command_queue = [] #увеличиваем передачу def gear_up(self): if (self.gear < 4) and (self.gear_cooldown == 0): self.gear = self.gear + 1 self.gear_cooldown = GameData.gearcooldown #уменьшаем передачу def gear_down(self): if (self.gear > 0) and (self.gear_cooldown == 0): self.gear = self.gear - 1 self.gear_cooldown = GameData.gearcooldown elif self.gear_cooldown == 0: self.gear = -2 self.gear_cooldown = GameData.gearcooldown #резкий тормоз def halt(self): self.gear = 0 #двигаем вправо def right(self): self.angle = self.angle - GameData.angle if self.angle < 0: self.angle = 360 - GameData.angle #двигаем влево def left(self): self.angle = self.angle + GameData.angle if self.angle >= 360: self.angle = 0 #команды в процессе игры def process_commands(self, respawn_points): #если команд больше 0 if len(self.command_queue) > 0: #действие отправляй в пайпе action = self.command_queue.pop(0) #действие взрыв = новую очередь if action == "flush": self.command_queue = [] #действие вверх = передачу вверх if action == "up": self.gear_up() #действие вниз = передачу вниз if action == "down": self.gear_down() #действие влево = двигай влево if action == "left": self.left() #действие вправо = двигай вправо if action == "right": self.right() #действие тормоз = тормози if action == "halt": self.halt() #действие огонь = огонь if action == "shoot": if len(pygame.sprite.spritecollide(self, respawn_points, 0)) == 0: self.shoot() # танки могут стрелять во время движения elif (len(self.command_queue) > 0): if self.command_queue[0] == "shoot": if len(pygame.sprite.spritecollide(self, respawn_points, 0)) == 0: dummy = self.command_queue.pop(0) self.shoot() #описываем движение танка def move(self): # передаём "скорость" умножаем на передачу и спомощьютригонометрии гоним xoffset = math.cos( self.angle * math.pi / 180) * self.gear * GameData.tankspeed yoffset = -math.sin( self.angle * math.pi / 180) * self.gear * GameData.tankspeed # тормоз при ударе об стену #для всех стен for wall in GameData.battleground[GameData.battlegroundnr].walls: if wall.colliderect(self.rect): #удар об стену? if wall.collidepoint(self.rect.left, self.rect.top): #тормози! if xoffset < 0: xoffset = 0 if yoffset < 0: yoffset = 0 #удар об стену? elif wall.collidepoint(self.rect.left, self.rect.bottom): #тормози! if xoffset < 0: xoffset = 0 if yoffset > 0: yoffset = -0 #удар об стену?(в таком-то положении) elif wall.collidepoint(self.rect.right, self.rect.top): #тормози! if xoffset > 0: xoffset = -0 if yoffset < 0: yoffset = 0 elif wall.collidepoint(self.rect.right, self.rect.bottom): if xoffset > 0: xoffset = -0 if yoffset > 0: yoffset = -0 elif wall.collidepoint(self.rect.centerx, self.rect.top): if yoffset < 0: yoffset = 0 elif wall.collidepoint(self.rect.centerx, self.rect.bottom): if yoffset > 0: yoffset = -0 elif wall.collidepoint(self.rect.left, self.rect.centery): if xoffset < 0: xoffset = 0 elif wall.collidepoint(self.rect.right, self.rect.centery): if xoffset > 0: xoffset = -0 else: xoffset = 0 yoffset = 0 # нельзя ездить по воде!(тоже,что и стены по сути) for pool in GameData.battleground[GameData.battlegroundnr].water: if pool.colliderect(self.rect): if pool.collidepoint(self.rect.left, self.rect.top): if xoffset < 0: xoffset = 0 if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.left, self.rect.bottom): if xoffset < 0: xoffset = 0 if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.right, self.rect.top): if xoffset > 0: xoffset = -0 if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.right, self.rect.bottom): if xoffset > 0: xoffset = -0 if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.centerx, self.rect.top): if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.centerx, self.rect.bottom): if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.left, self.rect.centery): if xoffset < 0: xoffset = 0 elif pool.collidepoint(self.rect.right, self.rect.centery): if xoffset > 0: xoffset = -0 else: xoffset = 0 yoffset = 0 # отбиваем танк при ударе об границу окна if self.x < 3: if xoffset < 0: xoffset = 1 if self.x > 759: if xoffset > 0: xoffset = -1 if self.y < 3: if yoffset < 0: yoffset = 1 if self.y > 724: if yoffset > 0: yoffset = -1 # а теперь после всех запрещений об ударах об стену и воду меняем позицию танка в действительности! newpos = self.rect.move((xoffset, yoffset)) self.rect = newpos #апдэйт def update(self): # апдэйте панели очков if pygame.font: #апдэйт смерте/убийств self.kills_display.set_score(self.kills) self.deaths_display.set_score(self.deaths) if self.visible: # теперь используем новую картинку танка self.image = self.images[(self.colour * 6) + GameData.animstep] self.original = self.image # и вращаем её center = self.rect.center rotate = pygame.transform.rotate self.image = rotate(self.original, self.angle) self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top else: center = self.rect.center self.image = GameData.transparant_sprite self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top
class Tank(pygame.sprite.Sprite): """Yes, this is what this game is about. The player tank is hardcoded to be the red one.""" images = [] animcycle = 6 def __init__(self, colour, respawnpoint, algorithm, visible=True): pygame.sprite.Sprite.__init__(self, self.containers) self.image = self.images[colour * 6] self.rect = self.image.get_rect() x = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][0] + 6 y = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][1] + 4 angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] newpos = self.rect.move((x, y)) self.rect = newpos self.colour = colour self.algorithm = algorithm self.visible = visible self.angle = angle self.gear = 0 self.bullets = 0 self.deaths = 0 self.kills = 0 self.state = 0 self.command_queue = [] self.original = self.image center = self.rect.center rotate = pygame.transform.rotate self.image = rotate(self.original, self.angle) self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top self.gun_cooldown = GameData.bulletloadtime self.gear_cooldown = GameData.gearcooldown # display tank on scoreboard self.icon_display = TankCopy(self.colour) if pygame.font: self.kills_display = Score("kills : %d", "orange", 870, 190 + self.colour * 75) self.deaths_display = Score("deaths : %d", "red", 870, 222 + self.colour * 75) # Make A.I. tanks come out of their spawn point at the start of a new game if self.colour <> GameData.red: self.command_queue = [] for i in range(0, 20): self.command_queue.append("up") self.command_queue.append("shoot") self.command_queue.append("flush") def move_to_respawn_point(self, respawnpoint): self.x = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][0] + 6 self.y = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][1] + 4 self.angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] self.rect.left = self.x self.rect.top = self.y def shoot(self): if (self.bullets < GameData.maxbullets) and (self.gun_cooldown == 0): #this was centerx-3, centery-0 Bullet(self.colour, self.rect.centerx - 3, self.rect.centery - 3, self.angle) self.bullets = self.bullets + 1 self.gun_cooldown = GameData.bulletloadtime def explode(self): self.deaths += 1 self.gear = 0 self.original = self.image flag = 0 respawnpoint = int(random.random() * 6) while respawnpoint in GameData.respawnlist: respawnpoint = int(random.random() * 6) while len(GameData.respawnlist) > 2: dummy = GameData.respawnlist.pop(0) GameData.respawnlist.append(respawnpoint) self.move_to_respawn_point(respawnpoint) self.angle = GameData.battleground[ GameData.battlegroundnr].respawnpoints[respawnpoint][2] self.rect.left = self.x self.rect.top = self.y self.command_queue = [] def gear_up(self): if (self.gear < 4) and (self.gear_cooldown == 0): self.gear = self.gear + 1 self.gear_cooldown = GameData.gearcooldown def gear_down(self): if (self.gear > 0) and (self.gear_cooldown == 0): self.gear = self.gear - 1 self.gear_cooldown = GameData.gearcooldown elif self.gear_cooldown == 0: self.gear = -2 self.gear_cooldown = GameData.gearcooldown def halt(self): self.gear = 0 def right(self): self.angle = self.angle - GameData.angle if self.angle < 0: self.angle = 360 - GameData.angle def left(self): self.angle = self.angle + GameData.angle if self.angle >= 360: self.angle = 0 def process_commands(self, respawn_points): if len(self.command_queue) > 0: action = self.command_queue.pop(0) if action == "flush": self.command_queue = [] if action == "up": self.gear_up() if action == "down": self.gear_down() if action == "left": self.left() if action == "right": self.right() if action == "halt": self.halt() if action == "shoot": if len(pygame.sprite.spritecollide(self, respawn_points, 0)) == 0: self.shoot() # tanks can shoot while turning or changing gear elif (len(self.command_queue) > 0): if self.command_queue[0] == "shoot": if len(pygame.sprite.spritecollide(self, respawn_points, 0)) == 0: dummy = self.command_queue.pop(0) self.shoot() def move(self): # xoffset & yoffset as in $tring$ (magazine of the Youth Computer Club) nr.1, 1984, page 13 xoffset = math.cos( self.angle * math.pi / 180) * self.gear * GameData.tankspeed yoffset = -math.sin( self.angle * math.pi / 180) * self.gear * GameData.tankspeed # stay out of walls for wall in GameData.battleground[GameData.battlegroundnr].walls: if wall.colliderect(self.rect): if wall.collidepoint(self.rect.left, self.rect.top): if xoffset < 0: xoffset = 0 if yoffset < 0: yoffset = 0 elif wall.collidepoint(self.rect.left, self.rect.bottom): if xoffset < 0: xoffset = 0 if yoffset > 0: yoffset = -0 elif wall.collidepoint(self.rect.right, self.rect.top): if xoffset > 0: xoffset = -0 if yoffset < 0: yoffset = 0 elif wall.collidepoint(self.rect.right, self.rect.bottom): if xoffset > 0: xoffset = -0 if yoffset > 0: yoffset = -0 elif wall.collidepoint(self.rect.centerx, self.rect.top): if yoffset < 0: yoffset = 0 elif wall.collidepoint(self.rect.centerx, self.rect.bottom): if yoffset > 0: yoffset = -0 elif wall.collidepoint(self.rect.left, self.rect.centery): if xoffset < 0: xoffset = 0 elif wall.collidepoint(self.rect.right, self.rect.centery): if xoffset > 0: xoffset = -0 else: xoffset = 0 yoffset = 0 # stay out of water for pool in GameData.battleground[GameData.battlegroundnr].water: if pool.colliderect(self.rect): if pool.collidepoint(self.rect.left, self.rect.top): if xoffset < 0: xoffset = 0 if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.left, self.rect.bottom): if xoffset < 0: xoffset = 0 if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.right, self.rect.top): if xoffset > 0: xoffset = -0 if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.right, self.rect.bottom): if xoffset > 0: xoffset = -0 if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.centerx, self.rect.top): if yoffset < 0: yoffset = 0 elif pool.collidepoint(self.rect.centerx, self.rect.bottom): if yoffset > 0: yoffset = -0 elif pool.collidepoint(self.rect.left, self.rect.centery): if xoffset < 0: xoffset = 0 elif pool.collidepoint(self.rect.right, self.rect.centery): if xoffset > 0: xoffset = -0 else: xoffset = 0 yoffset = 0 # bounce back at border if self.x < 3: if xoffset < 0: xoffset = 1 if self.x > 759: if xoffset > 0: xoffset = -1 if self.y < 3: if yoffset < 0: yoffset = 1 if self.y > 724: if yoffset > 0: yoffset = -1 # move & rotate the Tank sprite newpos = self.rect.move((xoffset, yoffset)) self.rect = newpos def update(self): # update scoreboard if pygame.font: self.kills_display.set_score(self.kills) self.deaths_display.set_score(self.deaths) if self.visible: # use next image self.image = self.images[(self.colour * 6) + GameData.animstep] self.original = self.image # rotate center = self.rect.center rotate = pygame.transform.rotate self.image = rotate(self.original, self.angle) self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top else: center = self.rect.center self.image = GameData.transparant_sprite self.rect = self.image.get_rect(center=center) self.x = self.rect.left self.y = self.rect.top