You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

终端游戏中光标无法回到打印区域开头以实现帧刷新的问题求助

终端游戏中光标无法回到打印区域开头以实现帧刷新的问题求助

我写了一个终端小游戏的代码,但现在卡壳了——我没法把光标移到整个打印内容的开头,这样就没法在下一帧覆盖掉之前的画面,实现游戏的动态刷新效果。我试着用控制字符移动光标,但它只能移到一半的位置,根本达不到预期效果。

你可以看看下面的代码,问题出在print_game函数里的光标移动行(对应原代码第25行):

import sys
import colorama
from colorama import Fore, init, Back
from random import randint
from pytimedinput import timedInput
import os
import msvcrt

def print_game():
    for cell in CELLS:
        if list(cell) == Player:
            print(Fore.MAGENTA + "i", end="")
        elif cell in Border:
            print(Fore.GREEN + "█", end="")
        elif cell in Spikes:
            print(Fore.RED + "▲", end="")
        elif cell == Finish_Point:
            print("*", end="")
        else:
            print(" ", end="")
        if cell[0] == X-1:
            print("")
    sys.stdout.write('\x1b[50A')  # 这里是我尝试移动光标行,就是问题所在

def Gravity():
    if (Player[0], Player[1]+1) not in Border:
        if (Player[0], Player[1]+1) not in Spikes:
            Player[1] += 1

def Movement(key):
    if key == "d" and (Player[0]+1, Player[1]) not in Border:
        Player[0] += 1
    if key == "a" and (Player[0]-1, Player[1]) not in Border:
        Player[0] -= 1

def Jump():
    global Jump_Height, Player
    if (Player[0], Player[1]-1) in Border:
        Jump_Height = 0
    if Jump_Height != 0:
        Jump_Height -= 1
        Player[1] -= 1
    else:
        Gravity()

def Start_Menu_1():
    os.system("cls")
    print("""
______
| ___ \\
| |_/ /   _ _ __  _ __   ___ _ __
|    / | | | '_ \\| '_ \\ / _ \\ '__|
| |\\ \\ |_| | | | | | | |  __/ |
\\_| \\_\\__,_|_| |_|_| |_|\\___|_|
""")
    print( "                ",Back.WHITE + "PLAY")
    print( "                 QUIT")

def Start_Menu_2():
    os.system("cls")
    print("""
______
| ___ \\
| |_/ /   _ _ __  _ __   ___ _ __
|    / | | | '_ \\| '_ \\ / _ \\ '__|
| |\\ \\ |_| | | | | | | |  __/ |
\\_| \\_\\__,_|_| |_|_| |_|\\___|_|
""")
    print( "                ","PLAY")
    print( "                ", Back.WHITE + "QUIT")

def Lose_Menu():
    os.system("cls")
    print("""
__     __           _                      _
\\ \\   / /          | |                    | |
\\ \\_/ /__  _   _  | |     ___  ___  ___  | |
 \\   / _ \\| | | | | |    / _ \\/ __|/ _ \\ | |
 | | (_) | |_| | | |___| (_) \\__ \\  __/ |_|
 |_|\\___/ \\__,_| |______\\___/|___/\\___| (_)
""")
    input("press enter to  'Exit' ")

def Win_Menu():
    os.system("cls")
    print("""
__     __                                 _
\\ \\   / /                                | |
\\ \\_/ /__  _   _  __      _____  _ __   | |
 \\   / _ \\| | | | \\ \\ /\\ / / _ \\| '_ \\  | |
 | | (_) | |_| |  \\ V  V / (_) | | | | |_|
 |_|\\___/ \\__,_|   \\_/\\_/ \\___/|_| |_| (_)
""")
    input("press enter to  'Exit' ")

init(autoreset=True)
colorama.init()

# SETTINGS
Y = 42
X = 36

Border = [
    (26, 0), (27, 0), (28, 0), (29, 0), (30, 0), (31, 0), (32, 0), (33, 0), (34, 0), (35, 0),
    (26, 1), (35, 1), (26, 2), (35, 2), (26, 3), (35, 3), (26, 4), (30, 4), (31, 4), (32, 4),
    (33, 4), (35, 4), (18, 5), (19, 5), (20, 5), (21, 5), (22, 5), (23, 5), (24, 5), (25, 5),
    (26, 5), (30, 5), (35, 5), (18, 6), (30, 6), (35, 6), (18, 7), (30, 7), (35, 7), (18, 8),
    (30, 8), (32, 8), (35, 8), (18, 9), (22, 9), (23, 9), (24, 9), (25, 9), (26, 9), (27, 9),
    (28, 9), (29, 9), (30, 9), (32, 9), (35, 9), (18, 10), (23, 10), (24, 10), (30, 10), (32, 10),
    (33, 10), (34, 10), (35, 10), (18, 11), (19, 11), (20, 11), (24, 11), (30, 11), (32, 11),
    (18, 12), (24, 12), (30, 12), (32, 12), (13, 13), (14, 13), (15, 13), (16, 13), (17, 13),
    (18, 13), (22, 13), (23, 13), (24, 13), (32, 13), (11, 14), (1, 14), (2, 14), (3, 14), (4, 14),
    (5, 14), (6, 14), (7, 14), (8, 14), (12, 14), (13, 14), (23, 14), (32, 14), (0, 15), (1, 15),
    (8, 15), (9, 15), (10, 15), (11, 15), (23, 15), (25, 15), (29, 15), (30, 15), (31, 15), (32, 15),
    (0, 16), (9, 16), (18, 16), (19, 16), (20, 16), (21, 16), (22, 16), (23, 16), (25, 16), (29, 16),
    (0, 17), (9, 17), (18, 17), (25, 17), (29, 17), (0, 18), (9, 18), (18, 18), (25, 18), (29, 18),
    (0, 19), (9, 19), (10, 19), (11, 19), (12, 19), (13, 19), (14, 19), (16, 19), (17, 19), (18, 19),
    (25, 19), (26, 19), (27, 19), (28, 19), (29, 19), (0, 20), (3, 20), (14, 20), (15, 20), (16, 20),
    (18, 20), (25, 20), (0, 21), (3, 21), (4, 21), (18, 21), (25, 21), (0, 22), (3, 22), (4, 22),
    (5, 22), (18, 22), (25, 22), (0, 23), (3, 23), (4, 23), (5, 23), (6, 23), (18, 23), (25, 23),
    (0, 24), (2, 24), (3, 24), (4, 24), (5, 24), (6, 24), (7, 24), (8, 24), (9, 24), (10, 24),
    (11, 24), (12, 24), (13, 24), (14, 24), (15, 24), (16, 24), (17, 24), (18, 24), (25, 24),
    (0, 25), (18, 25), (25, 25), (0, 26), (18, 26), (25, 26), (0, 27), (18, 27), (25, 27),
    (0, 28), (18, 28), (25, 28), (0, 29), (1, 29), (2, 29), (3, 29), (4, 29), (5, 29), (6, 29),
    (7, 29), (8, 29), (9, 29), (10, 29), (11, 29), (12, 29), (13, 29), (14, 29), (15, 29), (16, 29),
    (18, 29), (25, 29), (13, 30), (18, 30), (25, 30), (13, 31), (18, 31), (25, 31), (13, 32),
    (18, 32), (25, 32), (13, 33), (16, 33), (17, 33), (18, 33), (25, 33), (13, 34), (15, 34),
    (18, 34), (25, 34), (13, 35), (18, 35), (25, 35), (13, 36), (14, 36), (15, 36), (18, 36),
    (25, 36), (15, 37), (18, 37), (25, 37), (15, 38), (18, 38), (19, 38), (20, 38), (21, 38),
    (23, 38), (24, 38), (25, 38), (15, 39), (23, 39), (15, 40), (23, 40), (15, 41), (16, 41),
    (17, 41), (18, 41), (19, 41), (20, 41), (21, 41), (22, 41), (23, 41)
]

Spikes = [
    (33, 9), (34, 9), (26, 18), (27, 18), (28, 18), (3, 19), (15, 19), (4, 20), (5, 21),
    (6, 22), (7, 23), (9, 23), (10, 23), (11, 23), (12, 23), (13, 23), (3, 28), (4, 28),
    (5, 28), (7, 28), (9, 28), (11, 28), (13, 28), (15, 28), (15, 33), (19, 37), (20, 37),
    (21, 37), (23, 37), (24, 37), (16,40)
]

Finish_Point = (17, 23)
Player = [11, 18]
Jump_Height = 0
CELLS = [(x, y) for y in range(Y) for x in range(X)]

main_sc=0
while True:
    if main_sc==0:
        Start_Menu_1()
    else:
        Start_Menu_2()
    aa=msvcrt.getch().decode("ASCII")
    if aa == "B":
        print("Runnner............")
        input()
    if aa=="w" and main_sc!=0:
        Start_Menu_1()
        main_sc=0
    if aa=="s" and main_sc!=1:
        Start_Menu_2()
        main_sc=1
    if aa==" " :
        if main_sc == 0:
            os.system('cls')
            while True:
                print_game()
                Jump()
                Move, _ = timedInput("", timeout=0.05)
                if Move == "d":
                    Movement("d")
                if Move == "a":
                    Movement("a")
                if Move == "w" and (Player[0], Player[1]+1) in Border and Jump_Height == 0:
                    b = randint(0, 2)
                    if b != 1:
                        Jump_Height = 3
                    else:
                        Jump_Height = 6
                if Move == "p" :
                    break
                if (Player[0], Player[1]+1) in Spikes or (Player[0], Player[1]+1-1) in Spikes:
                    if Jump_Height == 0 :
                        Lose_Menu()
                        break
                #sys.stdout.write('\x1b[43A')
            else:
                exit()
            Player = [11, 18]

我试过用sys.stdout.write('\x1b[50A')来向上移动50行,但看起来这个数值不对,光标只能回到一半的位置,没法覆盖整个游戏画面。有没有大佬能指点一下,怎么才能准确把光标移到游戏打印区域的开头,实现帧刷新呢?

备注:内容来源于stack exchange,提问作者Blue Boi

火山引擎 最新活动