我用Python编写了一个在控制台中运行的3D游戏。为了防止它闪烁,我必须将要显示的内容写入ConsoleScreenBuffer
。文件是this。我知道我必须使用:
import win32console
buffer = win32console.CreateConsoleScreenBuffer()
但是CreateConsoleScreenBuffer()
的参数是什么?文件中说:
HANDLE WINAPI CreateConsoleScreenBuffer(
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ const SECURITY_ATTRIBUTES *lpSecurityAttributes,
_In_ DWORD dwFlags,
_Reserved_ LPVOID lpScreenBufferData
);
这在C中。help(win32console.CreateConsoleScreenBuffer)
没有提供有用的信息。前两个参数是int,第二个是“PySECURITY_ATTRIBUTES”-对象,第三个也是int(我想是吧?)
CreateConsoleScreenBuffer(DesiredAccess, ShareMode, SecurityAttributes, Flags)
DesiredAccess=GENERIC_READ and GENERIC_WRITE : int
GENERIC_READ and/or GENERIC_WRITE
ShareMode=FILE_SHARE_READ and FILE_SHARE_WRITE : int
FILE_SHARE_READ and/or FILE_SHARE_WRITE
SecurityAttributes=None : PySECURITY_ATTRIBUTES
Specifies security descriptor and inheritance for handle
Flags=CONSOLE_TEXTMODE_BUFFER : int
CONSOLE_TEXTMODE_BUFFER is currently only valid flag
我没有发现任何在线实施的例子
如果您知道任何其他使控制台绘制更快的方法,请告诉我
这是我的(不是喷气机)游戏。它会闪烁,因为它绘制得不够快。我遵循的教程是C++,使用CreateConsoleScreenBuffer消除闪烁,因为所有的东西都是一次绘制而不是绘制。 相继地
import os
import time
import math
import threading
hardMap = [
["#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".","#",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#",".",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#","#",".",".",".",".",".",".",".",".",".",".",".",".",".","#"],
["#","#","#",".",".",".",".",".",".",".",".",".",".",".","#","#"],
["#","#","#","#","#","#","#","#","#","#","#","#","#","#","#","#"],
]
gameMap = "".join(["".join(hardMap[n]) for n in range(len(hardMap))])
notDone = True
rotationSpeed = 0.02
playerX = 5
playerY = 5
playerA = 0
fov = 4
fov = math.pi / fov
depth = 20
fps = 30
screenWidth = 120
screenHeight = 40
os.system(f'mode con: cols={screenWidth} lines={screenHeight}')
screen = [" " for n in range(screenHeight * screenWidth)]
mapWidth = len(hardMap[0])
mapHeight = len(hardMap)
def printScreen(string):
os.system('cls')
time.sleep(0.01)
for x in [string[i:i+screenWidth] for i in range(0,len(string),screenWidth)]:
print("".join(x))
c = 0
while(notDone):
c += 1
playerA = playerA + rotationSpeed
startTime = time.time()
for x in range(screenWidth):
rayAngle = (playerA - fov / 2) + ((x / screenWidth) * fov)
distanceToWall = 0
hitWall = False
shade = " "
eyeX = math.sin(rayAngle)
eyeY = math.cos(rayAngle)
"""
with open("log.txt","a") as f:
f.write("x"+str(eyeX)+"\n")
f.write("y"+str(eyeY)+"\n")
f.write("h"+str(mapHeight)+"\n")
f.write("w"+str(mapWidth)+"\n")
f.write("\n")
"""
while not hitWall and distanceToWall < depth:
distanceToWall = distanceToWall + 0.1
testX = int(playerX + eyeX * distanceToWall)
testY = int(playerY + eyeY * distanceToWall)
if testX < 0 or testX >= mapWidth or testY < 0 or testY>= mapHeight:
hitWall = True
distanceToWall = depth
elif gameMap[testY * mapWidth + testX] == "#":
hitWall = True
ceiling = int((screenHeight / 2.0) - (screenHeight / distanceToWall))
floor = screenHeight - ceiling
for y in range(screenHeight):
if y < ceiling:
screen[y * ceiling + x] = " "
elif y > ceiling and y <= floor:
if distanceToWall <= depth / 4: shade = u"\u2588"
elif distanceToWall < depth / 3: shade = u"\u2593"
elif distanceToWall < depth / 2: shade = u"\u2592"
elif distanceToWall < depth / 1: shade = u"\u2591"
else: shade = " "
screen[y * screenWidth + x] = shade
else:
b = 1.0 - ((y - screenHeight / 2.0) / (screenHeight/2))
if b < 0.25: shade = "#"
elif b < 0.5: shade = "X"
elif b < 0.75: shade = "."
elif b < 0.9: shade = "-"
else: shade = " "
screen[y * screenWidth + x] = shade
printScreen(screen)
"""
with open("log.txt","a") as f:
f.write(str("\n".join(screen)))
f.write("\n\n\n\n\n\n\n\n")
"""
time.sleep(max(1./fps - (time.time() - startTime), 0))
我假设您正在学习javid/OLC的控制台FPS教程
简单的答案是:您需要
win32con
和win32console
,下面是一个更好的答案有点晚了,但是这个页面:win32console docs @ Tim Golden和PyConsoleScreenBuffer Object @ Tim Golden对于解决这个问题非常有用。有两种方法可以做到这一点。一个是使用
win32console and win32con
,另一个是使用ANSI转义序列。实际上,您所要做的就是将光标移动到控制台上的0,0处进行打印。这里是方法一:这在控制台FPS中应该可以正常工作(使用WriteConsoleOutputCharacter)。只要把命令放在javid放的地方就可以了。第二种方法是使用colorama/ANSI序列将光标返回到起始位置。这种方法可以总结为:
os.system("echo \033[0;0H")
。不能使用print
函数使用转义序列,它们不受支持(使用colorama除外)。以下是一个例子:我希望这有帮助天空
相关问题 更多 >
编程相关推荐