zoukankan      html  css  js  c++  java
  • 小白学Python做个小游戏

    用pygame模块做个小游戏

        Pygame是一个Python中专门用于多媒体应用(如电子游戏)的开发模块,其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上,SDL是一套跨平台的多媒体开发库,用C语言实现,被广泛的应用于游戏、模拟器、播放器等的开发。下面将用Pygame做一个“大球吃小球”的游戏,主要是加深对面向对象编程的理解。
    

    制作游戏窗口

    import pygame
    
    
    def main():
        # 初始化导入的pygame中的模块
        pygame.init()
        # 初始化用于显示的窗口并设置窗口尺寸
        screen = pygame.display.set_mode((800, 600))
        # 设置当前窗口的标题
        pygame.display.set_caption('大球吃小球')
        running = True
        # 开启一个事件循环处理发生的事件
        while running:
            # 从消息队列中获取事件并对事件进行处理
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
    
    
    if __name__ == '__main__':
        main()
    

    在窗口中绘图

        绘制好图形化窗口后,使用draw模块的函数在窗口上绘制我们需要的图形:线条,矩形,圆形等等,值的注意的是屏幕的坐标系原点在左上角,x轴正向朝右,y抽正向朝下。在表示位置和大小时,默认的单位都是像素,而像素就是屏幕上的一个点。pygame中颜色用的是色光的三原色:红绿蓝,通过一个元组或列表来指定颜色的RGB值,每个值都在0-255之间。
    
    
    import pygame
    
    
    def main():
        # 初始化导入的pygame中的模块
        pygame.init()
        # 初始化用于显示的窗口并设置窗口尺寸
        screen = pygame.display.set_mode((800, 600))
        # 设置当前窗口的标题
        pygame.display.set_caption('大球吃小球')
        # 设置窗口的背景色(颜色是由红绿蓝三原色构成的元组)
        screen.fill((242, 242, 242))
        # 绘制一个圆(参数分别是: 屏幕, 颜色, 圆心位置, 半径, 0表示填充圆)
        pygame.draw.circle(screen, (255, 0, 0,), (100, 100), 30, 0)
        # 刷新当前窗口(渲染窗口将绘制的图像呈现出来)
        pygame.display.flip()
        running = True
        # 开启一个事件循环处理发生的事件
        while running:
            # 从消息队列中获取事件并对事件进行处理
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
    
    
    if __name__ == '__main__':
        main()
    

    实现动画效果

        动画效果的实现其实就是让不连续的图片连续的播放,只要每秒中达到了一定的帧数,就能做出流畅的动画效果,而让小球动起来可以在循环中改变小球的位置,并刷新实现。
    
    import pygame
    
    
    def main():
        # 初始化导入的pygame中的模块
        pygame.init()
        # 初始化用于显示的窗口并设置窗口尺寸
        screen = pygame.display.set_mode((800, 600))
        # 设置当前窗口的标题
        pygame.display.set_caption('大球吃小球')
        # 定义变量来表示小球在屏幕上的位置
        x, y = 50, 50
        running = True
        # 开启一个事件循环处理发生的事件
        while running:
            # 从消息队列中获取事件并对事件进行处理
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
            screen.fill((255, 255, 255))
            pygame.draw.circle(screen, (255, 0, 0,), (x, y), 30, 0)
            pygame.display.flip()
            # 每隔50毫秒就改变小球的位置再刷新窗口
            pygame.time.delay(50)
            x, y = x + 5, y + 5
    
    
    if __name__ == '__main__':
        main()
    
    

    碰撞检测

        要求小球碰到墙壁会反弹,而2个球相撞,大球会吃掉小球。这里的碰撞检测直接检查2个小球的圆心距与半径和的关系就好,为了制造更多的小球,我们可以通过鼠标事件处理,在鼠标点击位置创建颜色、大小和移动速度不同的小球,这里就要使用面向对象的知识。
    
    class Ball(object):
        '''定义球'''
    
        def __init__(self, center, color, radius, sx, sy):
            '''初始化'''
            self._center = center
            self._color = color
            self._radius = radius
            self._sx = sx
            self._sy = sy
    
        @property
        def center(self):
            return self._center
    
        @property
        def radius(self):
            return self._radius
    
        @radius.setter
        def radius(self, radius):
            self._radius = radius
    
        def move(self):
            '''移动'''
            x, y = self._center[0], self._center[1]
            x += self._sx
            y += self._sy
            self._center = (x, y)
            if x + self._radius >= 800 or x - self._radius <= 0:
                self._sx = -self._sx
            if y + self._radius >= 600 or y - self._radius <= 0:
                self._sy = -self._sy
    
        def draw(self, screen):
            '''画球'''
            pygame.draw.circle(screen, self._color, self._center,self._radius, 0)#0表示实心,
    
        def eat(self, other):
            '''吃球'''
            x, y = self._center[0], self._center[1]
            x1, y1 = other.center[0], other.center[1]
            line = ((x - x1) ** 2 + (y - y1) ** 2) ** 0.5
            if line < (self._radius + other.radius):
                if self._radius < other.radius:
                    other.radius += round(((3.14*self._radius**2*0.5)**0.5 / 3.14)**0.5)
                    self._radius = 0
                elif self._radius > other.radius:
                    self._radius += round(((3.14*other.radius**2*0.5)**0.5 / 3.14)**0.5)
                    other.radius = 0
    
    
    def refresh(screen, balls):
        bg_color = (250, 250, 250)
        screen.fill(bg_color)
        for ball in balls:
            ball.draw(screen)
        pygame.display.flip()
    
    
    def random_color():
        red = randint(0, 255)
        green = randint(0, 255)
        blue = randint(0, 255)
        return red, green, blue
    
    
    

    事件处理

        游戏中通过点击鼠标获得不同小球,因此通过事件对象的type属性来判定事件类型,利用pos属性来获取鼠标点击位置。
    
    def main():
        balls = []
        pygame.init()
        screen = pygame.display.set_mode([800, 600])
        red_color = (255, 0, 0)
        ball = Ball((100, 100), red_color, 30, 3, 3)
        x, y = 200, 200
        pygame.display.set_caption('大球吃小球')
        clock = pygame.time.Clock()
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                #处理鼠标事件,1表示左键
                elif event.type == pygame.MOUSEBUTTONDOWN and \
                    event.button == 1:
                    center = event.pos
                    color = random_color()
                    radius = randrange(10, 50)
                    sx, sy = randint(-10, 10), randint(-10, 10)
                    ball = Ball(center, color, radius, sx, sy)
                    balls.append(ball)
            refresh(screen, balls)
            clock.tick(50)
            for index, ball in enumerate(balls):
                ball.move()
                for i in range(index,len(balls)):
                   ball.eat(balls[i])
    
        pygame.quit()#退出
    
    if __name__ == '__main__':
        main()
    
    
        合并以上2段代码就能做出一个很简单的小游戏,pygame做2D游戏尚可,如果要做3D游戏,可以使用Panda3D。
    

  • 相关阅读:
    easyui的dataGrid生成的日期时间,总是不能很好的兼容ie8和谷歌,终于摸索出一个合适的办法
    DELPHI使用TClientDataSet时不携带MIDAS.DLL的方法
    你又重新年轻了一次,这一次你打算怎么活?
    c#网站项目的发布:项目方式、webSite网站模式(未能获得项目引用XXX的依赖项的解决)
    当取不到raisError的错误信息只能取到return的错误代码时,可以取connection.errors[0].description
    layer iframe大致使用
    全选
    下拉选
    checkbox
    js判断值对否为空
  • 原文地址:https://www.cnblogs.com/bbszc520/p/8632933.html
Copyright © 2011-2022 走看看