精华内容
下载资源
问答
  • 如何用python写游戏脚本?

    千次阅读 2020-08-17 13:43:08
    前言 最近在玩儿公主连结,之前也玩儿过阴阳师这样的游戏,这样的游戏都会有个初始号这样的东西,或者说是可以...当然,作为一名程序员,肝这种东西完全可以用写代码的方式帮我们自动完成。游戏脚本其实并不高深,最简

    前言

    最近在玩儿公主连结,之前也玩儿过阴阳师这样的游戏,这样的游戏都会有个初始号这样的东西,或者说是可以肝的东西。

    很多人学习python,不知道从何学起。
    很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
    很多已经做案例的人,却不知道如何去学习更加高深的知识。
    那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
    QQ群:101677771

    当然,作为一名程序员,肝这种东西完全可以用写代码的方式帮我们自动完成。游戏脚本其实并不高深,最简单的体验方法就是下载一个Airtest了,直接截几个图片,写几层代码,就可以按照自己的逻辑玩儿游戏了。

    当然,本篇文章不是要讲Airtest这个怎么用,而是用原始的python+opencv来实现上面的操作。

    这两天我写了一个公主连结刷初始号的程序,也不能算写游戏脚本的老手,这篇文章主要是分享一些基础的技术和使用上的心得吧。

    准备工作

    首先,我们要完成以下准备。

    • 安卓设备 一个:模拟器或者真机都可以。
    • 安装 ADB ,并添加到系统的 PATH 里:adb是用来
    • 安装 tesseract-ocr ,并添加到系统的 PATH 里:帮助我们实现简单的字符识别
    • 安装 python3.7 以上的版本

    这里adb和tesseract我放在百度网盘里了,里面顺便放了一个录制的效果视频。

    链接: pan.baidu.com/s/1edTPu2o7… 提取码:33aw

    python库安装

    pip install pillow pytesseract opencv-python
    复制代码

    除此以外,如果有需要可以安装 uiautomator2 ,这篇文章就不涉及这块知识了。

    使用 adb 获取安卓设备

    这里我们主要是涉及到单个安卓设备的ADB连接操作,首先我们打开模拟器。

    然后我们调用 adb devices 来获取当前的安卓设备,我这里是一个模拟器。

    接下来可以调用 adb shell 测试一下是否能进入到安卓设备的shell环境下,确认可以输入 exit 退出即可。

    如果有的时候进不了shell,可以先调用一下 adb kill-server ,然后再调用 adb devices 。

    可能常用的ADB Shell命令

    接下来是一些ADB的命令操作。通过adb命令,我们可以用python来操作的安卓设备。

    屏幕截图

    最常见的操作就是截图了,先调用 screencap 截图放到安卓设备里,然后再把截图下拉到电脑。

    def take_screenshot():
        os.system("adb shell screencap -p /data/screenshot.png")
        os.system("adb pull /data/screenshot.png ./tmp.png")
    复制代码

    下拉文件

    下拉文件就是刚刚那个 adb pull 了,以公主连结为例,以下代码可以导出账号信息的xml,以后通过xml就可以登录了。

    os.system(f"adb pull /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml ./user_info.xml")
    复制代码

    上传文件

    有了下拉自然就有上传了,通过 adb push 即可完成。以公主连结为例,以下代码可以完成账号的切换。

    # 切换账号1
    os.system("adb push ./user_info1.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml")
    
    # 切换账号2
    os.system("adb push ./user_info2.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml")
    复制代码

    点击屏幕某个位置

    def adb_click(center, offset=(0, 0)):
        (x, y) = center
        x += offset[0]
        y += offset[1]
        os.system(f"adb shell input tap {x} {y}")
    复制代码

    输入文字

    text = "YourPassword"
    os.system(f"adb shell input text {text}")
    复制代码

    删除字符

    有的时候输入框会有输入的缓存,我们需要删除字符。

    # 删除10个字符
    for i in range(10):
        os.system("adb shell input keyevent 67")
    复制代码

    查询当前运行的包名和Activity

    通过以下代码,可以查询当前运行的程序的Activity,也可以顺便查包名。

    adb shell dumpsys activity activities
    复制代码

    停止某个应用

    有时候会需要停止某个应用,需要提供应用的包名。

    adb shell am force-stop tw.sonet.princessconnect
    复制代码

    开启某个应用

    开启某个应用需要提供包名以及Activity。

    adb shell am start -W -n tw.sonet.princessconnect/jp.co.cygames.activity.OverrideUnityActivity
    复制代码

    图像操作

    对于图像的操作第一就是图像查找了,比如说像Airtest提供的这种,无非就是判断某个图像在不在截屏中,在的话在什么位置。

    除此之外还需要一些抠图,比如说我们想获取 账号的id , 账号的等级 ,需要截取出一部分图片然后进行OCR操作。

    图像查找

    图像查找其实就是先拿到两张图片,然后调用 cv2.matchTemplate 方法来查找是否存在以及位置,这里匹配是一个相对模糊的匹配,会有一个相似度的概率,最高是1。我们设定一个阈值来判断模板是否在截屏里即可。

    这里截屏如下,文件名为 tmp.png :

    模板如下:

    代码如下:

    import cv2
    
    def image_to_position(screen, template):
        image_x, image_y = template.shape[:2]
        result = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        print("prob:", max_val)
        if max_val > 0.98:
            global center
            center = (max_loc[0] + image_y / 2, max_loc[1] + image_x / 2)
            return center
        else:
            return False
    
    if __name__ == "__main__":
        screen = cv2.imread('tmp.png')
        template =  cv2.imread('Xuandan.png')
        print(image_to_position(screen, template))
    复制代码

    运行上述代码后,可以看到模板匹配出来的概率为 0.9977 ,位置为(1165, 693),对于一张图片,左上角为原点,因为我的分辨率是1280 * 720,那么右下角的坐标就是(1280, 720)。可以看到我们这个选单其实就是刚好在右下角的位置。

     

    如何快速裁剪模板?(win10)

    游戏脚本其实并不是代码很难写,而是需要截很多的图,这些图要保证分辨率和原始一样。我发现在win10如果用画图打开图片

    可以保证使用QQ截屏出来的分辨率,和图片本身的分辨率一样。

    这个时候直接用qq截屏出来的模板即可直接用于识别。

    图像裁剪

    接下来就是有时候需要裁剪一些图像了,当然我们的模板图片也可以通过裁剪图片的方式得到,这样的模板图片是最准的。

    裁剪其实就是需要裁剪的位置,以及需要的高度和宽度,说白了就是一篇长方形的区域,下面的代码使用PIL库实现。

    from PIL import Image
    
    def crop_screenshot(img_file, pos_x, pos_y, width, height, out_file):
        img = Image.open(img_file)
        region = (pos_x, pos_y, pos_x + width, pos_y + height)
        cropImg = img.crop(region)
        cropImg.save(out_file)
        print("exported:", out_file)
    
    if __name__ == "__main__":
        crop_screenshot("tmp.png", 817,556, 190, 24, "test_id.png")
    
    复制代码

    上面的代码以截取玩家的id为例。

    运行代码后,得到截图如下:

    简单的OCR

    得到了以上的图片信息后就是进行OCR了,也就是光学字符识别。这里代码非常简单,只要调用API即可。

    from PIL import Image
    import pytesseract
    
    image = Image.open('test_id.png')
    content = pytesseract.image_to_string(image)   # 识别图片
    print(content)
    
    复制代码

    不过需要注意的一点就是pytesseract识别出来的结果会有空格符,换行符这样的符号,真正要用的时候进行一些字符的过滤即可。

    The End

    这篇文章到这里就结束了,主要还是介绍一些ADB以及图像相关的基础操作,有些内容比如说多开和uiautomator2因为我暂时没用到所以就没写,百度一下应该也不是很难。代码写的比较丑还没完善好,就先不放了。

    展开全文
  • 手把手教你用Python写一个简单的贪吃蛇小游戏 人生苦短,我用Python! hello 大家好!我是Mark,一个姓马名克的中国人。 最近呢突然特别想玩一个贪吃蛇的小游戏,可是家里管得严,电脑上面,手机上面都不让下载,...

    手把手教你用Python写一个简单的贪吃蛇小游戏

    人生苦短,我用Python!

    hello 大家好!我是Mark,一个姓马名克的中国人。

    最近呢突然特别想玩一个贪吃蛇的小游戏,可是家里管得严,电脑上面,手机上面都不让下载,可是,对于会Python的我,这根本不是问题。
    今天,我们就来看看,如何通过Python来写一个贪吃蛇小游戏!

    注意一下,本文适合稍微有一点Python基础的朋友,如果你点进来只是想体验一下Python写的小游戏,可以直接拉到文章最后,有惊喜哟!

    首先,我这里调用pygame模块
    安装:

    pip install pygame
    

    安装完成之后输入

    python
    import pygame
    

    如果没有报错,说明安装成功。

    接下来,我们就开始撸代码啦!

    一、导入模块

    import pygame, time, random, sys
    

    time模块用于控制时间,sys模块用于退出程序,random模块用于随机生成食物。

    二、初始化游戏窗口

    '''初始化游戏'''
    pygame.init()
    
    # 初始化游戏窗口
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption('贪吃蛇小游戏')
    

    这里创建了一个640 × 480的长方形窗口。
    同时,将窗口上方的名称设定为“贪吃蛇小游戏”

    三、定义一些需要用的变量名

    # 定义速度
    fpsclock = pygame.time.Clock()
    
    # 定义字体
    font = pygame.font.Font('C:/Windows/Fonts/ARLRDBD.TTF', 80)
    
    # 定义颜色
    red = pygame.Color(255, 0, 0)
    blue = pygame.Color(0, 0, 255)
    balck = pygame.Color(0, 0, 0)
    white = pygame.Color(255, 255, 255)
    grey = pygame.Color(130, 130, 130)
    

    定义字体的位置,当中有一个“C:/Windows/Fonts/ARLRDBD.TTF”,这个是字体文件的位置,后面的80是字体的大小。

    另外注意,下面的颜色,用的是RGB光学三原色,这个只做了解。

    四、定义贪吃蛇和食物的基本信息。

    '''初始化贪吃蛇和食物'''
    # 贪吃蛇的位置
    snake_head = [100, 100]
    
    # 贪吃蛇的身体
    snake_body = [[80, 100], [60, 100], [40, 100]]
    
    # 定义贪吃蛇的开始方向
    direction = 'right'
    
    # 食物标记
    food_flag = 1
    
    # 第一个食物的位置
    food_position = [300, 300]
    

    相信大家注意到了,食物标记 这个东西,当食物标记为1,就代表食物没有被吃掉,当食物标记为2,就代表已经被吃掉了。

    注意一下这里的坐标
    坐标
    这个pygame的坐标方式和正常的不太一样,如图所示。

    五、开启游戏主循环

    while True:
        # 屏幕用黑色填充
        screen.fill(0)
    
    	'''检测事件'''
        for event in pygame.event.get():
            # 检测退出
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
    

    这里注意一下了,一定要检测退出,不然点击退出按钮的时候就会一直转圈圈,无法退出。

    六、检测按键是否按下

            # 检测按键是否按下
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP and direction != 'down':
                    direction = 'up'
    
                elif event.key == pygame.K_DOWN and direction != 'up':
                    direction = 'down'
    
                elif event.key == pygame.K_RIGHT and direction != 'left':
                    direction = 'right'
    
                elif event.key == pygame.K_LEFT and direction != 'right':
                    direction = 'left'
    

    注意一下,这里的缩进级别和上一个 if 的级别相等,
    连起来看是这样的
    缩进
    这里有很多 if 语句,拆开来看其实不难。

    七、移动贪吃蛇
    一样的,直接上代码

        '''移动贪吃蛇'''
        if direction == 'up':
            snake_head[1] -= 20
    
        if direction == 'down':
            snake_head[1] += 20
    
        if direction == 'right':
            snake_head[0] += 20
    
        if direction == 'left':
            snake_head[0] -= 20
       
       	# 将蛇的头部当前的位置加入到蛇身的列表中
        snake_body.insert(0, list(snake_head))
    

    这几个语句都很简单,自行理解。

    八、判定食物是否被吃

        # 判定食物是否被吃
        if snake_head[1] == food_position[1] and snake_head[0] == food_position[0]:
            food_flag = 2
    
        else:
            snake_body.pop()
    

    这个也很简单,就是说,一旦蛇头与食物坐标一致,食物标记就变成了被吃的状态。

    九、随机生成食物
    话不多说,上代码

        # 随机生成食物
        if food_flag == 2:
            x = random.randrange(1, 32)
            y = random.randrange(1, 24)
            food_position = [int(x * 20), int(y * 20)]
            food_flag = 1
    

    这个很好理解,随机生成 x 和 y 然后将食物标记归零。

    十、绘制贪吃蛇
    当你写完了以上代码,你会发现,咦?为什么我这个屏幕一片黑色?
    因为呀,你的贪吃蛇都没有画出来呢!

    # 画出贪吃蛇
    def snake(Snake_body):
        for i in Snake_body:
            pygame.draw.rect(screen, white, (i[0], i[1], 20, 20))
    

    这里看一下这个方法

    pygame.draw.rect(surf 也就是你要画的屏幕, color 颜色, (x横轴, y纵轴, int长, int宽)
    

    如果是旧版本的pygame,可以将代码改成这样

    # 画出贪吃蛇
    def snake(Snake_body):
        for i in Snake_body:
            pygame.draw.rect(screen, white, Rect(i[0], i[1], 20, 20))
    

    十一、绘制食物
    接下来,我们就让食物也出现在屏幕上面吧

    # 画出食物
    def food(food_Position):
        pygame.draw.rect(screen, red, (food_Position[0], food_Position[1], 20, 20))
    

    如果是旧版本的pygame,把代码改成这样

    # 画出食物
    def food(food_Position):
        pygame.draw.rect(screen, red, Rect(food_Position[0], food_Position[1], 20, 20))
    

    十二、绘制分数
    代码如下

    # 打印分数
    def drawscore(score):
        # 设置分数的颜色
        score_surf = font.render('%s' % score, True, grey)
    
        # 设置分数的位置
        score_rect = score_surf.get_rect()
        score_rect.midtop = (320, 240)
    
        # 绑定以上句柄
        screen.blit(score_surf, score_rect)
    

    十三、在屏幕上绘制贪吃蛇和食物
    好了,绘制贪吃蛇和绘制食物的函数都定义完成了,接下来,让我们把他添加到主循环当中去。
    在屏幕用黑色填充之后,加入以下代码

        # 画出角色
        snake(snake_body)
        food(food_position)
        drawscore(len(snake_body) - 3)
    
        # 刷新屏幕
        pygame.display.flip()
    
        fpsclock.tick(10)
    

    注意了,一定要添加到填充屏幕的后面,看起来是这样的
    注意
    这个时候,你再一次运行代码,就可以畅快的玩一个无敌版本的贪吃蛇了!
    咦?为什么是无敌版本
    相信大家都知道了,因为我们还没有定义死亡的的函数呢!

    十四、定义死亡函数

    def game_over():
        # 设置文字颜色
        game_over_surf = font.render('Game Over!', True, grey)
    
        # 设置文字位置
        game_over_rect = game_over_surf.get_rect()
        game_over_rect.midtop = (320, 10)
    
        # 绑定以上句柄
        screen.blit(game_over_surf, game_over_rect)
    
        pygame.display.flip()
        time.sleep(3)
        pygame.quit()
        sys.exit()
    

    函数定义完成了,接下来,把它添加到主循环里面去。

    十五、完成游戏

        '''判定死亡'''
        # 碰到边缘
        if snake_head[0] < 0 or snake_head[0] > 620:
            game_over()
    
        elif snake_head[1] < 0 or snake_head[1] > 460:
            game_over()
    
        # 贪吃蛇碰到自己
        for i in snake_body[1:]:
            if snake_head[0] == i[0] and snake_head[1] == i[1]:
                game_over()
    
    

    OK啦!
    你的贪吃蛇小游戏完成啦!
    现在去试一试吧,一定会非常有意思的!

    十六、福利环节
    是的,你没有看错,这就是福利环节,专门给来打酱油的人提供的环节。
    我已经将源代码打包成了一个exe,供无聊人士使用
    这里提供几个下载地址:
    百度网盘:链接: https://pan.baidu.com/s/10uG7lF3pIQ03jLVQGBzEkg 提取码: wrss

    蓝奏云:https://wws.lanzous.com/ip8lddkqxuh

    CSDN下载:https://download.csdn.net/download/zhugezuoyuan/12516509

    使用方法:
    下载压缩包,解压,双击里面的ARLRDBD.TTF字体文件进行安装,不然程序无法运行,源代码就是压缩包当中的源码.py

    好了,今天的分享就到这里,再见!

    展开全文
  • 介绍了Python贪吃蛇游戏的编写代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 代码如下: # Write By Guobao # 2017/4//7 # # 贪吃蛇 # #做边界,*做食物,o做身体和头部 #...

    介绍了Python贪吃蛇游戏的编写代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    代码如下:

    # Write By Guobao
    # 2017/4//7
    #
    # 贪吃蛇
    # 用#做边界,*做食物,o做身体和头部
    # python 3.6.1
     
    import copy
    import random
    import os
    import msvcrt
     
    # the board class, used to put everything
    class board:
     
     __points =[]
     
     def __init__(self):
     self.__points.clear()
     for i in range(22):
     line = []
     if i == 0 or i == 21:
     for j in range(22):
      line.append('#')
     else:
     line.append('#')
     for j in range(20):
      line.append(' ')
     line.append('#')
     self.__points.append(line)
     
     def getPoint(self, location):
     return self.__points[location[0]][location[1]]
     
     def clear(self):
     self.__points.clear()
     for i in range(22):
     line = []
     if i == 0 or i == 21:
     for j in range(22):
      line.append('#')
     else:
     line.append('#')
     for j in range(20):
      line.append(' ')
     line.append('#')
     self.__points.append(line)
     
     def put_snake(self, snake_locations):
     # clear the board
     self.clear()
     
     # put the snake points
     for x in snake_locations:
     self.__points[x[0]][x[1]] = 'o'
     
     # the head
     x = snake_locations[len(snake_locations) - 1]
     self.__points[x[0]][x[1]] = 'O'
     
     def put_food(self, food_location):
     self.__points[food_location[0]][food_location[1]] = '*'
     
     def show(self):
     os.system("cls")
     for i in range(22):
     for j in range(22):
     print(self.__points[i][j], end='')
     print()
     
    # the snake class
    class snake:
     __points = []
     
     def __init__(self):
     for i in range(1, 6):
     self.__points.append([1, i])
     
     def getPoints(self):
     return self.__points
     
     # move to the next position
     # give the next head
     def move(self, next_head):
     self.__points.pop(0)
     self.__points.append(next_head)
     
     # eat the food
     # give the next head
     def eat(self, next_head):
     self.__points.append(next_head)
     
     # calc the next state
     # and return the direction
     def next_head(self, direction='default'):
     
     # need to change the value, so copy it
     head = copy.deepcopy(self.__points[len(self.__points) - 1])
     
     # calc the "default" direction
     if direction == 'default':
     neck = self.__points[len(self.__points) - 2]
     if neck[0] > head[0]:
     direction = 'up'
     elif neck[0] < head[0]:
     direction = 'down'
     elif neck[1] > head[1]:
     direction = 'left'
     elif neck[1] < head[1]:
     direction = 'right'
     
     if direction == 'up':
     head[0] = head[0] - 1
     elif direction == 'down':
     head[0] = head[0] + 1
     elif direction == 'left':
     head[1] = head[1] - 1
     elif direction == 'right':
     head[1] = head[1] + 1
     return head
     
    # the game
    class game:
     
     board = board()
     snake = snake()
     food = []
     count = 0
     
     def __init__(self):
     self.new_food()
     self.board.clear()
     self.board.put_snake(self.snake.getPoints())
     self.board.put_food(self.food)
     
     def new_food(self):
     while 1:
     line = random.randint(1, 20)
     column = random.randint(1, 20)
     if self.board.getPoint([column, line]) == ' ':
     self.food = [column, line]
     return
     
     def show(self):
     self.board.clear()
     self.board.put_snake(self.snake.getPoints())
     self.board.put_food(self.food)
     self.board.show()
     
     
     def run(self):
     self.board.show()
     
     # the 'w a s d' are the directions
     operation_dict = {b'w': 'up', b'W': 'up', b's': 'down', b'S': 'down', b'a': 'left', b'A': 'left', b'd': 'right', b'D': 'right'}
     op = msvcrt.getch()
     
     while op != b'q':
     if op not in operation_dict:
     op = msvcrt.getch()
     else:
     new_head = self.snake.next_head(operation_dict[op])
     
     # get the food
     if self.board.getPoint(new_head) == '*':
      self.snake.eat(new_head)
      self.count = self.count + 1
      if self.count >= 15:
      self.show()
      print("Good Job")
      break
      else:
      self.new_food()
      self.show()
     
     # 反向一Q日神仙
     elif new_head == self.snake.getPoints()[len(self.snake.getPoints()) - 2]:
      pass
     
     # rush the wall
     elif self.board.getPoint(new_head) == '#' or self.board.getPoint(new_head) == 'o':
      print('GG')
      break
     
     # normal move
     else:
      self.snake.move(new_head)
      self.show()
     op = msvcrt.getch()
     
    game().run()
    

    由于Python监听键盘很麻烦,没有C语言的kbhit(),所以这条贪吃蛇不会自己动,运行效果如下:
    在这里插入图片描述
    要求:用#表示边框,用*表示食物,o表示蛇的身体,O表示蛇头,使用wsad来移动

    Python版本:3.7.1

    系统环境:Win7

    类:

    board:棋盘,也就是游戏区域

    snake:贪吃蛇,通过记录身体每个点来记录蛇的状态

    game:游戏类

    本来还想要个food类的,但是food只需要一个坐标,和一个新建,所以干脆使用list来保存坐标,新建food放在game里面,从逻辑上也没有太大问题

    展开全文
  • 用python语言如何写:猜数字游戏,输入一个1--100的整数,如果和生成的随机数相比大了,则输出:你猜大了! 如果小了,则输出:你猜小了!,...
  • 练习一种编程语言最好的技巧...本文的内容就是讲一讲用python的第三方模块——pygame,点小游戏的技巧。 一.利用pygame制作游戏的原理 基本概念:在pygame中,有两种极为重要的类别——Surface和Rect,我们日常...

    练习一种编程语言最好的技巧就是写点游戏的demo,因为当看到自己的code最后能以一种GUI的形式展现在自己面前的时候,人们往往会获得一种巨大的满足感。俗话说:兴趣就是最好的老师。此言得之。本文的内容就是讲一讲用python的第三方模块——pygame,写点小游戏的技巧。

    一.利用pygame制作游戏的原理

    1. 基本概念:在pygame中,有两种极为重要的类别——Surface和Rect,我们日常中所看到的那些丰富多彩的游戏,以及里面数不胜数的人物,其实在一开始设计时都会将其抽象为简单的图形——比如说矩形。举几个例子,你看到某个游戏中的人物在跳跃,其实是一个矩型在上下移动;你看到有些人物在移动,其幕后就是一个矩形在平动,等等。对于这种抽象而来的矩形,在pygame中有一个专门的类别叫Rect,设计Rect的methods和properties是整个问题的core。在设计完Rect后,我们要做的就是把图像render到对应的Rect对象上,此时的图像也有个类别,叫做Surface。将Surface引入到程序中很简单,将Surface渲染到Rect中也只是一句话的事情,就是用Surface的blit的方法,具体的用法可以看official documentation,这里只讲思路,不讲details。
    2. 程序设计:大家都知道animation是由一帧一帧的静态图像构成的,我们想要绘画出流畅的动作(比如人物的移动等等),就要绘制整个动作所涉及到的所有frame。这个我们一般把它放到一个infinity loop中。当然在这个loop中除了绘制图片以外,我们还要加一点基本的logic,比如判断到底是要画人物的站立动作,还是跳跃动作等。小小总结一下,我们在loop中无非做两件事:判断人物的状态,绘画出本次循环的图像。我一般把人物的状态用一个(或多个)flag表示,最后用一个长的if语句(很遗憾,python没有switch语句,不然方便很多)根据flag绘画状态,我总是把所有状态都放在一个if中,这样可以避免重复绘画。

    二.事件循环

    一个游戏最重要地还是与用户的交互,其中扮演关键角色的就是事件循环(event loop),之前我们有提到要判断物体的状态,比方说他此时是移动还是原地不动。而决定物体运动状态的就是用户,此时我们就要写一个event loop来检测一下用户到底输入了什么东西,这个最简单的例子就是键盘上的上下左右键,我们可以通过检测用户到底按了哪颗键来记录物体的状态。在pygame中,常见的状态是这么几种:QUIT, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEUP和MOUSEMOTION,这几个事件的意思从其名称中就可见一斑,值得注意的是我们在KEYDOWN和KEYUP中可能还要再嵌套一个循环来检测到底是哪颗键,毕竟KEYDOWN和KEYUP实在是太笼统了。

    三.平动,转动和翻转

    下面我们来探讨下核心问题:Rect的运动

    1. 平动:对于平动,我所采用的方法是每次循环把x和y用自增运算符+=或-=物体目前的速度,这个比较好理解,不过有两点要注意:一是所设置的速度不能过大,可以想象当速度达到一定值时会出现“瞬移”的效果;二是要注意循环的时间间隔时不确定的,因此无法用以上方法精确地表达出物体精确地运动速度,换句话说:物体移动的速度大小是“凭感觉”设置的,其误差可以通过不断地更改参数来缩小。
    2. 转动:如果是转动的话,就要涉及到pygame自带的方法:transform.rotate(),如果要计算旋转的角度,可以用built-in的math模块,也可以用pygame自带的math模块,注意到前者一般是返回一个弧度制,而pygame接受的是一个角度制的,将弧度值转到角度值需要乘一个57.29
    3. 翻转:翻转和转动还是有细微的差别,比方说让一个图形水平翻转,就无法靠简单地让一个物体旋转一个角度来实现。至于翻转地实现,要用到的方法是transform.filp()

    四.精灵和组(Group)

    1. 精灵:pygame有一个非常重要的class的概念叫做Sprite,那么Sprite存在的意义是什么呢?我们不妨假设一个情景:检测物体与物体碰撞,如果是自己编写的话,就要利用坐标和宽度和高度检测此时是否有重叠的现象,比较麻烦。但是如果继承了Sprite类的话,就可以使用内置的方法来检测碰撞信息。当然Sprite肯定不止这一种方法,详情请见pygame的官方文档。
    2. :有些时候对象比较多,比如python crash course中的alian invasion这个游戏,就会创造大量的外星飞船,为了监控每一只外星飞船,我们可以使用list来储存每一个对象,然而这也比较麻烦,好在pygame有内置的Group类,这个Group类的目的就是用来存储并监控各种sprite对象以及sprite子类的对象的创建Group类的方法也比较简单,只要等于一个sprite.Group()即可。

    五.背景音乐和音效

    1. 背景音乐:背景音乐就是从游戏一开始就不断播放的音乐(废话),所以只要在一开始设置就行。话不多说,贴代码。
      pygame.mixer.music.load(music_address)
      pygame.mixer.music.play(-1, 0.0)
      pygame.mixer.music.set_volume(0.2)

      其中这个-1代表音乐的单曲循环。 set_volume是指设置音量,具体请查找官方文档。

    2. 音效:音效和背景音乐不同,音效往往是跟着游戏的内容所产生的。比如说两个人打架,那么在打架的整个过程中就应该有打击的音效,打击的代码也十分简单,下面贴出,从形式上就可以看出和BGM是不同的。

      skill = pygame.mixer.Sound(sound_address)
      skill.set_volume(0.25)

      然后再相应的状态中play即可。 

     

     六.字体和计时器

    下面讲一下计时器和字体,有了这两个以及上面的工具,我们就能够造出一个五脏俱全的小游戏了

    1. 字体:很多时候我们都要在游戏中加入文本,当然我们也可以导入文本模样的图片来模拟文本,不过这样做太麻烦,下面我们来看看文本到底是怎么添加到游戏中的。
      font = pygame.font.Font(None, size)
      text = font.render(txt, True, (0, 0, 0))
      text_rect = text.get_rect()
      text_rect.x = x
      text_rect.y = y
      screen.blit(text, text_rect)

       

    2. 计时器:计时器也很重要,有时我们就是要用计时器来决定游戏的走向,pygame也有内置的Clock类,不过其方法返回的基本是一个milliseconds,这时候我们就要将其整除1000来获得以秒为单位的时间。下面我用Font和Clock做了一个简单的计时器,注意要把它放在loop中:
      # Draw current time
      time = pygame.time.get_ticks()
      time_font = pygame.font.Font(None, 60)
      # This skill could calculate int time
      time_surface = time_font.render("Time:" + str(time // 1000), True, (0, 0, 0))
      screen.blit(time_surface, [330, 70])
      
       

       

       

       

     

     

     


     

    展开全文
  • 今天我来分享如何用python写一个王者荣耀游戏的外挂 是不可能的 但是我们可以写个小游戏–汉诺塔 的外挂,这个游戏相信很多同学都玩过。 开始是三层,还很简单,四层还好,五层六层就有点费脑壳了。 话不多说,...
  • 如何用Python写猜数字和字母的游戏

    千次阅读 2020-08-11 21:50:52
    学完语法和正在学习语法的时候,我们可以在空闲的时候,几个简单的小项目,今天我们就最基础的语法看两个实战语法练习 猜数字游戏 项目游戏说明:让用户输入一个数字,然后系统自动产生一个序列里面的随机数,...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 228
精华内容 91
关键字:

如何用python写游戏

python 订阅