会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 133322个问题
Python 全系列/第二阶段:Python 深入与提高/模块 1186楼
Python 全系列/第二阶段:Python 深入与提高/文件处理 1187楼
Python 全系列/第二阶段:Python 深入与提高/GUI编程(隐藏) 1188楼
Python 全系列/第二阶段:Python 深入与提高/模块 1189楼
Python 全系列/第二阶段:Python 深入与提高/异常机制 1190楼

'''
1.坦克类
    1.1 我方坦克
    1.2 敌方坦克
    坦克的显示
    坦克的移动
    坦克的射击

2. 子弹类
    显示子弹
    子弹的移动

3. 墙壁类
    显示墙壁

4. 爆炸的效果类
    显示爆炸效果

5. 音效类
    播放音效

6. 游戏主窗口类
    开始游戏
    结束游戏
'''

'''
坦克类
'''
import pygame
from time import sleep
import random

#设置通用属性
BG_COLOR = pygame.Color(156,156,156)
Screen_Width = 700
Screen_Height = 500
Text_Color = pygame.Color(255,0,0)

class Tank:
   
    def display_tank(self) -> None:
        '''
        显示坦克
        '''
        #获取最新坦克的朝向位置图片
        self.image = self.images.get(self.directon)
        MainGame.windows.blit(self.image,self.rect)
    def move(self) -> None:
        '''
        坦克移动
        '''
        if self.directon == 'L':
            #判断是否超出边界
            if self.rect.left > 0:
                #修改坦克的位置  离左边的距离
                self.rect.left -= self.speed
        elif self.directon == 'R':
            #判断是否超出边界
            if self.rect.left + self.rect.width < Screen_Width:
                #修改坦克的位置  离左边的距离
                self.rect.left += self.speed
        elif self.directon == 'U':
            #判断是否超出边界
            if self.rect.top > 0:
                #修改坦克的位置  离上边的距离
                self.rect.top -= self.speed
        elif self.directon == 'D':
            #判断是否超出边界
            if self.rect.top + self.rect.height < Screen_Height:
                #修改坦克的位置  离上边的距离
                self.rect.top += self.speed
    def shot(self) -> None:
        '''
        坦克射击
        '''
        pass

class Mytank(Tank):
    '''
    我方坦克
    '''
    def __init__(self,left,top) -> None:
        #设置我方坦克的图片资源
        self.images = {
            'U':pygame.image.load('./img/p1tankU.gif'),
            'D':pygame.image.load('./img/p1tankD.gif'),
            'L':pygame.image.load('./img/p1tankL.gif'),
            'R':pygame.image.load('./img/p1tankR.gif'),
        }
        #设置坦克的方向
        self.directon = 'L'
        #获取图片信息
        self.image = self.images.get(self.directon)
        #获取图形的矩形面积
        self.rect = self.image.get_rect()
        #设置我方坦克位置
        self.rect.left = left
        self.rect.top = top
        #设置移动速度
        self.speed = 15
        #设置移动开关
        self.remove = False

class Enemytank(Tank):
    '''
    敌方坦克
    '''
    def __init__(self,left,top,speed) -> None:
        self.images = {
            'U':pygame.image.load('./img/enemy1U.gif'),
            'D':pygame.image.load('./img/enemy1D.gif'),
            'L':pygame.image.load('./img/enemy1L.gif'),
            'R':pygame.image.load('./img/enemy1R.gif'),
        }
        #设置地方坦克的方向
        self.directon = self.rand_direction()
        #获取图片信息
        self.image = self.images.get(self.directon)
        #获取图像图形
        self.rect = self.image.get_rect()
        #设置敌方坦克位置
        self.rect.left = left
        self.rect.top = top
        #设置移动速度
        self.speed = speed
        #设置移动步长
        self.step = 30

    def rand_direction(self) -> str:
        '''
        生成随机方向
        '''
        chice = random.randint(1,4)
        if chice == 1:
            return 'U'
        elif chice == 2:
            return 'L'
        elif chice == 3:
            return 'D'
        elif chice == 4:
            return 'R'
   
    def rand_move(self):
        '''
        随机移动
        '''
        #判断步长是否为0
        if self.step <= 0:
            #如果小于0,更换方向
            self.directon = self.rand_direction()
            #重置步长
            self.step = 20
        else:
            #如果大于0,移动
            self.move()
            self.step -= 1
    def shot(self):
        '''
        敌方坦克的射击
        '''
        num = random.randint(1,100)
        if num < 9:
            return Bullet(self)

class Bullet:
    '''
    子弹类
    '''
    def __init__(self,tank) -> None:
        #加载图片
        self.image = pygame.image.load('./img/enemymissile.gif')
        #获取子弹的方向
        self.directon = tank.directon
        #获取子弹图形
        self.rect = self.image.get_rect()
        #设置子弹位置
        if self.directon =='L':
            #子弹的位置 = 坦克的位置+坦克的宽度/2 -子弹的宽度/2
            self.rect.top = tank.rect.top + tank.rect.height/2 - self.rect.height/2
            #子弹的位置 = 坦克的位置 - 子弹的宽度
            self.rect.left = tank.rect.left - self.rect.width
           
        elif self.directon =='R':
            #子弹的位置 = 坦克的位置+坦克的宽度/2 -子弹的宽度/2
            self.rect.top = tank.rect.top + tank.rect.height/2 - self.rect.height/2
            #子弹的位置 = 坦克的位置 - 子弹的宽度
            self.rect.left = tank.rect.left + self.rect.width
           
        elif self.directon =='U':
            #子弹的位置 = 坦克的位置+坦克的宽度/2 -子弹的宽度/2
            self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2
            #子弹的位置 = 坦克的位置 - 子弹的高度
            self.rect.top = tank.rect.top - self.rect.height

        elif self.directon =='D':
            #子弹的位置 = 坦克的位置+坦克的宽度/2 -子弹的宽度/2
            self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2
            #子弹的位置 = 坦克的位置 - 子弹的高度
            self.rect.top = tank.rect.top + self.rect.height
        #设置子弹的速度
        self.speed = 10

    def display_bullet(self) -> None:
        '''
        显示子弹
        '''
        MainGame.windows.blit(self.image,self.rect)
       
    def move_bullet(self) -> None:
        '''
        子弹的移动
        '''
        #根据子弹生成的方向来移动
        if self.directon == 'L':
            #判断子弹是否超出屏幕
            if self.rect.left > 0:
                self.rect.left -= self.speed

        elif self.directon == 'R':
            if self.rect.left + self.rect.width < Screen_Width:
                self.rect.left += self.speed
        elif self.directon == 'U':
            if self.rect.top > 0:
                self.rect.top -= self.speed
        elif self.directon == 'D':
            if self.rect.top + self.rect.height < Screen_Height:
                self.rect.top += self.speed

class Wall:
    '''
    墙壁类
    '''
    def __init__(self) -> None:
        pass
    def display_wall(self) -> None:
        '''
        显示墙壁
        '''
        pass

class Explode:
    '''
    爆炸效果类
    '''
    def __init__(self) -> None:
        pass
    def display_explode(self) -> None:
        '''
        显示爆炸效果
        '''
        pass

class Music:
    '''
    音乐类
    '''
    def __init__(self) -> None:
        pass
    def play_music(self) -> None:
        '''
        播放音效
        '''
        pass

class MainGame:
    '''
    游戏主窗口类
    '''
    #设置主窗口对象
    windows = None
    #设置我方坦克的位置
    my_tank = None
    #存储敌方坦克的列表
    enemy_tank_list = []
    #设置敌方坦克的数量
    enemy_tank_count = 6
    #存储我方子弹的列表
    my_bullet_list = []
    #存储敌方子弹列表
    enemy_bullet_list = []


    def __init__(self) -> None:
        pass
    def start_game(self) -> None:
        '''
        开始游戏
        '''
        pygame.display.init()
        #创建一个窗口
        MainGame.windows = pygame.display.set_mode((Screen_Width,Screen_Height))
        #设置窗口标题
        pygame.display.set_caption('坦克大战')
        #创建一个我方坦克
        MainGame.my_tank = Mytank(450,300)
        #创建敌方坦克
        self.creat_enemy_tank()

        #刷新窗口
        while True:
            sleep(0.06)
            #添加背景色
            MainGame.windows.fill(BG_COLOR)
            #增加提示文字
            #1. 增加文字的内容及字体
            #获得可用字体
            #num = 6
            text = self.get_text_surface(f'敌方坦克的剩余数量{MainGame.enemy_tank_count}')
            #2. 如何添加文字
            MainGame.windows.blit(text,(10,10))
            #增加事件
            self.get_event()
            #显示我方坦克
            MainGame.my_tank.display_tank()
            #显示敌方坦克
            self.display_enemy_tank()
            #一直移动坦克
            if MainGame.my_tank.remove:
                MainGame.my_tank.move()
            #显示我方子弹
            self.display_my_bullet()
            #显示敌方子弹
            self.display_enemy_bullet()
            pygame.display.update()
           
    def display_my_bullet(self) -> None:
        '''
        显示我方子弹
        '''
        for my_bullet in MainGame.my_bullet_list:
            #显示我方子弹
            my_bullet.display_bullet()
            #移动我方子弹
            my_bullet.move_bullet()

    def creat_enemy_tank(self) -> None:
        '''
        创建地方坦克
        '''
        self.enemy_top = 100
        self.enemy_speed = 8
        for i in range(self.enemy_tank_count):
            #生成坦克位置
            left = random.randint(0,600)
            #创建敌方坦克
            e_tank = Enemytank(left,self.enemy_top,self.enemy_speed)
            #将敌方坦克添加到列表中
            self.enemy_tank_list.append(e_tank)

    def display_enemy_tank(self) -> None:
        '''
        显示敌方坦克
        '''
        for e_tank in self.enemy_tank_list:
            #显示敌方坦克
            e_tank.display_tank()
            #移动敌方坦克
            e_tank.rand_move()
            #发射子弹
            e_bullet = e_tank.shot()
            #判断是否有子弹
            if e_bullet:
                #将子弹添加到列表中
                MainGame.enemy_bullet_list.append(e_bullet)
               
   
    def display_enemy_bullet(self) -> None:
        '''
        显示敌方子弹
        '''
        for e_bullet in MainGame.enemy_bullet_list:
            #显示子弹
            # if e_bullet.live:
                # 如果存活
                    e_bullet.display_bullet()
                    e_bullet.move_bullet()
            # else:
                #如果子弹不存活
                # MainGame.enemy_bullet_list.remove(e_bullet)
               
    def get_text_surface(self,text:str) -> None:
        '''
        获取文字的图片
        '''
        #初始化字体模块
        pygame.font.init()
        # #获取可以使用的所有字体
        # print(pygame.font.get_fonts())
        #创建字体
        font = pygame.font.SysFont('kaiti',18)
        #绘制文字内容
        text_surface = font.render(text,True,Text_Color)
        #将绘制的文字信息返回
        return text_surface
    def get_event(self) -> None:
        '''
        获取事件
        '''
        #获取所有事件
        event_list = pygame.event.get()
        for event in event_list:
            #判断是什么事件,然后做吹相应的处理
            if event.type == pygame.QUIT:
                #点击X退出游戏
                self.end_game()
            if event.type == pygame.KEYDOWN:
                #按下键盘
                if event.key == pygame.K_LEFT:
                    print('坦克向左移动')
                    #修改方向
                    MainGame.my_tank.directon = 'L'
                    #修改坦克可以移动
                    MainGame.my_tank.remove = True
                    #通过坦克对象
                    # MainGame.my_tank.move()
                elif event.key == pygame.K_RIGHT:
                    print('坦克向右移动')
                    MainGame.my_tank.directon = 'R'
                    #修改坦克可以移动
                    MainGame.my_tank.remove = True
                    # MainGame.my_tank.move()
                elif event.key == pygame.K_UP:
                    print('坦克向上移动')
                    MainGame.my_tank.directon = 'U'
                    #修改坦克可以移动
                    MainGame.my_tank.remove = True
                    # MainGame.my_tank.move()
                elif event.key == pygame.K_DOWN:
                    print('坦克向下移动')
                    MainGame.my_tank.directon = 'D'
                    #修改坦克可以移动
                    MainGame.my_tank.remove = True
                    # MainGame.my_tank.move()
                elif event.key == pygame.K_SPACE:
                    #发射子弹
                    print('发射子弹')
                    #创建子弹
                    m_bullet = Bullet(MainGame.my_tank)
                    #将子弹添加到列表中
                    MainGame.my_bullet_list.append(m_bullet)

            if event.type == pygame.KEYUP and event.key in (pygame.K_LEFT,pygame.K_RIGHT,pygame.K_UP,pygame.K_DOWN):
                #修改坦克的移动状态
                MainGame.my_tank.remove = False

            #可以吧循环体中的move模块都移动到这里
            # MainGame.my_tank.move()

    def end_game(self) -> None:
        '''
        结束游戏
        '''
        print('结束游戏,欢迎再次使用')
        exit()


if __name__ == '__main__':
    #调用MainGame中的start_game方法,开始游戏
    MainGame().start_game()
    
    
    
    
    Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "e:\VScode\TANK_GAME\17. 敌方坦克发射子弹.py", line 460, in <module>
    MainGame().start_game()
  File "e:\VScode\TANK_GAME\17. 敌方坦克发射子弹.py", line 324, in start_game
    self.display_enemy_bullet()
  File "e:\VScode\TANK_GAME\17. 敌方坦克发射子弹.py", line 374, in display_enemy_bullet
    if e_bullet.live:
       ^^^^^^^^^^^^^
AttributeError: 'Bullet' object has no attribute 'live'
这个‘live’命令是系统自带的吗,为什么我在调用的时候提醒我没有这个目标呢

Python 全系列/第二阶段:Python 深入与提高/坦克大战 1191楼
Python 全系列/第二阶段:Python 深入与提高/文件处理 1195楼
Python 全系列/第二阶段:Python 深入与提高/模块 1196楼

老师,你看这个是按照上面敲得,有按钮,但是按钮没反应,也不报错,这是怎么回事?

# 开发画笔软件
from tkinter.filedialog import *
from tkinter.colorchooser import *

win_width=900;win_height=450

class Application(Frame):
    def __init__(self,master=None,bg='#000000'):
        super().__init__(master)
        self.x = 0
        self.y = 0
        self.bg=bg
        self.fg='#ff0000'
        self.lastDraw=0
        self.starDrawFlag=False
        self.pack()
        self.createWidget()

    def createWidget(self):
        # 绘图区
        self.drawpad = Canvas(self,width=win_width,
                height=win_height*0.9,bg=self.bg)
        self.drawpad.pack()

        # 设定按钮
        btn_start=Button(self,text='开始',name='start')
        btn_start.pack(side='left',padx='10')
        btn_pen = Button(self, text='画笔', name='pen')
        btn_pen.pack(side='left', padx='10')
        btn_rect = Button(self, text='矩形', name='rect')
        btn_rect.pack(side='left', padx='10')
        btn_clear = Button(self, text='清屏', name='clear')
        btn_clear.pack(side='left', padx='10')
        btn_eraser = Button(self, text='橡皮擦', name='eraser')
        btn_eraser.pack(side='left', padx='10')
        btn_line = Button(self, text='直线', name='line')
        btn_line.pack(side='left', padx='10')
        btn_lineArrow = Button(self, text='箭头直线', name='lineArrow')
        btn_lineArrow.pack(side='left', padx='10')
        btn_color = Button(self, text='颜色', name='color')
        btn_color.pack(side='left', padx='10')

        # 事件处理
        btn_pen.bind_class('Button','<1>',self.eventManager)
        self.drawpad.bind('<ButtonRelease-1>',self.stopDraw)

        # 增加颜色切换的快捷键
        root.bind('<KeyPress-r>',self.kuaijiejian)
        root.bind('<KeyPress-g>', self.kuaijiejian)
        root.bind('<KeyPress-y>', self.kuaijiejian)

    def eventManager(self,event):
        name=event.widget.winfo_name()
        if name == 'line':
            self.drawpad.bind('<B1-Motion>',self.myline)
        elif name == 'lineArrow':
            self.drawpad.bind('<B1-Motion>',self.mylineArrow)
        elif name == 'rect':
            self.drawpad.bind('<B1-Motion>',self.myrect)
        elif name == 'pen':
            self.drawpad.bind('<B1-Motion>',self.mypen)
        elif name == 'eraser':
            self.drawpad.bind('<B1-Motion>',self.myeraser)
        elif name == 'clear':
            self.drawpad.delete('all')
        elif name == 'color':
            c = askcolor(color=self.fg,title='选择画笔颜色')
            self.fg=c[1]

    def stopDraw(self,event):
        self.startDrawFlag=False
        self.lastDraw=0

    def startDraw(self,event):
        self.drawpad.delete(self.lastDraw)
        if not self.startDrawFlag:
            self.starDrawFlag=True
            self.x=event.x
            self.y=event.y

    def myline(self,event):
        self.startDraw(event)
        self.lastDraw=self.drawpad.\
            create_line(self.x,self.y,event.x,event.y,fill=self.fg)

    def mylineArrow(self,event):
        self.startDraw(event)
        self.lastDraw=self.drawpad.create_line(self.x,self.y,
                    event.x,event.y,arrow=LAST,fill=self.fg)

    def myrect(self,event):
        self.startDraw(event)
        self.lastDraw=self.drawpad.create_rectangle(self.x,self.y,
                    event.x,event.y,outline=self.fg)

    def mypen(self,event):
        self.startDraw(event)
        self.drawpad.create_line(self.x,self.y,event.x,event.y,
                    fill=self.fg)
        self.x=event.x
        self.y=event.y

    def myeraser(self,event):
        self.startDraw(event)
        self.drawpad.create_rectangle(event.x-4,event.y-4,
                    event.x+4,event.y+4,fill=self.bg)
        self.x=event.x
        self.y=event.y

    def kuaijiejian(self,event):
        if event.char=='r':
            self.fg='#ff0000'
        elif event.char=='g':
            self.fg='#00ff00'
        elif event.char=='y':
            self.fg='#ffff00'

if __name__ == '__main__':
    root=Tk();root.geometry(str(win_width)+'x'+str(win_height)+'+200+300')
    root.title('百战程序员的画图软件')
    app=Application(master=root)
    root.mainloop()


Python 全系列/第二阶段:Python 深入与提高/GUI编程(隐藏) 1197楼
Python 全系列/第二阶段:Python 深入与提高/GUI编程(隐藏) 1199楼

# coding= utf-8

"""坦克大战设计
   新增功能:
            加载我方坦克"""

import pygame


screen_width=700
screen_height=500
bg_color=pygame.Color(0,0,0)  # RGB值: 000为黑色
COLOR_PINK =pygame.Color(255,192,203)

# 主类
class MainGame():
    window = None
    my_tank= None
    def __init__(self):
        pass

    # start game (开始游戏)
    def startGame(self):
        # load main window(加载主窗口)
        # initial window(初始化窗口)
        pygame.display.init()

        # set size and display window(设计窗口大小并显示窗口)
        MainGame.window=pygame.display.set_mode([screen_height,screen_width])

        # 初始化我方坦克
        MainGame.window=Tank(350,250)

        # set title for window (设计窗口标题)
        pygame.display.set_caption('Tank War 666')
        while True:
            # set fill color for window(给窗口设置填充色)
            MainGame.window.fill(bg_color)
            # 获取事件
            self.getEvent()

            # 绘制文字
            MainGame.window.blit(self.getText('enemy tanks%d'%5),(10,10))

            # 调用坦克显示的方法
            MainGame.my_tank.displayTank()

            # 一直更新显示窗口
            pygame.display.update()

    # exit game   (退出游戏)
    def exitGame(self):
        print('tanks,bye')
        exit()

    # 左上角文字的绘制
    def getText(self,text):
        # 初始化字体模块
        pygame.font.init()
        #  查看所有的字体
        # print(pygame.font.get_fonts())
        # 获取字体font对象
        font= pygame.font.SysFont('calibri', 20)
        #获取字体
        text = font.render(text, True,COLOR_PINK)
        return text


    # get event  (获取事件)
    def getEvent(self):
        #获取所有事件
        eventList= pygame.event.get()

        # 遍历事件
        for event in eventList:
            # 判断按下的键是关闭还是键盘按下
            # 如果按的是退出,则关闭窗口
            if event.type == pygame.QUIT:
                self.exitGame()
            # 如果是键盘的按下
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    print('press key Left, turn left')
                elif event.key == pygame.K_RIGHT:
                    print('press key Left, turn right')
                elif event.key == pygame.K_UP:
                    print('press key Left, turn up')
                elif event.key == pygame.K_DOWN:
                    print('press key Left, turn Down')
# 坦克类
class Tank():
    # 添加距离左边left 距离上边top
    def __init__(self,left,top):
        # 保存加载的图片
        self.images={'U':pygame.image.load('../img/p1tankU.gif'),
                     'D':pygame.image.load('../img/p1tankD.gif'),
                     'L':pygame.image.load('../img/p1tankL.gif'),
                     'R':pygame.image.load('../img/p1tankR.gif'),
                     }
        # 方向
        self.direction='L'
        # 根据当前图片方向获取图片 surface
        self.image=self.images[self.direction]
        # 根据图片获取区域
        self.rect=self.image.get_rect()
        # 设置区域的left和top
        self.rect.left=left
        self.rect.top=top



    # move(移动)
    def move(self):
        pass

    # shot(射击)
    def shot(self):
        pass

    # show tank(展示坦克的方法)
    def displayTank(self):
        # 获取展示对象
        self.image=self.images[self.direction]
        # 调用blit方法展示
        MainGame.window.blit(self.image, self.rect)

# our team tank(我方坦克)
class MyTank(Tank):
    def __init__(self):
        pass

# enemy tank(敌方坦克)
class EnemyTank(Tank):
    def __init__(self):
        pass

# bullet(子弹类)
class Bullet():
    def __init__(self):
        pass
    # move (移动)
    def move(self):
        pass
    # display bullet(展示子弹)
    def displayBullet(self):
        pass



# wall class(墙壁类)

class Wall():
    def __init__(self):
        pass

    # display wall (展示墙壁的方法)
    def displayWall(self):
        pass

class Explode():
    def __init__(self):
        pass

    # display explode (展示爆炸的方法)
    def displayExplode(self):
        pass

# music (音效类)
class Music():
    def __init__(self):
        pass

    # play music(播放音乐)
    def playMusic(self):
        pass


if __name__ =='__main__':
    MainGame().startGame()

    # MainGame().getText()  ( 打印查看字体)

老师我这个程序总是闪一下就退了,查了一下没查出来什么原因

Python 全系列/第二阶段:Python 深入与提高/游戏开发-坦克大战 1200楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637