我正在用Python编写一个非常简单的农业游戏,使用诅咒。在这一点上,我已经成功地允许玩家(只是一个"@“角色)在窗口内移动。
我有几个文件与ascii艺术,我打印到窗口的东西,以填充世界,在其中的球员可以四处移动。例如,我有一个名为"house“的文件,其中包含:
_ . ^ . _
/____.____\
| |
| ## _ ## |
|_""_H_""_|我有一个课程如下:
class Thing(object):
def __init__(self, Xstart, Ystart, looksLike, list, window):
self.Xstart = Xstart
self.Ystart = Ystart
self.X = Xstart
self.Y = Ystart
self.looksLike = looksLike
self.boundries = []
self.find_boundries()
list.append(self)
self.draw(window)
def find_boundries(self):
file = open(self.looksLike).readlines()
for line in file:
for char in line:
if char == '\n':
pass
elif char == ' ': # skip all whitespace
self.X += 1
else:
self.boundries.append([self.X, self.Y])
self.X += 1
self.Y += 1
self.X = self.Xstart
self.X = self.Xstart # reset x & y to starting coordinates
self.Y = self.Ystart
def draw(self, window):
#file = open(self.looksLike).readlines()
#for line in file:
# window.addstr(self.Y, self.X, line)
# self.Y += 1
#self.Y = self.Ystart
file = open(self.looksLike).read()
for char in file:
window.addch(self.Y, self.X, char)
if char == '\n':
self.Y += 1
self.X = self.Xstart
else:
self.X += 1
self.X = self.Xstart
self.Y = self.Ystart因此,my Thing类的构造函数以一个文件名作为参数(looksLike),而its方法打开文件,读取文件,并将其内容打印到窗口。然后,我可以创建一个house对象,将我的" house“文件作为参数传递,我的ascii house将被打印到窗口。
问题是,一旦对象被打印到窗口,当我将播放机移到打印对象的右侧时,播放机就消失了。然而,在上面、下面和打印对象的左边,播放机仍停留在视图中。例如,
_ . ^ . _
/____.____\
| |
| ## _ ## |
|_""_H_""_|
@在这个位置,"@“字符是可见的,但是如果我向上移动一个空格,它就消失了。如果我继续移动玩家向上,"@“将再次出现后,它移动到最上面的角色的房子。
我认为这个问题是由于addstr()和addch() (我都尝试过)在窗口结束之前打印空白的性质造成的,但是我一直找不到关于这方面的任何文档。
我已经考虑过为每个打印的对象创建一个新窗口,但是当有超过几个对象被打印到窗口时,这似乎会变得非常麻烦。另外,我希望定义打印到屏幕上的物体周围的边框,这些物体的形状不仅仅是方形或矩形。
是否有从文件到窗口的打印,没有尾随空格,也没有为每个打印对象创建一个新窗口?
发布于 2014-01-01 01:53:09
我假设这个问题是由于addstr()和addch() (我都尝试过)打印空白直到窗口结束的性质所致,
你为什么这么认为?
首先,您从未在您向我们展示的代码中实际调用addstr,所以不可能是这样。
至于addch,它绝对不应该这样做--正如您所看到的那样,例如,从右到左的绘制。或者通过运行这些琐碎的测试代码:
# usual curses setup
stdscr.addch(10, 10, 'a')
stdscr.addch(10, 9, 'b')如果你没有在测试程序中看到a,你的终端就有问题了。但如果你是,那么你的假设是错误的,这与addch无关。
几乎可以肯定的是,问题是您实际上在房子文件中有空位。在诅咒中,如果你在另一个字符的上面画一个字符,它就会取代旧的字符,它不会试图合并它们或攻击它们或类似的东西。(这很好,因为大多数控制台没有任何方法来做任何这样的事情,…)
如果新字符是空格,它只是用空格替换旧字符。就像你看到的一样。
所以,修复方法是删除每一行末尾的所有空格,对吗?好吧,你可以这么做。或者你只需要rstrip()每一行。(您不需要\n;您可以通过完成对整个行的迭代来判断您已经到了一行的末尾,对吧?那么,您可以在您的file = open(…).readlines()代码中,或者在不麻烦readlines()的代码中,只在文件本身上循环;您不能使用不同的file = open(…).read()代码,但我不知道您为什么要在那里进行不同的操作。)
或者,由于您的find_boundries函数非常小心地跳过空格,所以您可能想在draw中做同样的事情,但忘记了吗?如果是这样的话,只需编写您打算跳过空格的代码。
但是,对于整个问题,有一个简单得多的解决方案:只需在房子后面而不是在它之前绘制@,这根本就不是一个问题。当然,这意味着如果玩家和房子在同一个地方,他会出现在房子的“外面”,而不是隐藏在“-but”里面--你已经有了防止这种情况发生的代码,所以如果它发生的话,它看起来应该不会有什么关系。
发布于 2014-01-01 01:33:39
幸运的是,我从来没有使用过诅咒,我不能看到你的玩家阶级。
尽管如此,这个片段可能会给您一些想法(按'x‘退出游戏)(使用WASD移动播放器)(需要启用ANSI的控制台:
#! /usr/bin/python3
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
getch = _GetchUnix ()
house = ''' _ . ^ . _
/____.____\\
| |
| ## _ ## |
|_""_H_""_|'''
class Screen:
def __init__ (self, width, height, background):
self.width = width
self.height = height
self.bg = '\x1b[{}m'.format (40 + background)
self.clear = '\x1b[0m'
self.objects = []
def __iadd__ (self, obj):
self.objects.append (obj)
obj.screen = self
return self
def render (self):
print ('\x1b[1;1H', end = '')
for y in range (self.height):
for x in range (self.width):
print (self.bg + ' ' + self.clear, end = '')
print ()
for obj in self.objects: obj.render ()
print ('\x1b[{};1H'.format (self.height) )
class Object:
def __init__ (self, graphics, foreground, background, x, y):
self.graphics = graphics.split ('\n')
self.fg = '\x1b[{}m'.format (30 + foreground)
self.bg = '\x1b[{}m'.format (40 + background)
self.clear = '\x1b[0m'
self.x = x
self.y = y
def render (self):
for y, line in enumerate (self.graphics):
print ('\x1b[{};{}H'.format (self.y + y, self.x), end = '')
print (self.fg + self.bg + line + self.clear)
def collide (self, x, y):
if y < self.y: return False
if x < self.x: return False
if y > self.y + len (self.graphics) - 1: return False
if x > self.x + len (self.graphics [y - self.y] ): return False
return True
def move (self, dx, dy):
nx, ny = self.x + dx, self.y + dy
if ny < 1: return
if ny > self.screen.height: return
if nx < 1: return
if nx > self.screen.width: return
for obj in self.screen.objects:
if obj == self: continue
if obj.collide (nx, ny): return
self.x, self.y = nx, ny
house = Object (house, 0, 7, 6, 3)
player = Object ('@', 1, 3, 10, 10)
s = Screen (40, 20, 3)
s += house
s += player
while True:
c = getch ()
if c == 'x': break
if c == 'w': player.move (0, -1)
if c == 's': player.move (0, 1)
if c == 'a': player.move (-1, 0)
if c == 'd': player.move (1, 0)
s.render ()这里是一个屏幕截图:

https://stackoverflow.com/questions/20864620
复制相似问题