打字机效果 Pygame

2023-12-01

这个问题确实很难问,但我知道 Stack Overflow 的你们都是最聪明的人。

我完全不知道为什么会发生这个问题(我对 Python 和 Pygame 相当熟悉,所以任何关于如何改进代码的建议都会带着提高我的技能的热爱而被接受)。

我正在创建什么: 这确实是一个噱头项目,我在 Raspberry Pi 上连接了一个 2.5 英寸的小屏幕 (PiTFT),代码创建了一个打字机效果,在编写文本时在文本前面有一个移动光标。

挑战 1 是,每次在 pygame 中移动精灵时,都必须重新绘制所有内容,否则您会看到一条轨迹,并且由于光标在文本前面移动,因此结果将如下所示:

enter image description here

我设法通过黑化/清除屏幕来解决这个问题。但后来我把以前写的信全都丢了。 因此,我创建了一个列表(整个单词),其中填充了所有以前编写的字符。我每次循环循环时都会使用此列表来重绘所有以前编写的文本。 所以现在:

Sample of issue

正如您所看到的,文本看起来很有趣。 应该是这样写的:

[i] 初始化...

[i] 进入幽灵模式...[]

我花了很多时间才达到这一点 - 并且代码几乎完美运行!神奇的事情发生在函数 print_screen() 中,但是我的代码中是什么导致文本最后包含了另一行的字母? :>

非常感谢您的帮助

这是完整的代码:

import pygame
import time
import os
import sys
from time import sleep
from pygame.locals import *

positionx = 10
positiony = 10
entireword = []
entireword_pos = 10
counter = 0
entire_newline = False


#Sets the width and height of the screen
WIDTH = 320
HEIGHT = 240
speed = 0.05

#Importing the external screen
os.putenv('SDL_FBDEV', '/dev/fb1')
os.putenv('SDL_MOUSEDRV', 'TSLIB')
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')

#Initializes the screen - Careful: all pygame commands must come after the init
pygame.init()

#Sets mouse cursor visibility
pygame.mouse.set_visible(False)
#Sets the screen note: must be after pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))

# initialize font; must be called after 'pygame.init()' to avoid 'Font not Initialized' error
myfont = pygame.font.SysFont("monospace", 18)

#Class

class cursors(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 20))
        self.image.fill((0,255,0))
        self.rect = self.image.get_rect()
        self.rect.center = (positionx + 10, positiony + 10)

    def update(self):
        self.rect.x = positionx + 10
        self.rect.y = positiony

#Functions

#Prints to the screen
def print_screen(words, speed):
    rel_speed = speed
    for char in words:
        #speed of writing
        if char == ".":
            sleep(0.3)
        else:
            sleep(rel_speed)

        #re-renders previous written letters
        global entireword

        # Old Typewriter functionality - Changes position of cursor and text a newline

        #Makes sure the previous letters are rendered and not lost
        #xx is a delimter so the program can see when to make a newline and ofcourse ignore writing the delimiter
        entireword.append(char)
        if counter > 0:
            loopcount = 1
            linecount = 0 # This is to which line we are on
            for prev in entireword:
                if prev == 'xx':
                    global linecount
                    global positiony
                    global loopcount
                    linecount = linecount + 1
                    positiony = 17 * linecount
                    loopcount = 1
                if prev != 'xx':  #ignore writing the delimiter
                    pchar = myfont.render(prev, 1, (255,255,0))
                    screen.blit(pchar, (loopcount * 10, positiony))
                    loopcount = loopcount + 1

        if char != 'xx':
            # render text
            letter = myfont.render(char, 1, (255,255,0))
            #blits the latest letter to the screen
            screen.blit(letter, (positionx, positiony))

        # Appends xx as a delimiter to indicate a new line
        if entire_newline == True:
            entireword.append('xx')
            global entire_newline
            entire_newline = False

        global positionx
        positionx = positionx + 10
        all_sprites.update()
        all_sprites.draw(screen)
        pygame.display.flip()
        screen.fill((0,0,0)) # blackens / clears the screen

        global counter
        counter = counter + 1

#Positions cursor at new line
def newline():
    global positionx
    global positiony
    positionx = 10
    positiony = positiony + 17

all_sprites = pygame.sprite.Group()
cursor = cursors()
all_sprites.add(cursor)

#Main loop
running = True
while running:
    global speed
    global entire_newline

    words = "[i] Initializing ..."
    entire_newline = True
    newline()
    print_screen(words,speed)

    words = "[i] Entering ghost mode ..."
    entire_newline = True
    newline()
    print_screen(words,speed)

    #Stops the endless loop if False
    running = False
sleep(10)

很抱歉,如果我不直接回答你的问题,因为你的代码现在对我来说太混乱了,所以我冒昧地重写了你的代码来完成你想要的事情。

这个想法是有两个精灵:

  • 光标,a) 显示在屏幕上,b) 跟踪要写入的文本和位置

  • 板,基本上只是渲染文本的表面

注意所有的书写逻辑是如何在Cursor类,我们有一个漂亮、简单且愚蠢的主循环。

import pygame
import os

#Sets the width and height of the screen
WIDTH = 320
HEIGHT = 240

#Importing the external screen
os.putenv('SDL_FBDEV', '/dev/fb1')
os.putenv('SDL_MOUSEDRV', 'TSLIB')
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')

#Initializes the screen - Careful: all pygame commands must come after the init
pygame.init()
clock = pygame.time.Clock()

#Sets mouse cursor visibility
pygame.mouse.set_visible(False)
#Sets the screen note: must be after pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))


class Board(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((WIDTH, HEIGHT))
        self.image.fill((13,13,13))
        self.image.set_colorkey((13,13,13))
        self.rect = self.image.get_rect()
        self.font = pygame.font.SysFont("monospace", 18)

    def add(self, letter, pos):
        s = self.font.render(letter, 1, (255, 255, 0))
        self.image.blit(s, pos)

class Cursor(pygame.sprite.Sprite):
    def __init__(self, board):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 20))
        self.image.fill((0,255,0))
        self.text_height = 17
        self.text_width = 10
        self.rect = self.image.get_rect(topleft=(self.text_width, self.text_height))
        self.board = board
        self.text = ''
        self.cooldown = 0
        self.cooldowns = {'.': 12,
                        '[': 18,
                        ']': 18,
                        ' ': 5,
                        '\n': 30}

    def write(self, text):
        self.text = list(text)

    def update(self):
        if not self.cooldown and self.text:
            letter = self.text.pop(0)
            if letter == '\n':
                self.rect.move_ip((0, self.text_height))
                self.rect.x = self.text_width
            else:
                self.board.add(letter, self.rect.topleft)
                self.rect.move_ip((self.text_width, 0))
            self.cooldown = self.cooldowns.get(letter, 8)

        if self.cooldown:
            self.cooldown -= 1

all_sprites = pygame.sprite.Group()
board = Board()
cursor = Cursor(board)
all_sprites.add(cursor, board)

text = """[i] Initializing ...
[i] Entering ghost mode ...

done ...

"""

cursor.write(text)

#Main loop
running = True
while running:

    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False

    all_sprites.update()
    screen.fill((0, 0, 0))
    all_sprites.draw(screen)
    pygame.display.flip()
    clock.tick(60)

enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

打字机效果 Pygame 的相关文章

随机推荐

  • 使用 exit(1) 时释放内存,C++

    我正在做一项学校作业 我们被告知 每当我们有意见时 错误我们应该打印一条消息并退出程序 显然我使用 exit 1 但是 问题是我在使用这个函数时出现内存泄漏 我不明白为什么 我使用的每个变量都在堆栈上而不是在堆上 我应该做什么来防止这些内存
  • React:如何加载和渲染外部html文件?

    我使用 React 和 Redux 构建了一个小型博客应用程序 博客显示帖子页面 其中包含帖子的标题 作者 标签和描述 当单击标题或 阅读更多 按钮时 我想从本地项目的数据文件夹中加载并呈现一个包含所有帖子的相应帖子的 HTML 文件 Re
  • git checkout [commit-name] 与带点的比较

    有什么区别git checkout commit name and git checkout commit name 我看到第一个命令更改为分离的头状态 您可以从那里提交并继续创建一个新分支 我对第二个命令的作用感到困惑 它保留在主服务器上
  • 如何使用Fast Member将数据批量复制到列名不一致的表中?

    我有一个Person具有以下列名的表 身份证号 姓名 出生日期 我也有一个 poco 作为 public class Person public int Id get set public string Name get set publi
  • 画布宽度值不正确

    所以我认为代码
  • 检测页面上的任何内容是否正在动画化

    我知道关于 animated选择器 但目前正在遇到 可能是少数几个 旧版 IE 的性能问题 见图 我觉得这可能是我正在测试的方式ANY页面动画 目前我正在循环一个间隔 核心测试是 is animated This 这就是我担心的 但由于我不
  • 提交表单数据而不重新加载页面

    我尝试提交表单而不使用 jQuery 重新加载页面本身 但是数据没有显示 并且表单正在重新加载 这是不需要的 jQuery 代码 function submitFormData var firstval first val var seco
  • 如何转置 dask 数据框(将列转换为行)以实现整洁的数据原则

    TLDR 我从 dask bag 创建了一个 dask 数据框 dask 数据框将每个观察 事件 视为一列 因此 我没有为每个事件提供几行数据 而是为每个事件提供一列 目标是将列转置为行 就像 pandas 使用 df T 转置数据帧一样
  • SQL 连接和连接行

    我在两个表之间有多对多关系 Table God Restaurants包含我的餐馆 Table God RestaurantKat包含不同的类别 Table God RestKatReference包含两列 每列保存两个表的 id 以下语句
  • 使用 .htaccess 基于日期和名称的友好 URL

    我计划将我的博客从 wordpress com 上切换到在我自己的服务器上托管的我自己的网站上 当然 我想保留 WordPress 的链接结构 这样 WWW 上指向我博客的链接就不会中断 所以我的问题是 如何获得以下友好的 URL http
  • 如何在 MATLAB 中更改条形颜色

    我是编程新手 所以我正在学习 MATLAB 入门 我想知道如何更改 MATLAB 中条形图的颜色 这是我的脚本 有人可以帮忙吗 x 1 8 for y 20 30 40 50 60 70 80 bar x y if y lt 40 col
  • 使用 XIB 和以编程方式执行视图的优点和缺点

    我想决定是使用 XIB 更好还是完全使用代码设计我的视图 到目前为止 我已经读到 当您在界面生成器上设计视图时 它们是预先构建的 因此即使它们使用更多内存 用户也会感觉一切都更快 人们说使用代码做所有事情都比较困难 但我发现它同样容易 所以
  • 使用 Apache Beam 将插入流式传输到 BigQuery 时如何指定 insertId

    BigQuery 支持流式插入的重复数据删除 如何通过 Apache Beam 使用此功能 https cloud google com bigquery streaming data into bigquery dataconsisten
  • 使用jdom创建xml,如何设置standalone =“no”属性

    当我创建 jdom 文档 Document doc new Document 时 默认情况下我只在 xml 标头中看到版本和编码 如何添加独立属性以获得 在文档到达 JDOM 之前 XMLParser 通常会删除标头 我很确定你的意思是你正
  • Font Awesome 无法使用 vue 正确更新

    我正在尝试使用 font awesome 和 bulma 制作一个可点击的 星 图标 在 Vue 中的常规样式和实体样式 fas 和 far 之间切换 为了实现此目的 我有以下组件
  • 原生 GetUninitializedObject 实际存在于哪里?

    我对一些序列化的东西很好奇 所以我四处探索FormatterServices并找到了一个名为的方法nativeGetUninitializedObject它实际上处理给定类型的初始化 不调用构造函数 该方法装饰有extern关键字和以下属性
  • c 分段错误 fgets

    int main int argc char argv FILE inFilePtr fopen argv 1 r char rawdata malloc sizeof char 100 float ary malloc sizeof fl
  • 两个移动物体与纬度/经度坐标的交点

    尽管我已经阅读了几篇文章 但到目前为止我还无法真正解决这个问题 希望有人可以在这里提供帮助 事实 已知变量 地球表面上的两个移动物体 均具有当前已知的纬度 经度坐标 两个物体的速度也是已知的 以米 秒为单位 一个物体的方向 角度 是已知的
  • HybridAuth / PHP Facebook SDK 身份验证失败(getUser 返回 0)

    我正在尝试配置 HybridAuth 目前还处于早期阶段 现在我想做的就是连接并确保 HA 将重定向到 Facebook 并提示安装应用程序 然后在用户返回时对用户进行身份验证 我正在手动调用以下位置 http mydomain com a
  • 打字机效果 Pygame

    这个问题确实很难问 但我知道 Stack Overflow 的你们都是最聪明的人 我完全不知道为什么会发生这个问题 我对 Python 和 Pygame 相当熟悉 所以任何关于如何改进代码的建议都会带着提高我的技能的热爱而被接受 我正在创建