# coding=utf-8
# Time : 2018/8/4 9:20
# Author : 云水君
# Email : 632942444@qq.com
# File : 坦克大战.py
import pygame
from random import randint
class TankMain():
"""
坦克大战主程序
"""
# 用于存储敌方坦克对象,使用pygame的sprite类里的Group方法,方便碰撞检测
em_tanks = pygame.sprite.Group()
# 用于存储敌方坦克发射的子弹对象的列表
em_bullet = []
my_tank = "" # 用于存储我方坦克对象的类字段
width = 1000
height = 700
def start_game(self):
screen = pygame.display.set_mode((TankMain.width, TankMain.height))
screen.fill((10, 10, 10))
pygame.display.set_caption("坦克大战")
TankMain.my_tank = my = MyTank(500, 600)
my.displays(screen)
pygame.display.flip()
my_bullet = []
# 产生敌方坦克,并且位置不重复
while len(TankMain.em_tanks) < 10:
emtank = EmTank(randint(70, 900), randint(70, 400))
if TankMain.em_tanks:
flag = True
for em in TankMain.em_tanks:
if pygame.sprite.collide_rect(em, emtank): # pygame自带的碰撞检测方法
flag = False
break
if flag:
TankMain.em_tanks.add(emtank)
else:
TankMain.em_tanks.add(emtank)
while True:
pygame.time.delay(15)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYUP:
my.move_state = "stop"
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w or event.key == pygame.K_UP:
my.direction = "up"
my.move_state = "move"
if event.key == pygame.K_s or event.key == pygame.K_DOWN:
my.direction = "down"
my.move_state = "move"
if event.key == pygame.K_d or event.key == pygame.K_RIGHT:
my.direction = "right"
my.move_state = "move"
if event.key == pygame.K_a or event.key == pygame.K_LEFT:
my.direction = "left"
my.move_state = "move"
if event.key == pygame.K_SPACE:
missile = my.fire(screen)
my_bullet.append(missile)
screen.fill((10, 10, 10))
my.move()
my.displays(screen)
my.hit()
if my.hp == 0:
print("游戏结束")
# exit()
if len(TankMain.em_tanks) > 0:
for em_tank in TankMain.em_tanks:
em_tank.move_state = "move"
em_tank.displays(screen)
em_tank.hit()
em_tank.move()
# em_tank.hit()
if em_tank.hp == 0:
TankMain.em_tanks.remove(em_tank)
rand_num = randint(1, 30)
if rand_num == 2:
rand_num = randint(1, 4)
if rand_num == 1:
em_tank.direction = "down"
if rand_num == 2:
em_tank.direction = "up"
if rand_num == 3:
em_tank.direction = "left"
if rand_num == 4:
em_tank.direction = "right"
rand_num = randint(1, 30)
if rand_num == 3:
TankMain.em_bullet.append(em_tank.fire(screen))
for bullet in TankMain.em_bullet:
bullet.move()
bullet.displays(screen)
if bullet.move_state == "stop" or bullet.hp == 0:
TankMain.em_bullet.remove(bullet)
for bullet in my_bullet:
bullet.move()
bullet.hit()
bullet.displays(screen)
if bullet.move_state == "stop" or bullet.hp == 0:
my_bullet.remove(bullet)
pygame.display.update()
class Operation(pygame.sprite.Sprite):
# 游戏中所有类的父类,把公共的方法和属性写在这个类里面。继承pygame的Sprite类,不然无法使用自带的碰撞检测方法
def __init__(self):
pygame.sprite.Sprite.__init__(self) # 初始化Sprit类 必须要有
self.direction = "up" # 默认的朝向为向上
self.speed = 2
self.move_state = "stop"
def move(self):
self.oldx = x = self.rect.left # 用于回到碰撞前的X坐标
self.oldy = y = self.rect.top # 用于回到碰撞前的y坐标
if self.move_state == "move":
# 根据朝向来决定移动,到了边界就停止
if self.direction == "right":
if x >= TankMain.width-self.size:
self.move_state = "stop"
else:
self.rect.left += self.speed
if self.direction == "left":
if x <= 0:
self.move_state = "stop"
else:
self.rect.left -= self.speed
if self.direction == "down":
if y >= TankMain.height - self.size:
self.move_state = "stop"
else:
self.rect.top += self.speed
if self.direction == "up":
if y <= 0:
self.move_state = "stop"
else:
self.rect.top -= self.speed
def displays(self, screen):
self.image = self.images[self.direction]
screen.blit(self.image, self.rect)
class Tank(Operation):
def __init__(self):
super().__init__()
self.hp = 2
self.size = 60
self.images = {}
self.oldx = 0 # 用于回到碰撞前的X坐标,开始默认为0,游戏开始后随着移动自动更新
self.oldy = 0 # 用于回到碰撞前的y坐标
def fire(self, screen): # 调用开火的方法 就产生一颗子弹,并且子弹的坐标由调用者自己的坐标产生
return Bullet(self.rect.left+int(self.size/2), self.rect.top+int(self.size/2), self.direction, screen)
def stay(self): # 发生了碰撞,就调用此方法 回到碰撞前的坐标,达到不能穿透的效果
self.rect.left = self.oldx
self.rect.top = self.oldy
class MyTank(Tank):
def __init__(self, x, y):
super().__init__()
self.images["left"] = pygame.image.load(r"./images/my_left.jpg")
self.images["up"] = pygame.image.load(r"./images/my_up.jpg")
self.images["right"] = pygame.image.load(r"./images/my_right.jpg")
self.images["down"] = pygame.image.load(r"./images/my_down.jpg")
self.image = self.images[self.direction] # 坦克显示的图片 由坦克的朝向决定
# 这里是Sprite碰撞检测的关键.get_rect()方法返回的是一个RECT,自带的碰撞检测方法靠的就是这个来判断碰撞
self.rect = self.image.get_rect()
self.rect.left = x # RECT有四个属性 其中.left表示x坐标
self.rect.top = y # .top 表示y坐标
def hit(self): # 碰撞检测
# .spritecollide方法 判断一个对象与一个组的碰撞 返回的是一个在组中发生了碰撞的对象的列表
hit_list = pygame.sprite.spritecollide(self, TankMain.em_bullet, False) # 判断与敌方子弹的碰撞
for em_bullet in hit_list:
em_bullet.hp -= 1
self.hp -= em_bullet.hurt # 与子弹碰撞了 就血量减少 并且子弹的血量也减少(用于后面删除子弹)
hit_list2 = pygame.sprite.spritecollide(self, TankMain.em_tanks, False) #判断与敌方坦克的碰撞
for em_tank in hit_list2:
em_tank.stay() # 发生了碰撞,敌方坦克回到碰撞前的坐标
self.stay() # 自己本身也回到碰撞前的坐标
class EmTank(Tank):
def __init__(self, x, y):
super().__init__()
self.images["left"] = pygame.image.load(r"./images/em_left.jpg")
self.images["up"] = pygame.image.load(r"./images/em_up.jpg")
self.images["right"] = pygame.image.load(r"./images/em_right.jpg")
self.images["down"] = pygame.image.load(r"./images/em_down.jpg")
self.image = self.images[self.direction]
self.rect = self.image.get_rect()
self.rect.left = x
self.rect.top = y
def hit(self):
for em in TankMain.em_tanks:
if em != self:
# .collide_rect()方法用于判断两个对象的碰撞 返回布尔值
if pygame.sprite.collide_rect(self, em): # 判断 敌方坦克之间的碰撞
em.stay()
self.stay()
class Bullet(Operation):
def __init__(self, x, y, direction, screen):
super().__init__()
self.hurt = 1
self.hp = 1
self.speed = 10
self.move_state = "move"
self.direction = direction
self.size = 5
# 画圆的方法返回的对象就之间是一个RECT
self.rect = pygame.draw.circle(screen, (255, 0, 0), (x, y), self.size)
self.rect.left = x
self.rect.top = y
def displays(self, screen):
pygame.draw.circle(screen, (255, 0, 0), (self.rect.left-int(self.size/2), self.rect.top-int(self.size/2)), self.size)
def hit(self):
hit_list = pygame.sprite.spritecollide(self, TankMain.em_tanks, False) #检测我方的子弹与敌方坦克的碰撞
for em_tank in hit_list:
em_tank.hp -= self.hurt
self.hp -= 1
if __name__ == '__main__':
pygame.init()
game = TankMain() #创建一个游戏对象
game.start_game() #开始游戏
19坦克大战!
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和...