pygame 实现的一个丑陋的控制台(正在施工中... )

前言

exit 退出。
$ var 添加查看。
# var 删除查看。
exp 执行表达式中的程序。

效果图

console

pygame_console.py

# pygame 的多行输入尝试

# coding=utf-8
 
import pygame
import time
from pygame.locals import *
from sys import exit

pygame.init()
pygame.display.set_caption("GGN Pygame Console") # 标题

font = pygame.font.SysFont('consolas', 20) # Name Size
fullScreenState = FULLSCREEN

Resolution = (1920,1080) # 分辨率

screen = pygame.display.set_mode(Resolution, fullScreenState, 32) # 设置显示区域
linePos = 0 # 当前光标所在的列(光标在下标为 linePos 的字符前面)

def SparTime(msg, string): # 按照时间进行闪烁
    if int(time.time() * 2) % 2 != 0:
        string = len(string) * " " # 奇数不显示,偶数显示
    if linePos == len(msg):
        return msg + string
    else:
        return msg[:linePos] + string + msg[linePos:] # 中间插入

message = ""
text = font.render(">>>" + SparTime(message, "_"), True, (34, 252, 43)) # 文本框

history = []
memory = []

help = None # 帮助文档会把解释器卡死

def Find(memo, key): # 在 list 中匹配
    for i in range(0, len(memo)):
        if memo[i] == key:
            return i
    return -1 # not found

def StrCut(string): # 截取字符串
    if len(string) > 64:
        return string[:64] + " ..."
    return string

position = 0 # 当前所在历史记录的行

def GetVal(string): # TODO: 不安全
    return string.split(" => Exec ")[0] # 截取运行信息前的部分

while True:
    for event in pygame.event.get():
        if event.type==QUIT:
            exit()
        if event.type==KEYDOWN:
            if event.unicode != "" and len(message) < 64: # 输入可以被视为字符
                if linePos < len(message):
                    message = message[:linePos] + event.unicode + message[linePos:]
                    linePos += 1
                else:
                    message += event.unicode # 尾部追加
                    linePos += 1
                pygame.time.wait(10)
                #text = font.render(">>>" + message + SparTime("_"), True, (34, 252, 43)) # 文本框
                pygame.event.clear() # 清空 100 ms 内的输入信息

            if event.key == K_BACKSPACE: # 删除一个末尾字符
                if message != "":
                    if linePos != 0:
                        message = message[: linePos-1] + message[linePos:]
                        linePos -= 1
                    pygame.time.wait(10)
                    #text = font.render(">>>" + message + SparTime("_"), True, (34, 252, 43)) # 文本框
                    pygame.event.clear() # 清空 100 ms 内的输入信息

            elif event.key == K_RETURN: # 按下 RETURN 换行
                linePos = 0
                if message == "exit": # 退出功能
                    exit()
                if message[0] == "$": # 添加查看变量
                    if len(message) != 1: # 添加查看
                        if Find(memory, message[1:]) == -1:
                            memory.append(message[1:])
                        # print("memory = " + str(memory))
                        message = ""
                elif message[0] == "#": # 清除查看变量
                    if len(message) != 1:
                        pos = Find(memory, message[1:])
                        if pos != -1:
                            del memory[pos]
                        message = ""
                elif message != "": # 执行 python 语句
                    try:
                        exec(message)
                        history.append(message + " => Exec End.")
                    except:
                        history.append(message + " => Exec Fail.")
                    message = ""
                    position = len(history)

                #text = font.render(">>>" + message + SparTime("_"), True, (34, 252, 43)) # 文本框
                #pygame.event.clear() # 清空 100 ms 内的输入信息

            elif event.key == K_ESCAPE: # 按下 ESC 全屏与非全屏切换
                if fullScreenState == FULLSCREEN:
                    fullScreenState = 0
                    screen = pygame.display.set_mode(Resolution, 0, 32) # 设置显示区域
                else:
                    fullScreenState = FULLSCREEN
                    screen = pygame.display.set_mode(Resolution, FULLSCREEN, 32) # 设置显示区域

            elif event.key == K_DOWN: # 翻阅消息记录
                if position >= 1:
                    position -= 1
                    if position < len(history):
                        message = GetVal(history[position])
                    else:
                        message = ""
                    linePos = 0

            elif event.key == K_UP: # 翻阅消息记录
                if position < len(history):
                    position += 1
                    if position < len(history):
                        message = GetVal(history[position])
                    else:
                        message = ""
                    linePos = 0
            
            elif event.key == K_LEFT: # 移动光标
                if linePos >= 1:
                    linePos -= 1

            elif event.key == K_RIGHT: # 移动光标
                if linePos < len(message):
                    linePos += 1
    
    screen.fill((0,0,0)) # 黑色背景
    text = font.render(">>>" + SparTime(message, "_"), True, (34, 252, 43)) # 文本框
    screen.blit(text, (40, 100)) # 放置文本框
    for i in range(0, len(history)): # 历史命令
        pre = "   "
        if len(history) - i - 1 == position: # 倒序输出历史记录
            pre = "-> "
        tmp = font.render(StrCut(pre + history[len(history)-i-1]), True, (34, 252, 43)) # 文本框
        screen.blit(tmp, (40, 100 + (i + 2) * 22)) # 放置文本框
    
    for i in range(0, len(memory)):
        try:
            tmp = font.render(StrCut(memory[i] + " = " + str(eval(memory[i]))), True, (34, 252, 43))
        except:
            tmp = font.render(memory[i] + " = Value Error." , True, (34, 252, 43))
        screen.blit(tmp, (800, 100 + (i + 2) * 22)) # 放置文本框
    pygame.display.update()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值