终端游戏中光标无法回到打印区域开头以实现帧刷新的问题求助
终端游戏中光标无法回到打印区域开头以实现帧刷新的问题求助
我写了一个终端小游戏的代码,但现在卡壳了——我没法把光标移到整个打印内容的开头,这样就没法在下一帧覆盖掉之前的画面,实现游戏的动态刷新效果。我试着用控制字符移动光标,但它只能移到一半的位置,根本达不到预期效果。
你可以看看下面的代码,问题出在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




