上一篇 python3+libtcod学习(一) 安装环境与绘制符号
移动符号
创建一个名为input_handlers.py的文件,这段代码实现了一些简单的键盘输入功能。
import tcod as libtcod
# 0.定义了一个名为的函数handle_keys,它接受一个参数key,这个参数来源于键盘输入
def handle_keys(key):
# 1.以下的条件语句都是判断摁下了哪个键,依次是上、下、左、右、回车加Alt、Esc
# 其中回车加Alt的作用是切换全屏和窗口显示,Esc为关闭屏幕。
if key.vk == libtcod.KEY_UP:
return {'move': (0, -1)}
elif key.vk == libtcod.KEY_DOWN:
return {'move': (0, 1)}
elif key.vk == libtcod.KEY_LEFT:
return {'move': (-1, 0)}
elif key.vk == libtcod.KEY_RIGHT:
return {'move': (1, 0)}
if key.vk == libtcod.KEY_ENTER and key.lalt:
return {'fullscreen': True}
elif key.vk == libtcod.KEY_ESCAPE:
return {'exit': True}
# 2.如果没有键盘输入返回空字典。
return {}
接下来修改在教程一中engine.py的代码,只在有修改的地方写注释:
import tcod as libtcod
from input_handlers import handle_keys
def main():
screen_width = 80
screen_height = 50
# 0.设置符号坐标,在下面的代码中这两个值根据键盘输入而改变
player_x = int(screen_width / 2)
player_y = int(screen_height / 2)
libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False)
# 1.保存键盘和鼠标输入
key = libtcod.Key()
mouse = libtcod.Mouse()
while not libtcod.console_is_window_closed():
# 2.捕获用户输入,更新key和mouse
libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)
libtcod.console_set_default_foreground(0, libtcod.white)
# 3.将注释0中的坐标作为参数传入
libtcod.console_put_char(0, player_x, player_y, '@', libtcod.BKGND_NONE)
libtcod.console_flush()
# 4.将键盘参数传入按键处理函数,得到的返回值都是字典,根据返回值得不同进行不同的处理
action = handle_keys(key)
move = action.get('move')
exit = action.get('exit')
fullscreen = action.get('fullscreen')
if move:
dx, dy = move
player_x += dx
player_y += dy
if exit:
return True
if fullscreen:
libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
if __name__ == '__main__':
main()
运行代码后,按下上下左右键实现简单的符号移动。但是此时还有一个问题,这段代码只能生成却无法删除符号,这样的现象就是摁下移动键,屏幕中生成的是一串符号‘@’的移动轨迹,而我们想要的效果是只留下最新生成的‘@’,处于原本位置上的‘@’应该被删除。
所以在显示屏幕上设置的内容后加入以下一行代码:
...
libtcod.console_flush() #在这一行后加入
libtcod.console_put_char(con, player_x, player_y, ' ', libtcod.BKGND_NONE)
...
这样的效果就是生成‘@’然后再删除,由于屏幕处于循环中不停地生成新的‘@’,所以屏幕上有且只有一个‘@’出现。
生成新的控制台
观察以下代码
libtcod.console_set_default_foreground(0, libtcod.white)
libtcod.console_put_char(0, player_x, player_y, '@', libtcod.BKGND_NONE)
这两个函数中的第一个参数‘0’在教程一中解释到是“控制台”的意思,这里的0就是系统默认的控制台,在游戏制作的过程中往往需要生成更多的控制台,比如说不希望绘制的东西被用户看到,所以将engine.py的代码修改如下:
...
libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False)
# 0.生成新的控制台,以下绘制的东西都放在这个控制台上
con = libtcod.console_new(screen_width, screen_height)
key = libtcod.Key()
mouse = libtcod.Mouse()
while not libtcod.console_is_window_closed():
libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)
# 1.修改参数,将默认的0改为我们自己生成的控制台
libtcod.console_set_default_foreground(con, libtcod.white)
libtcod.console_put_char(con, player_x, player_y, '@', libtcod.BKGND_NONE)
libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0)
libtcod.console_flush()
libtcod.console_put_char(con, player_x, player_y, ' ', libtcod.BKGND_NONE)
...
在这个过程中有一个函数 libtcod.console_blit( ),它的参数含义分别是控制台1、控制台1的原点坐标x、y、屏幕的宽、高、控制台2、控制台2的原点坐标x、y,另外还有两个缺省参数可以用来设置透明度,它的作用是按照原教程的翻译来看是说“允许您在目标控制台上的特定位置对源控制台的矩形区域进行位块传输”,在这里它的效果看上去就是把‘con’控制台上的内容复制到默认‘0’控制台上面,缺少这句话屏幕上将什么都不显示。