python使用pygame模块实现坦克大战游戏
程序员文章站
2023-08-17 12:22:05
本文实例为大家分享了pygame模块实现坦克大战游戏的具体代码,供大家参考,具体内容如下
首先,第一步,游戏简单素材的准备。
炮弹,炮弹,坦克移动。音乐-开火素材。...
本文实例为大家分享了pygame模块实现坦克大战游戏的具体代码,供大家参考,具体内容如下
首先,第一步,游戏简单素材的准备。
炮弹,炮弹,坦克移动。音乐-开火素材。
其次,思路整理。
我们需要几个类,分别是玩家类,敌人类,炮弹类及地图类,开始游戏界面以及结束界面,血条等等。
开始coding。
主函数,new一个对象(java乱入emmm),声明一个对象。
# encoding : utf-8 # anthor : comi from gameloop import * from pygame import * import pygame,sys,time if __name__ == '__main__': player = game() # 声明一个类对象 player.game_start('keep-going') # 调用开始函数 while player.playing: # 进入游戏运行 player.new() # 开始游戏 player.screen.fill(black) player.game_start('game-over') # 游戏结束 time.sleep(1.5) # 可以不要
这里可以根据自己的需要进行更改相关代码
接下来 游戏的主循环
# encoding : utf-8 # author : comi from setting import * from pygame import * from sprite import * import pygame,sys vec = pygame.math.vector2 class game: # 游戏类 包含循环等 def __init__(self): # 初始化 pygame.init() # pygame 初始化 pygame.display.set_caption("keep-going") # 游戏窗口 左上角名称 self.screen = pygame.display.set_mode((width, height)) # 游戏窗口的大小 self.fpsclock = pygame.time.clock() # 设置游戏的刷新率 self.playing = true # 进入游戏的状态 self.running = true # 游戏运行的状态 self.waiting = true # 游戏等待的状态 self.pblood = 100 # 玩家血量 self.eblood = 100 # 敌人血量 self.player = player() # 声明一个游戏玩家对象 self.enemy = enemy() # 声明一个敌人对象 self.all_groups = pygame.sprite.group() # 通过pygame自带的 group 来判断碰撞检测 self.player_groups = pygame.sprite.group() self.map_groups = pygame.sprite.group() self.enemy_groups = pygame.sprite.group() def new(self): # 开始一个游戏 self.player_groups.add(self.player) # 将玩家添加到玩家组 self.all_groups.add(self.player) # 将玩家添加到 所有组 self.enemy_groups.add(self.enemy) self.all_groups.add(self.enemy) for platfroms in map1: # 地图 p = platform(*platfroms) # 取出所有值 self.map_groups.add(p) self.all_groups.add(p) self.run() # 调用函数运行游戏 def game_start(self,text): # 游戏的开始界面 self.text_draw(width / 2, height / 4, 64, text) # 文本 self.text_draw(width / 2, height * 3 / 4, 25,'press any key to continue',) # 文本 pygame.display.update() # 更行展示 while self.waiting: # 实现 按键等待开始效果 for event in pygame.event.get(): if event.type == pygame.quit: pygame.quit() sys.exit() if event.type == pygame.keydown: self.waiting = false def update(self): # 画面更新 self.map_groups.update() self.player_groups.update() self.enemy.bullet_groups.update(self.enemy.flag) # 通过按键判断子弹方向 self.player.bullet_groups.update(self.player.flag) self.enemy_groups.update() hit = pygame.sprite.groupcollide(self.player.bullet_groups, self.map_groups, true,false) # 子弹碰墙消失 hit = pygame.sprite.groupcollide(self.enemy.bullet_groups, self.map_groups, true, false) pmc = pygame.sprite.spritecollide(self.player,self.map_groups,false,false) # 撞墙 if pmc: key_pressed = pygame.key.get_pressed() if key_pressed[pygame.k_a]: self.player.pos.x = self.player.pos.x + gap if key_pressed[pygame.k_d]: self.player.pos.x = self.player.pos.x - gap if key_pressed[pygame.k_w]: self.player.pos.y = self.player.pos.y + gap if key_pressed[pygame.k_s]: self.player.pos.y = self.player.pos.y - gap emc = pygame.sprite.spritecollide(self.enemy,self.map_groups,false,false) # 撞墙 if emc: key_pressed = pygame.key.get_pressed() if key_pressed[pygame.k_left]: self.enemy.pos.x = self.enemy.pos.x + gap if key_pressed[pygame.k_right]: self.enemy.pos.x = self.enemy.pos.x - gap if key_pressed[pygame.k_up]: self.enemy.pos.y = self.enemy.pos.y + gap if key_pressed[pygame.k_down]: self.enemy.pos.y = self.enemy.pos.y - gap def run(self): while self.running: self.fpsclock.tick(fps) # 设置帧率 self.events() # 获取事件 self.draw_pic() # 画出图片 self.update() f self.eblood <= 0: # enemy self.screen.fill(black) self.game_start('p1 win!') time.sleep(1.5) self.running = false self.playing = false if self.pblood <= 0: # player self.screen.fill(black) self.game_start('p2 win!') time.sleep(1.5) self.running = false self.playing = false def text_draw(self, x, y, size, text): # 文本展示函数 self.font = pygame.font.font('freesansbold.ttf', size) # 字体,大小 self.text_surf = self.font.render(text, true, red) # 颜色 self.text_rect = self.text_surf.get_rect() # 矩形 self.text_rect.center = (x, y) # 位置 self.screen.blit(self.text_surf, self.text_rect) # 覆盖展示 def draw_pic(self): self.screen.fill(white) # 背景 self.text_draw(900,50,30,"keep") # 文本 self.text_draw(900, 100, 30, "going") self.text_draw(820, 150, 20, "p1:") self.text_draw(820, 200, 20, "p2:") self.text_draw(900, 250, 20, "attention!") self.text_draw(900,300,20,"the bullet can") self.text_draw(900, 350, 20, "be control!") self.bar_draw(850, 145, self.pblood) # 血条 hit = pygame.sprite.groupcollide(self.enemy.bullet_groups, self.player_groups, true, false) # 血条减少 if hit: self.pblood = self.pblood - randint(10, 15) self.bar_draw(850, 145, self.pblood) self.bar_draw(850, 195, self.eblood) hit = pygame.sprite.groupcollide(self.player.bullet_groups, self.enemy_groups, true, false) if hit: self.eblood = self.eblood - randint(10, 15) self.bar_draw(850, 195, self.eblood) self.map_groups.draw(self.screen) # 画出图片 self.player_groups.draw(self.screen) self.enemy_groups.draw(self.screen) self.player.bullet_groups.draw(self.screen) self.enemy.bullet_groups.draw(self.screen) pygame.display.update() def bar_draw(self, x, y, pct): # 血条函数 # draw a bar if pct <= 0: pct = 0 bar_lenth = 100 bar_height = 10 fill_lenth = (pct / 100) * bar_lenth out_rect = pygame.rect(x, y, bar_lenth, bar_height) fill_rect = pygame.rect(x, y, fill_lenth, bar_height) pygame.draw.rect(self.screen, green, fill_rect) pygame.draw.rect(self.screen, red, out_rect, 2) def events(self): # 事件 for events in pygame.event.get(): if events.type == pygame.quit: self.running = false self.playing = false
在主循环内实现了很多功能,文本窗口展示,血条展示,以及整个游戏循环的定义都是可以拿来借鉴的,我也是从油管主上学来的。
接下来,精灵类,包含玩家,敌人。子弹,地图四部分。
# encoding : utf-8 # antuor : comi from setting import * from pygame import * import pygame,sys,time from random import * from math import * vec = pygame.math.vector2 # 运用向量 class player(pygame.sprite.sprite): # 玩家类 bullet_groups = pygame.sprite.group() flag = 1 # 判断方向的flag def __init__(self): pygame.sprite.sprite.__init__(self) self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert() # 图片的加载 self.image.set_colorkey(white) # 设置忽略白色 self.rect = self.image.get_rect() self.rect.midbottom = (115, 130) self.pos = vec(115, 130) self.last_time = time.time() #记录上一次时间 用来设置子弹频率等 def update(self): key_pressed = pygame.key.get_pressed() # 按键获取 if key_pressed[pygame.k_a]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\left.png').convert() self.image.set_colorkey(white) self.pos.x -= move_space # 位置移动 self.flag = 2 if key_pressed[pygame.k_d]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\right.png').convert() self.image.set_colorkey(white) self.pos.x += move_space self.flag = 1 if key_pressed[pygame.k_w]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\up.png').convert() self.image.set_colorkey(white) self.pos.y -= move_space self.flag = 3 if key_pressed[pygame.k_s]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert() self.image.set_colorkey(white) self.pos.y += move_space self.flag = 4 if key_pressed[pygame.k_space]: self.shoot() self.rect.midbottom = self.pos def shoot(self): # 开火 self.now = time.time() # 获取现在时间 if self.now - self.last_time > 0.8: # 子弹时间间隔 # 这里显示错误了,应该在if 语句内 包含以下部分 pygame.mixer.music.load(r'c:\users\administrator\desktop\keepgoing\sounds\expl.wav') pygame.mixer.music.play() # 音乐加载 bullet = bullet(self.pos.x, self.pos.y) self.bullet_groups.add(bullet) self.last_time = self.now class platform(pygame.sprite.sprite): # 地图创建 def __init__(self, x, y, w, h): # x,y,宽,高 pygame.sprite.sprite.__init__(self) self.image = pygame.surface((w, h)) # 砖块大小 self.image.fill(yellow) # 砖颜色 self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y class enemy(pygame.sprite.sprite): # 与player 相同 bullet_groups = pygame.sprite.group() flag = 1 def __init__(self): pygame.sprite.sprite.__init__(self) self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert() self.image.set_colorkey(white) self.rect = self.image.get_rect() self.rect.midbottom = (315, 130) self.pos = vec(315, 130) self.bar = 100 self.last_time = time.time() self.flag = 1 def update(self): key_pressed = pygame.key.get_pressed() if key_pressed[pygame.k_left]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\left.png').convert() self.image.set_colorkey(white) self.pos.x -= move_space self.flag = 2 if key_pressed[pygame.k_right]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\right.png').convert() self.image.set_colorkey(white) self.pos.x += move_space self.flag = 1 if key_pressed[pygame.k_up]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\up.png').convert() self.image.set_colorkey(white) self.pos.y -= move_space self.flag = 3 if key_pressed[pygame.k_down]: self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\down.png').convert() self.image.set_colorkey(white) self.pos.y += move_space self.flag = 4 if key_pressed[pygame.k_p]: self.shoot() self.rect.midbottom = self.pos def shoot(self): self.now = time.time() if self.now - self.last_time > 0.8: pygame.mixer.music.load(r'c:\users\administrator\desktop\keepgoing\sounds\expl.wav') pygame.mixer.music.play() bullet = bullet(self.pos.x, self.pos.y) self.bullet_groups.add(bullet) self.bullet_groups.update(self.flag) self.last_time = self.now class bullet(pygame.sprite.sprite): # 炮弹组 def __init__(self, x, y): # 炮弹该有的位置 玩家周围 pygame.sprite.sprite.__init__(self) self.image = pygame.image.load(r'c:\users\administrator\desktop\keepgoing\img\dot.png ').convert() self.image.set_colorkey(white) self.rect = self.image.get_rect() self.rect.centerx = x + 10 # 这里是准确的位置,未进行准确更改 self.rect.bottom = y - 12 self.speed = 5 def update(self,flag): if flag == 1: # right self.rect.x += self.speed if flag == 2: # left self.rect.x -= self.speed if flag == 3: #up self.rect.y -= self.speed if flag == 4: # down self.rect.y += self.speed
最后,便是相关的设置文件了
# encoding : utf-8 # author :comi width = 1000 height = 600 fps = 60 food = 20 gap = 3 move_space = 1.5 back_space = 5 map1 = [(0, 0, width*2, 10), (0, 10, 10, height * 2), (0, height-10, width * 2, 10), (width - 210, 0, 10, height * 2), (50,50,100,20),(250,50,100,20),(150,230,100,20),(100,340,200,20), (50, 70, 20, 90), (130, 70, 20, 90),(250,70,20,90),(330,70,20,90), (130,280,20,70),(250,300,20,50), (80,320,20,20),(300,320,20,20),(185,200,30,30),(185,250,30,30), (60,300,20,20),(320,300,20,20), (40,280,20,20),(340,280,20,20), (490,100,160,40),(650,100,40,200),(425,250,150,40),(425,290,40,80), (510,365,160,40),(695,460,95,40),(595,454,40,100),(190,460,30,30), (300,450,200,40),(100,425,30,130),(200,520,230,25),(725,70,30,30), (725,140,30,30),(725,210,30,30),(725,280,30,30),(725,365,30,30) ] # map # color black = (0, 0, 0) white = (255, 255, 255) red = (255, 0, 0) green = (0, 255,0) blue = (0, 0, 255) yellow = ( 255,200,0) purple = (128,138,135)
这个坦克大战还有一些小的bug,比如说,当你按下space 开火是,第一发炮弹已经出去了,当你按下相反方向,子弹会按你第二次按下的方向移动。(不打算解决,开始学习游戏ai,和横板游戏的制作)
有想法的同学可以和我交流,欢迎大家留言。
最后,运行效果如下 ,双人操作 p1:w a s d space 开火 p2: 上 下左 右 p 开火
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 补气的食物有哪些值得推荐
下一篇: JavaScript数组迭代方法