精华内容
下载资源
问答
  • PYTHON文字游戏

    2018-03-28 13:20:47
    PYTHON文字游戏
  • 本教程将”游戏驱动,实战为主”作为出发点,详细介绍Python语言的基础知识,教程中剖析了六个典型的Python游戏,以培养学员解决问题的能力。理论与项目的完美结合是本系列教程的特色,做到让学员学以致用。 本教程...
  • Python做一个推箱子小游戏
  • 手把手教你用python游戏

    万次阅读 多人点赞 2018-01-17 21:41:10
    最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏、后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python游戏,项目来自《Python编程从入门到实践》...

    引言

    最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏、后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,项目来自《Python编程从入门到实践》(本文将原项目中的部分错误进行修改完善,PS:强烈推荐这本书,真的很赞),来感受下其中的有趣之处。本次开发的游戏叫做alien invasion。

    安装pygame并创建能左右移动的飞船

    安装pygame

    本人电脑是windows 10、python3.6,pygame下载地址:传送门
    请自行下载对应python版本的pygame
    运行以下命令

    $ pip install wheel
    $ pip install pygame‑1.9.3‑cp36‑cp36m‑win_amd64.whl

    创建Pygame窗口及响应用户输入

    新建一个文件夹alien_invasion,并在文件夹中新建alien_invasion.py文件,输入如下代码。

    import sys
    import pygame
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        screen = pygame.display.set_mode((1200,800))
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # fill color
            screen.fill(bg_color)
            # visualiaze the window
            pygame.display.flip()
    run_game()

    运行上述代码,我们可以得到一个灰色界面的窗口:

    $ python alien_invasion.py

    这里写图片描述

    创建设置类

    为了在写游戏的过程中能便捷地创建一些新功能,下面额外编写一个settings模块,其中包含一个Settings类,用于将所有设置存储在一个地方。这样在以后项目增大时修改游戏的外观就更加容易。
    我们首先将alien_invasion.py中的显示屏大小及显示屏颜色进行修改。
    首先在alien_invasion文件夹下新建python文件settings.py,并向其中添加如下代码:

    class Settings(object):
        """docstring for Settings"""
        def __init__(self):
            # initialize setting of game
    
            # screen setting
            self.screen_width = 1200
            self.screen_height = 800
            self.bg_color = (230,230,230)

    然后再alien_invasion.py中导入Settings类,并使用相关设置,修改如下:

    import sys
    import pygame
    from settings import Settings
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # fill color
            screen.fill(ai_settings.bg_color)
            # visualiaze the window
            pygame.display.flip()
    run_game()

    添加飞船图像

    接下来,我们需要将飞船加入游戏中。为了在屏幕上绘制玩家的飞船,我们将加载一幅图像,再使用Pygame()方法blit()绘制它。
    在游戏中几乎可以使用各种类型的图像文件,但是使用位图(.bmp)文件最为简单,这是因为Pygame默认加载位图。虽然其他类型的图像也能加载,但是需要安装额外的库。我们推荐去免费的图片素材网站上去找图像:传送门。我们在主项目文件夹(alien_invasion)中新建一个文件夹叫images,将如下bmp图片放入其中。
    这里写图片描述
    接下来,我们创建飞船类ship.py:

    import pygame
    class Ship():
    
        def __init__(self,screen):
            #initialize spaceship and its location
            self.screen = screen
    
            # load bmp image and get rectangle
            self.image = pygame.image.load('image/ship.bmp')
            self.rect = self.image.get_rect()
            self.screen_rect = screen.get_rect()
    
            #put spaceship on the bottom of window
            self.rect.centerx = self.screen_rect.centerx
            self.rect.bottom = self.screen_rect.bottom
    
        def blitme(self):
            #buld the spaceship at the specific location
            self.screen.blit(self.image,self.rect)

    最后我们在屏幕上绘制飞船,即在alien_invasion.py文件中调用blitme方法:

    import sys
    import pygame
    from settings import Settings
    from ship import Settings
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        ship = Ship(screen)
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # fill color
            screen.fill(ai_settings.bg_color)
            ship.blitme()
            # visualiaze the window
            pygame.display.flip()
    run_game()

    重构:模块game_functions

    在大型项目中,经常需要在添加新代码前重构既有代码。重构的目的是为了简化代码的结构,使其更加容易扩展。我们将实现一个game_functions模块,它将存储大量让游戏Alien invasion运行的函数。通过创建模块game_functions,可避免alien_invasion.py太长,使其逻辑更容易理解。

    函数check_events()

    首先我们将管理事件的代码移到一个名为check_events()的函数中,目的是为了隔离事件循环

    import sys
    import pygame
    
    def check_events():
        #respond to  keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

    然后我们修改alien_invasion.py代码,导入game_functions模块,并将事件循环替换成对函数check_events()的调用:

    import sys
    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        ship = Ship(screen)
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            gf.check_events()
            # fill color
            screen.fill(ai_settings.bg_color)
            ship.blitme()
            # visualiaze the window
            pygame.display.flip()
    run_game()

    函数update_screen()

    将更新屏幕的代码移到一个名为update_screen()函数中,并将这个函数放在模块game_functions中:

    def update_screen(ai_settings,screen,ship):
        # fill color
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        # visualiaze the window
        pygame.display.flip()

    其中alien_invasion修改如下:

    import sys
    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        ship = Ship(screen)
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            gf.check_events()
            gf.update_screen(ai_settings,screen,ship)
    run_game()

    从上面一套流程走下来,我们发现:在实际的开发过程中,我们一开始将代码编写得尽可能的简单,并在项目越来越复杂时进行重构。接下来我们开始处理游戏的动态方面。

    驾驶飞船

    这里我们要实现的就是使玩家通过左右箭头键来控制飞船的左移与右移。

    响应按键

    因为在pygame中,每次按键都被注册为KEYDOWN事件,在check_events()中,我们通过event.type检测到KEYDOWN事件后还需进一步判断是哪个按键。代码如下:

    def check_events(ship):
        #respond to  keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    #move right
                    ship.rect.centerx +=1

    允许不断移动

    玩家按住右箭头不动时,我们希望飞船能不断地移动,知道玩家松开为止。这里我们通过KETUO事件来判断。因此我们设置一个标志位moving_right来实现持续移动。原理如下:

    飞船不动时,标志moving_right将为false。玩家按下右箭头时,我们将这个标志设置为True;玩家松开时,我们将标志重新设置成False。

    这个移动属性是飞船属性的一种,我们用ship类来控制,因此我们给这个类增加一个属性名称叫,moving_right以及一个update()方法来检测标志moving_right的状态。
    ship

            self.moving_right = False
        def update(self):
            if self.moving_right:
                self.rect.centerx +=1

    game_functions

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    #move right
                    ship.moving_right = True
            elif event.type == pygame.KEYUP:
                if event.key = pygame.K_RIGHT:
                    ship.moving_right = False

    最后在alien_invasion中调用update()方法

        while True:
            # supervise keyboard and mouse item
            gf.check_events(ship)
            ship.update()

    左右移动

    前面我们实现了向右移动,接下来实现向左移动,逻辑类似,代码就不贴了。

    调整飞船的速度

    当前,每次执行while循环时,飞船最多移动一个像素,我们可以在Settings中添加ship_speed_factor,用于控制飞船的速度。我们将根据这个属性决定飞船每次循环时最多移动多少距离。
    Settings:

    class Settings(object):
        """docstring for Settings"""
        def __init__(self):
            # initialize setting of game
    
            # screen setting
            self.screen_width = 1200
            self.screen_height = 800
            self.bg_color = (230,230,230)
            self.ship_speed_factor = 1.5

    Ship:

    class Ship():
    
        def __init__(self,ai_settings,screen):
            #initialize spaceship and its location
            self.screen = screen
            self.ai_settings = ai_settings

    限制飞船的活动范围

    如果玩家按住箭头的时间过长,飞船就会消失,那么如何使飞船抵达屏幕边缘时停止移动?这里我们只需要修改Ship类中的update方法,增加一个逻辑判断。

    重构

    这里我们主要讲check_events()函数进行重构,将其中部分代码分成两部分,一部分处理KEYDOWN事件,一部分处理KEYUP事件。
    game_functions:

    def check_keydown_events(event,ship):
        if event.key == pygame.K_RIGHT:
            #move right
            ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            #move right
            ship.moving_left = True 
    def check_keyup_events(event,ship):
        if event.key == pygame.K_RIGHT:
            ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            #move right
            ship.moving_left = False
    def check_events(ship):
        #respond to  keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                check_keydown_events(event,ship)
            elif event.type == pygame.KEYUP:
                check_keyup_events(event,ship)

    射击

    接下来添加射击功能,使玩家按空格键时发射子弹,子弹将在屏幕中向上穿行,抵达屏幕后消失。

    添加子弹设置

    在Settings类中增加一些子弹的属性,这里我们创建一个宽3像素,高15像素的深灰色子弹。子弹的速度比飞船稍低。

    创建Bullet类

    import pygame
    from pygame.sprite import Sprite
    
    class Bullet(Sprite):
        """A class to manage bullets fired from the ship."""
    
        def __init__(self, ai_settings, screen, ship):
            """Create a bullet object, at the ship's current position."""
            super().__init__()
            self.screen = screen
    
            # Create bullet rect at (0, 0), then set correct position.
            self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
                ai_settings.bullet_height)
            self.rect.centerx = ship.rect.centerx
            self.rect.top = ship.rect.top
    
            # Store a decimal value for the bullet's position.
            self.y = float(self.rect.y)
    
            self.color = ai_settings.bullet_color
            self.speed_factor = ai_settings.bullet_speed_factor
    
        def update(self):
            """Move the bullet up the screen."""
            # Update the decimal position of the bullet.
            self.y -= self.speed_factor
            # Update the rect position.
            self.rect.y = self.y
    
        def draw_bullet(self):
            """Draw the bullet to the screen."""
            pygame.draw.rect(self.screen, self.color, self.rect)

    将子弹存储到group中

    前面定义了Bullet类和必要的设置后,就可以编写代码了,在玩家每次按空格键时都会发射一发子弹。首先,我们在alien_invasion中创建一个group,用于存储所有的有效子弹。

    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        ship = Ship(ai_settings,screen)
        bullets = Group()
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            gf.check_events(ai_settings, screen, ship,bullets)
            ship.update()
            bullets.update()
            gf.update_screen(ai_settings, screen, ship,bullets)

    开火

    这里我们修改check_keydown_events()函数,来监听玩家按下空格键的事件。这里还需要修改update_screen()函数,确保屏幕每次更新时,都能重绘每一个子弹。
    我们来看下效果:
    这里写图片描述

    删除消失的子弹

    在alien_invasion中删除消失的子弹。

    import sys
    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    from pygame.sprite import Group
    def run_game():
        #initialize game and create a dispaly object
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
        ship = Ship(ai_settings,screen)
        bullets = Group()
        pygame.display.set_caption("Alien Invasion")
        # set backgroud color
        bg_color = (230,230,230)
    
        # game loop
        while True:
            # supervise keyboard and mouse item
            gf.check_events(ai_settings, screen, ship,bullets)
            ship.update()
            bullets.update()
            for bullet in bullets.copy():
                if bullet.rect.bottom <=0:
                    bullets.remove(bullet)
            gf.update_screen(ai_settings, screen,ship,bullets)
    run_game()

    限制子弹数量

    为了鼓励玩家有目标的射击,我们规定屏幕上只能同时存在3颗子弹,我们只需要在每次创建子弹前检查未消失的子弹数目是否小于3即可。

    创建update_bullets()函数

    为了使alien_invasion中代码更加简单,我们将检查子弹管理的代码,移到game_functions模块中:

    def update_bullets(bullets):
        bullets.update()
        for bullet in bullets.copy():
            if bullet.rect.bottom<=0:
                bullets.remove(bullet)

    创建fire_bullet()函数

    这里我们将发射子弹的代码移到一个独立的函数中:

    def fire_bullet(ai_settings,screen,ship,bullets):
        if len(bullets) < ai_settings.bullets_allowed:
            new_bullet = Bullet(ai_settings,screen,ship)
            bullets.add(new_bullet) 

    添加外星人,并检测碰撞

    在我们完成新的任务之前,我们先给游戏添加一个结束游戏的快捷键Q:

    创建第一个外星人

    这里和创建飞船的方法一样

    class Alien(Sprite):
        """A class to represent a single alien in the fleet."""
    
        def __init__(self, ai_settings, screen):
            """Initialize the alien, and set its starting position."""
            super().__init__()
            self.screen = screen
            self.ai_settings = ai_settings
    
            # Load the alien image, and set its rect attribute.
            self.image = pygame.image.load('images/alien.bmp')
            self.rect = self.image.get_rect()
    
            # Start each new alien near the top left of the screen.
            self.rect.x = self.rect.width
            self.rect.y = self.rect.height
    
            # Store the alien's exact position.
            self.x = float(self.rect.x)
        def blitme(self):
            """Draw the alien at its current location."""
            self.screen.blit(self.image, self.rect)

    创建一群外星人

    这里我们首先确定一行能容纳多少个外星人以及要绘制几行。这里改动代码较多,直接看效果:
    这里写图片描述

    移动外星人

    前面我们创建的是静态的外星人,现在我们需要让外星人动起来。这里我们在Settings类中设置外星人移动的速度,然后通过Alien类中的update的方法来实现移动

    射杀外星人

    要想射杀外星人,就必须先检测两个编组成员之间是否发生碰撞,在游戏中,碰撞就是游戏元素重叠在一起。这里我们使用sprite.groupcollide()来检测两个编组的成员之间的碰撞。
    子弹击中外星人时,需要立马知道,并同时使被碰撞的外星人立即消失,因此我们需要在更新子弹的位置后立即检测碰撞。

    结束游戏

    这里我们还需要知道何时该结束游戏,有以下几种情况:

    • 飞船全部被摧毁
    • 外星人到达屏幕底部

    实际效果:
    这里写图片描述

    计分

    最后我们将给游戏添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏。我们还将实现一个计分系统,能够在玩家等级提高时加快节奏。

    添加Play按钮

    这里可以先将游戏初始化为非活动状态,当我们点击了按钮,就开始游戏。由于Pygame中没有内置的创建按钮的方法。因此我们可以通过创建一个Button类来创建一个自带标签的实心矩形。我们通过检测鼠标发生点击后的坐标是否与我们绘制的按钮发生碰撞与否来判断是否发生了点击事件。

    提高等级

    为了使玩家将敌人消灭干净后能够提高游戏难度,增加趣味性,这里我们可以在Settings类中进行修改,增加静态初始值,和动态初始值。

    记分、等级、剩余飞船

    这里写图片描述

    打包成exe可执行文件

    上面游戏开发完了,那么你需要将其转成文exe的可执行文件。我们采用pyinstaller,安装步骤参考:传送门

    项目代码

    github地址:传送门

    展开全文
  • Python游戏】用AI玩Python游戏FlappyBird【源码】

    千次阅读 多人点赞 2021-05-02 21:38:15
    本项目是作者实现用AI玩Python游戏中的游戏逻辑部分,暂不会牵扯到相关的AI逻辑,当然为了便于AI训练,该游戏进行了一定的简化处理,没有添加开始游戏等其他界面。 一、Flappy Bird是什么? Flappy Bird是一款...

    提示:如果本文对您有帮助,欢迎点赞支持!



    前言

    本项目是作者实现用AI玩Python小游戏中的游戏逻辑部分,暂不会牵扯到相关的AI逻辑,当然为了便于AI训练,该游戏进行了一定的简化处理,没有添加开始游戏等其他界面。


    一、Flappy Bird是什么?

    Flappy Bird是一款玩家要在游戏中尽可能长地维持小鸟生命的游戏。

    小鸟不断向前飞行,会遇到一系列高低不同的管道,管道将小鸟通过的高度限制在特定的范围内。

    小鸟由于重力会自动掉落到地面,所以玩家需要不断操作使小鸟进行Flap,躲避管道和地面,游戏分数由小鸟成功通过多少个管道障碍物来衡量。

    如果小鸟撞到地面或者管道,它就会死亡并结束游戏。

    二、本项目简介

    1.实现效果

    20210502_164334.gif20210502_184743.gif20210502_211029.gif20210502_212711.gif

    2.游戏逻辑的相关链接

    (1)游戏逻辑部分

    【FlappyBird小游戏】编写游戏逻辑(一)——基本游戏主循环【源码】

    【FlappyBird小游戏】编写游戏逻辑(二)——读取游戏资源【源码】

    【FlappyBird小游戏】编写游戏逻辑(三)——添加Bird和Pipe【源码】

    【FlappyBird小游戏】编写游戏逻辑(四)——控制Bird和碰撞检测【源码】

    如果读者不想一篇篇阅读博客,习惯直接看代码的话,可以找到在我的资源中找到该下载链接。

    下载后将会得到如下文件资源:

    (2)AI训练逻辑部分

    【FlappyBird小游戏】编写AI逻辑(一)——RL系统和数据预处理

    【FlappyBird小游戏】编写AI逻辑(二)——基于队列的经验重放池

    【FlappyBird小游戏】编写AI逻辑(三)——RL算法的训练主循环

    【FlappyBird小游戏】编写AI逻辑(四)——搭建CNN网络

    【FlappyBird小游戏】编写AI逻辑(五)——定义计算图与学习机制

    该部分代码将会在GitHub上开源,其相关地址为:https://github.com/MagicDeveloperDRL/MRL-AIFlappyBird-Python-master

    我们使用的基于CNN的DQN算法来训练AI-Bird,其计算图结构如下:

    说明

    该项目没有在Github开源的主要原因是因为近期部分用户不怀好意直接下载了我的一些源码拿去赚积分,让我处理起来很不愉快,所以该项目就将源码拆分到一篇篇博客中。

    如果读者在阅读或者使用源码的过程中遇到该项目的技术性问题,可以直接私信我或者评论,相互交流,共同进步!

     

    展开全文
  • pygame开发小游戏,附录完整代码。【建议收藏】

    大家好,我是Lex 喜欢欺负超人那个Lex

    划重点:马上就到毕业季了,你心中的那个学姐,你真的放下了吗?

    今天跟着lex,用pygame为你的学姐,定制开发一个拼图游戏【完整项目代码】

    代码干货满满,建议收藏+实操!!!有问题及需要,请留言哦~~

    事情是这样的

    马上就快到毕业季了,大四的学姐们快要离校了

    你心中那个没有说出口的学姐,你还记得吗

    跟着博主,用pygame给你心中那个学姐

    做一款专属于她的拼图游戏

    万一有什么意外收获呢?

    先上效果

    我用隔壁诗诗学姐的照片,给她做了一个拼图游戏

    结果,我自己的拼不出来了

    配置环境

    安装pygame模块

    #pip install pygame
    
    PS C:\Users\lex> pip install pygame Looking in indexes: 
    http://mirrors.aliyun.com/pypi/simple Requirement already satisfied:
     pygame in f:\develop\python36\lib\site-packages (2.0.1)
    
    PS C:\Users\lex>

    配置文件

    cfg.py

    配置需要读取的学姐的照片路径、引入游戏引用到的字体及颜色。

    '''配置文件'''
    import os
    
    '''屏幕大小'''
    SCREENSIZE = (640, 640)
    '''读取学姐照片'''
    PICTURE_ROOT_DIR = os.path.join(os.getcwd(), 'resources/pictures')
    '''字体路径'''
    FONTPATH = os.path.join(os.getcwd(), 'resources/font/FZSTK.TTF')
    '''定义一些颜色'''
    BACKGROUNDCOLOR = (255, 255, 255)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    BLACK = (0, 0, 0)
    '''FPS'''
    FPS = 40
    '''随机打乱拼图次数'''
    NUMRANDOM = 100

    引入资源

    将诗诗学姐的照片,添加到resources/pictures路径下,

    游戏启动时,根据我们在cfg.py中的配置,会自动将该路径的照片

    加载成为我们拼图的原材料。

     主函数代码

    pintu.py

    代码结构搞的简单一点。一个配置文件cfg,一个资源路径resources,存放字体和图片。

    主函数代码放在这里:

    1、定义四个可移动函数,在存在空格的情况下,允许向空格的方向移动。

    2、createboard:随机将图片拆分,并且打乱。

    3、开始时,随机从图片文件夹获取一张图片:如果想给整个宿舍的学姐做游戏,

    就把所有人的照片放进去,这样每次打开,会随机生成一个学姐的照片作为游戏背景。

    '''
    Function:
        拼图小游戏
    作者:
        LexSaints
    '''
    import os
    import sys
    import cfg
    import random
    import pygame
    
    
    '''判断游戏是否结束'''
    def isGameOver(board, size):
        assert isinstance(size, int)
        num_cells = size * size
        for i in range(num_cells-1):
            if board[i] != i: return False
        return True
    
    
    '''将空白Cell左边的Cell右移到空白Cell位置'''
    def moveR(board, blank_cell_idx, num_cols):
        if blank_cell_idx % num_cols == 0: return blank_cell_idx
        board[blank_cell_idx-1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-1]
        return blank_cell_idx - 1
    
    
    '''将空白Cell右边的Cell左移到空白Cell位置'''
    def moveL(board, blank_cell_idx, num_cols):
        if (blank_cell_idx+1) % num_cols == 0: return blank_cell_idx
        board[blank_cell_idx+1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+1]
        return blank_cell_idx + 1
    
    
    '''将空白Cell上边的Cell下移到空白Cell位置'''
    def moveD(board, blank_cell_idx, num_cols):
        if blank_cell_idx < num_cols: return blank_cell_idx
        board[blank_cell_idx-num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-num_cols]
        return blank_cell_idx - num_cols
    
    
    '''将空白Cell下边的Cell上移到空白Cell位置'''
    def moveU(board, blank_cell_idx, num_rows, num_cols):
        if blank_cell_idx >= (num_rows-1) * num_cols: return blank_cell_idx
        board[blank_cell_idx+num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+num_cols]
        return blank_cell_idx + num_cols
    
    
    '''获得打乱的拼图'''
    def CreateBoard(num_rows, num_cols, num_cells):
        board = []
        for i in range(num_cells): board.append(i)
        # 去掉右下角那块
        blank_cell_idx = num_cells - 1
        board[blank_cell_idx] = -1
        for i in range(cfg.NUMRANDOM):
            # 0: left, 1: right, 2: up, 3: down
            direction = random.randint(0, 3)
            if direction == 0: blank_cell_idx = moveL(board, blank_cell_idx, num_cols)
            elif direction == 1: blank_cell_idx = moveR(board, blank_cell_idx, num_cols)
            elif direction == 2: blank_cell_idx = moveU(board, blank_cell_idx, num_rows, num_cols)
            elif direction == 3: blank_cell_idx = moveD(board, blank_cell_idx, num_cols)
        return board, blank_cell_idx
    
    
    '''随机选取一张图片'''
    def GetImagePath(rootdir):
        imagenames = os.listdir(rootdir)
        assert len(imagenames) > 0
        return os.path.join(rootdir, random.choice(imagenames))
    
    
    '''显示游戏结束界面'''
    def ShowEndInterface(screen, width, height):
        screen.fill(cfg.BACKGROUNDCOLOR)
        font = pygame.font.Font(cfg.FONTPATH, width//15)
        title = font.render('恭喜! 你成功完成了拼图!', True, (233, 150, 122))
        rect = title.get_rect()
        rect.midtop = (width/2, height/2.5)
        screen.blit(title, rect)
        pygame.display.update()
        while True:
            for event in pygame.event.get():
                if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    pygame.quit()
                    sys.exit()
            pygame.display.update()
    
    
    '''显示游戏开始界面'''
    def ShowStartInterface(screen, width, height):
        screen.fill(cfg.BACKGROUNDCOLOR)
        tfont = pygame.font.Font(cfg.FONTPATH, width//4)
        cfont = pygame.font.Font(cfg.FONTPATH, width//20)
        title = tfont.render('拼图游戏', True, cfg.RED)
        content1 = cfont.render('按H或M或L键开始游戏', True, cfg.BLUE)
        content2 = cfont.render('H为5*5模式, M为4*4模式, L为3*3模式', True, cfg.BLUE)
        trect = title.get_rect()
        trect.midtop = (width/2, height/10)
        crect1 = content1.get_rect()
        crect1.midtop = (width/2, height/2.2)
        crect2 = content2.get_rect()
        crect2.midtop = (width/2, height/1.8)
        screen.blit(title, trect)
        screen.blit(content1, crect1)
        screen.blit(content2, crect2)
        while True:
            for event in pygame.event.get():
                if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == ord('l'): return 3
                    elif event.key == ord('m'): return 4
                    elif event.key == ord('h'): return 5
            pygame.display.update()
    
    
    '''主函数'''
    def main():
        # 初始化
        pygame.init()
        clock = pygame.time.Clock()
        # 加载图片
        game_img_used = pygame.image.load(GetImagePath(cfg.PICTURE_ROOT_DIR))
        game_img_used = pygame.transform.scale(game_img_used, cfg.SCREENSIZE)
        game_img_used_rect = game_img_used.get_rect()
        # 设置窗口
        screen = pygame.display.set_mode(cfg.SCREENSIZE)
        pygame.display.set_caption('拼图游戏 —— Linux黑客小课堂')
        # 游戏开始界面
        size = ShowStartInterface(screen, game_img_used_rect.width, game_img_used_rect.height)
        assert isinstance(size, int)
        num_rows, num_cols = size, size
        num_cells = size * size
        # 计算Cell大小
        cell_width = game_img_used_rect.width // num_cols
        cell_height = game_img_used_rect.height // num_rows
        # 避免初始化为原图
        while True:
            game_board, blank_cell_idx = CreateBoard(num_rows, num_cols, num_cells)
            if not isGameOver(game_board, size):
                break
        # 游戏主循环
        is_running = True
        while is_running:
            # --事件捕获
            for event in pygame.event.get():
                # ----退出游戏
                if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    pygame.quit()
                    sys.exit()
                # ----键盘操作
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT or event.key == ord('a'):
                        blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
                    elif event.key == pygame.K_RIGHT or event.key == ord('d'):
                        blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
                    elif event.key == pygame.K_UP or event.key == ord('w'):
                        blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
                    elif event.key == pygame.K_DOWN or event.key == ord('s'):
                        blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
                # ----鼠标操作
                elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    x, y = pygame.mouse.get_pos()
                    x_pos = x // cell_width
                    y_pos = y // cell_height
                    idx = x_pos + y_pos * num_cols
                    if idx == blank_cell_idx-1:
                        blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
                    elif idx == blank_cell_idx+1:
                        blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
                    elif idx == blank_cell_idx+num_cols:
                        blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
                    elif idx == blank_cell_idx-num_cols:
                        blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
            # --判断游戏是否结束
            if isGameOver(game_board, size):
                game_board[blank_cell_idx] = num_cells - 1
                is_running = False
            # --更新屏幕
            screen.fill(cfg.BACKGROUNDCOLOR)
            for i in range(num_cells):
                if game_board[i] == -1:
                    continue
                x_pos = i // num_cols
                y_pos = i % num_cols
                rect = pygame.Rect(y_pos*cell_width, x_pos*cell_height, cell_width, cell_height)
                img_area = pygame.Rect((game_board[i]%num_cols)*cell_width, (game_board[i]//num_cols)*cell_height, cell_width, cell_height)
                screen.blit(game_img_used, rect, img_area)
            for i in range(num_cols+1):
                pygame.draw.line(screen, cfg.BLACK, (i*cell_width, 0), (i*cell_width, game_img_used_rect.height))
            for i in range(num_rows+1):
                pygame.draw.line(screen, cfg.BLACK, (0, i*cell_height), (game_img_used_rect.width, i*cell_height))
            pygame.display.update()
            clock.tick(cfg.FPS)
        # 游戏结束界面
        ShowEndInterface(screen, game_img_used_rect.width, game_img_used_rect.height)
    
    
    '''run'''
    if __name__ == '__main__':
        main()

     游戏运行方法

    1、开发工具启动

    如果你有python开发环境VScode、sublimeText、notepad+、pycharm等等这些环境,可以直接在工具中,运行游戏。

    2、命令行运行游戏

    如下图:

    【两种方法获取完整源码】

    1、资源下载:【pygame开发实战开发30例 完整源码】

    https://download.csdn.net/download/weixin_42350212/15836285

    2、订阅专栏:【获取完整源码+教程】

    一起来学pygame吧 游戏开发30例(二)——塔防游戏

    一起来学pygame吧 游戏开发30例(四)——俄罗斯方块小游戏

    推荐阅读

    python实战

    【python实战】前女友发来加密的 “520快乐.pdf“,我用python破解开之后,却发现。。。

    【python实战】昨晚,我用python帮隔壁小姐姐P证件照 自拍,然后发现...

    【python实战】女友半夜加班发自拍 python男友用30行代码发现惊天秘密

    【python实战】python你TM太皮了——区区30行代码就能记录键盘的一举一动

    python实战】女神相册密码忘记了,我只用Python写了20行代码~~~

    渗透测试

    【渗透案例】上班摸鱼误入陌生网址——结果被XSS劫持了

    【渗透测试】密码暴力破解工具——九头蛇(hydra)使用详解及实战

    【渗透学习】Web安全渗透详细教程+学习线路+详细笔记【全网最全+建议收藏】

    【渗透案例】如何用ssh工具连接前台小姐姐的“小米手机”——雷总看了直呼内行!!!

    【渗透测试】密码暴力破解工具——九头蛇(hydra)使用详解及实战

    pygame系列文章

    一起来学pygame吧 游戏开发30例(二)——塔防游戏

    一起来学pygame吧 游戏开发30例(三)——射击外星人小游戏

    一起来学pygame吧 游戏开发30例(四)——俄罗斯方块小游戏

    一起来学pygame吧 游戏开发30例(五)——消消乐 小游戏

    一起来学pygame吧 游戏开发30例(六)——高山滑雪 小游戏

    CSDN官方学习推荐 ↓ ↓ ↓

    CSDN出的Python全栈知识图谱,太强了,推荐给大家!

    展开全文
  • 用一晚上时间,用python做的RPG小游戏(面向对象思想)
  • python2048游戏设计

    万次阅读 2016-11-05 23:34:55
    python 2048游戏 pygame

    先添上最终完成效果图

    这里写图片描述

    这里写图片描述

    Github链接

    https://github.com/happyte/2048,这个是2048的代码仓库,同时我在CSDN上也上传了资源。希望大家指出不足之处。

    2048设计思想

    • 1.大家都玩过2048,我们可以认为4*4的方块是个矩阵,开始是4*4的零矩阵。游戏开始在任意地方出现2或4,以后每次出现的数字都是2或者4。然后我们可以上下左右移动,移动的规则是例如向左动,某一行(左移只需要考虑每一行)的数比如是[2,4,0,2]向左移动,移动后变成[2,4,2,0],移动后不允许(每行或者每列,与移动方向有关)两个非0数字之间有0的存在。移动前相邻两个数相同的话会合并,例如[2,2,4,4]会合并成[4,8,0,0]

    • 2.移动合并完后,会在所有为0的位置随机挑选出一个位置填上2或者4,记住是先移动合并完后才会随机填上2或者4。

    • 3.有些时候我们发现往某个方向无法移动,例如下面这张情况:
      这里写图片描述
      向左和向下都无法移动,向左移动的话每一行移动后还是原来老样子,因为每一行任意相邻两个非0数之间不存在间隔且无法合并。向下移动的话每一列还是原来老样子,因为每一列任意相邻两个非0数之间不存在间隔且无法合并。在无法移动(即移动后还是老样子的情况下)不会在随机0位置处添加随机数2或4。只有移动后改变了矩阵的原来样子且矩阵最小值为0才会在随机0位置出添加随机数2或4。

    • 4.有两种情况移动后不会添加随机数2或4,第一种情况是上面这种情况,往一个方向移动没有效果。另外一种是矩阵都为非0数,没有位置添加随机数2或4。

    • 5.游戏结束的情况,当矩阵没有0而且每行每列任意两个相邻数无法合并。

    基础类

    • 1.我们将上下左右移动都封装成一个类,继承一个基础类,基础类的对象应该拥有matrix矩阵属性,一个列表用于存储0元素位置zerolist和纪录当前分数score
      这里写图片描述

    • 2.将矩阵移动并返回处理完的矩阵,这里我们将矩阵上下左右移动统一转换为矩阵向左移动,这个我在继承类中会写出。

      • 先获得矩阵的行、列数

        lastmatrix = matrix.copy()
        m,n = matrix.shape
      • 再对每一行进行处理,每行都是转化成list对象,矩阵是array类型的对象,在初始化时使用numpy模块构造出来。

          list(matrix[i])

        将每一行非0元素之间的0删除。不断删除第一个0元素再往最后 添 加0,直到非0元素之间没有0。例如[2,4,0,4]经过处理后变成[2,4,4,0]

          for i in range(m):
              newList = self.removeZero(list(matrix[i]))

        会掉用下面这个removeZero函数
        这里写图片描述

      • 将非0元素处理完成之后要对list进行合并,例如上面的[2,4,4,0]变成[2,8,0,0],只要对比相邻两个元素是否相同,返回处理完的list
        这里写图片描述
      • 每行的list都处理完了,把处理完的每行的list赋给老矩阵每行的list,接下来我们要找到所有0元素的位置,并且把位置添加到zerolist这个链表中来。

          matrix[i] = newList
          for k in range(Size-1,Size-newList.count(0)-1,-1):
              self.zerolist.append((i,k))

        从每一行的最后一个元素向前找,因为0元素一定在最后!!!Size在文件初始化时设置为4,代表4*4矩阵。

      • 如果移动后的矩阵和函数进来时复制的那个矩阵相同说明已经无法移动(也称为移动没有效果),不需要在随机的一个0位置添加随机数。还有一种情况矩阵都为非0数,没有0元素的位置了。

        if matrix.min() == 0 and (matrix!=lastmatrix).any():
            #往矩阵添加随机数2或者4

        下面贴上整个函数的代码
        这里写图片描述

    继承类

    • 1.继承类只有两个函数,一个是初始化函数,另外一个是处理矩阵函数。因为是继承基础类,要拿到基础类对象属性matrixzerolistscore要调用基类的__init__函数。以左移类为例
      这里写图片描述

    • 2.处理数据函数,左移类不需要对矩阵先变化,因为基础类的Sequence函数就是根据左移写的。
      这里写图片描述

    • 3.右移类,右移➡是左移⬅的逆向排列。先对矩阵每行的数进行一个逆序,例如[2,4,4,0]转换成[0,4,4,2],再掉用Sequence进行处理,例如上面这行处理完为[8,2,0,0],处理完后再对每行进行逆序,得到[0,0,2,8],就是[2,4,4,0]右移的结果。其实我们的思路就是无论如何移动,我们都先转换成左移,处理完后再还原成应该移动方向的样子。
      这里写图片描述
      [:,::-1]就是对矩阵每行进行逆序

    • 4.向上类,本来上移⬆就是左移⬅的转置。道理和右移动一样。
      这里写图片描述

    • 5.向下类,下移可以有多种方法变成左移,比如下移先变成上移,上移转置变成左移。或者下移先转置成右移,右移再逆序成左移。这里采用下移先变成上移,上移转置变成左移。
      这里写图片描述

    游戏初始化

    • 1.该类封装了一系列函数,都是类方法和静态方法,可以直接拿该类调用函数。其中�最重要函数的是设置数据函数,游戏开始时在任意位置设置2或者4,移动后在处理完的矩阵的任意0元素位置添加2或者4。
      这里写图片描述
      该函数有两个默认参数matrixzerolist,初始化矩阵时调用这个函数不需要传入这两个参数。移动完成后的矩阵会调用这个函数,传入matrixzerolist参数。

    • 2.获得随机数的位置,同样也有一个默认参数为zerolist=None
      这里写图片描述
      因为初始化时没有传入zerolist参数,因此a,b为(0,3)之间的随机整数。移动后的矩阵传入zerolist参数,记住之前我们往zerolist添加的都是tuple对象。sample函数取出存在zerolist中的任意一个元素,取出仍然是个list对象,例如取出就是[(0,3)],因此加后面的[0]取出的结果就是(0,3)

    • 3.返回随机数2或者4
      这里写图片描述

    • 4.描绘标题和描绘方块数字函数。我给每种不同数字的方块定义了不同的颜色,放在一个字典中。
      这里写图片描述
      描绘标题函数,内部调用了描绘方块函数
      这里写图片描述
      描绘方块函数
      这里写图片描述

    • 5.主函数的键盘按下会调用这个函数,根据移动方向创建不同对象,然后通过这个对象调用这个类的handleData函数。
      这里写图片描述

    • 6.判断游戏是否结束函数,矩阵最小值不为0且每行每列相邻数不相同
      这里写图片描述

    主函数

    • 1.主函数比较简单,做完一些初始化工作进入While循环,不断判断什么事件发生,只有退出程序事件和键盘事件。
      这里写图片描述

    github链接

    github链接:https://github.com/happyte,里面有2048的代码仓库,同时我在CSDN上也上传了资源。希望大家指出不足之处。

    展开全文
  • python游戏开发——简单弹球游戏

    万次阅读 多人点赞 2019-04-25 11:09:28
    本案例采用 python 实现了一个简单的弹球游戏。该游戏在一个单独的图形窗口中运行。游戏初始化后,在游戏窗口点击鼠标左键开始游戏。玩家通过控制键盘的左、右方向键来控制弹板的移动,弹球和弹板撞击一次,得一分,...
  • Python开发一个滑雪小游戏

    万次阅读 多人点赞 2021-06-09 14:27:01
    Python开发小游戏
  • Python实现“小兔子和Bun”游戏 Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏Python实现塔防小游戏 ...
  • python五子棋游戏代码实现

    万次阅读 多人点赞 2019-08-25 09:54:01
    很多人都感觉游戏”这个词汇听着就很难,不知道怎么去实现。那么“接下来就是见证奇迹的时刻”。 思路: (1)准备好棋盘图片,棋子图片(白棋、黑棋),获胜时的图片共四张。想要图片资源可以点击此链接: ...
  • python游戏大全——30个,快来下载吧!
  • 使学员们在Python学习过程中,在以下的八个方面,有所提高: 1、Python中类的使用 2、Python中模块的相互调用 3、tkinter模块高级绘图、动画的使用方法 4、Python中键盘事件的绑定 5、构造方法、循环语句 6、列表的...
  • 1、Python猜拳小游戏代码:2、import random #导入随机模块3、4、num = 15、yin_num = 06、shu_num = 07、while num 2:12、 print('不能出大于2的值')13、 else:14、 data = ['石头', '剪刀', '布']15、 ...
  • python脚本语言---现今用的最多的脚本语言之一,google内部也在用,是其内部除java/c++之外第三大语言,另外它在多媒体方面的表现也不俗,想用python游戏的朋友看看
  • Python实现“小兔子和Bun”游戏 Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏Python实现塔防小游戏 ...
  • Python实现经典吃豆豆小游戏 Python实现“小兔子和Bun”游戏 Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏...
  • 用pygame一个简单的python游戏---贪吃蛇

    千次阅读 多人点赞 2020-11-30 12:04:08
    用pygame一个简单的python游戏—贪吃蛇 贪吃蛇游戏链接: c++贪吃蛇:https://blog.csdn.net/weixin_46791942/article/details/106850986 正文开始 下载pygame模块 pip install pygame 编写的是最简单的贪吃蛇...
  • 很多人认为Python只适合用来大数据,或者是爬虫之类,而对于写游戏,他们认为Python实在是个loser,然而这几个游戏,你们玩过吗? 第一种游戏:这是一款基于Python的战争游戏,在国外的名字不亚于国内的某些策略...
  • 用pygame一个简单的python游戏---七彩同心圆

    万次阅读 多人点赞 2020-12-13 10:00:58
    用pygame一个简单的python游戏—七彩同心圆 这个小游戏原是我同学python课的课后作业,并不是很难,就简单实现了一下,顺便加强一下pygame库的学习。 玩法:每次点击鼠标时,会以鼠标为圆心,不断向外扩展圆...
  • python做个弹球游戏(一)

    万次阅读 2016-06-11 20:34:09
    python tkinter模块一个击打反弹球和球拍的游戏。球在屏幕上飞,玩家需要把它击打回去,只要球落到屏幕底部,游戏就结束。 首先我们一个在屏幕上到处移动的小球: #coding:utf-8 from tkinter import...
  • python实现小游戏

    2018-07-23 21:34:02
    利用python编写的贪吃蛇经典小游戏,以可视化的方式展示游戏运行效果。
  • Python实现“小兔子和Bun”游戏 Python实现八音符小游戏 Python实现拼图小游戏 Python实现滑雪小游戏 Python实现经典90坦克大战 Python实现FlappyBird的小游戏 Python实恐龙跳一跳小游戏Python实现塔防小游戏 ...
  • Python简单游戏代码

    万次阅读 多人点赞 2018-07-20 23:46:07
    #控制游戏速度 fpsColck = pygame.time.Clock() #创建pygame显示层 playSurface = pygame.display.set_mode((640,480)) pygame.display.set_caption('贪吃蛇') #初始化贪吃蛇的起始坐标 snakePosition = [100...
  • 基于python的猜数游戏

    2018-10-27 14:11:01
    运用python基础的一个猜数游戏
  • python写的跑酷类小游戏,适合新手参考,现在只实现了吃金币和障碍物碰撞功能,相对比较简单,可以自己拓展。
  • python管道小鸟游戏

    2019-03-06 20:23:04
    python语言制作的管道小鸟游戏,可以通过键盘的空格键来控制小鸟的上下移动
  • python2048游戏源代码

    2017-10-26 14:17:58
    python3.5.2版本的2048小游戏,基于wxpython开发的GUI,解压后有.exe执行文件可以打开直接开始游戏,具体源代码请进我的主页查找~
  • 由于pygame的首页上不去没法上它的官网下载模块,ubuntu下其实很方便,一个命令就搞定了: sudo apt-get install python-pygame 这个游戏是用的python2.7.3的,我的系统默认安装的就是这个版本,我也就没有改了。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 179,476
精华内容 71,790
关键字:

python做游戏

python 订阅