Roguelike大全,使用python+libtcod:1

原文地址:Complete Roguelike Tutorial, using python+libtcod, part 1
原文目录:Complete Roguelike Tutorial, using python+libtcod
随手翻的,纯粹是笔记,如果有英语比我还差又想入门roguelike游戏开发的可以随便看看(虽然我建议你还是看原文免得被我误导)
处女座请绕道,英语好的请自行看原文反正我也放旁边了

图像

设置 我们开始动手吧!

Windows操作系统下 Python的安装 (懒得翻)需要注意很多源码是32位环境下写的,最好下载相应的32位python(即使你在64位操作系统下)

libtcod的安装,如果像我一样用pycharm可以略过,反正直接在pycharm里装比较方便 pycharm如何安装libtcod可自行百度

检查libtcod是否工作,基本上不会遇到啥问题(略)

如何设置文件夹环境,反正我是基于https://github.com/fengshuitm/Python-Roguelike-Framework进行开发的,也不用管这些了,强烈建议没必要自己折腾这些,万一遇到问题再说呗

import libtcodpy as libtcod 

在屏幕上显示@

要载入libcodpy这个库

设置屏幕的宽、高、刷新率,请设置成宏

SCREEN_WIDTH = 80 SCREEN_HEIGHT = 50 LIMIT_FPS = 20

现在我们来设置自定义字体!(原作者你激动个啥。。。)这很简单。libtcod带了一堆我们可以用的字体,但是请记住它们有不同的"格式",而你需要对其进行专门说明,比如一个"graysacle","tcod layout"的字体, 就有一个_gs_tc的结尾。如果你想要用一个有其它布局的字体来彰显你的与众不同,可以参考文档(链接在“ docs on the subject ”),不过建议还是以后在折腾这些吧,注意字体的大小是自动检测的

libtcod.console_set_custom_font('arial10x10.png', 
libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

这也许是最重要的一段声明,用以初始化窗口,我们设置了窗口的大小,题头(如果你乐意的话现在就可以把它改了),而最后一个参数描述了是否全屏

 libtcod.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'python/libtcod tutorial', False)

对于一个即时制roguelike,你必须要限制游戏的速度(也就是每秒帧数或者是FPS),如果你做的是回合制,忘了这句话吧,这句话在回合制游戏里没毛用

 libtcod.sys_set_fps(LIMIT_FPS)

现在是主循环,它让你的程序不断的执行直到窗口被关闭

 while not 
libtcod.console_is_window_closed():

对于每一个迭代,我们想在屏幕上打印些东西。如果你的游戏是回合制的,任何一个指令就是一个回合;如果是即时制,任何一个迭代就是一帧。这里我们将字体颜色 设置为白色,如果你想设置成别的颜色可以根据上面的链接找到相应的颜色列表,以及如何混着用它们的知识。0表征了我们将在0号控制台打印这些文字,这事儿我们以后再细说

libtcod.console_set_default_foreground(0, libtcod.white)

别忘了缩进,这对于python很重要(废话。。。),一定不要把tabs和空格混着用!这种事情在你从网上拷贝别人的代码时经常会遇到,而那时你将会看到跟缩进(indentation)有关的error(那就是线索了)。请务必只使用四个空格 或者直接使用tab,我们的例子里将使用前者,但是tabs在很多编辑器里也挺好用的所以它也是一个好的选择。 现在我们在坐标(1,1)打印一个字符,再一次的,第一个0区分了不同的控制台,也就是这个例子里的屏幕。猜猜看是哪个字符?对!就是@!(。。。有点无力吐槽的感觉)

  libtcod.console_put_char(0, 1, 1, '@', libtcod.BKGND_NONE)

在主循环的最后你需要重新刷新屏幕,这被叫做flushing the console,下面的代码就是干这个的

 libtcod.console_flush()

塔达!你已经完成了。跑一跑这段代码并且给自己一点鼓励吧!

下面是一些会导致跑不通的常见错误 1.你是不是用的python3? 2.在windows环境下,蹦出"Incompatible architecture" 错误,请确保python和libtcod都是32位或者都是64位 3.还是在windows环境下(windows真是事儿多),蹦出"The specified module could not be found" 错误,说明libtcod这个模块没有正确加载,请回头去确认一下正确安装了这个模块 3.还是跑不通?查查看下面的这个问题链接吧(链接在上面的英文里) 可能你注意到了,我们的代码没有任何给人输入的地方,游戏也会在你点击“esc”键之后崩溃,不用担心,马上我们就加上键盘响应的支持 你可以在链接里看到全部的代码

让你的小人到处转转吧 很简单不是么?现在我们来让小人@跟随按键去运动! 首先我们需要一个变量来表征玩家的坐标位置。我们用如下的变量,并用屏幕中心对其进行初始化(记住要在主循环之前哦)

 playerx = SCREEN_WIDTH/2 playery = SCREEN_HEIGHT/2 

下面的函数用以检测按键的按下。当一个按钮被按下,根据上下左右改变玩家的位置

 def handle_keys():    
  global playerx, playery        #movement keys 
if libtcod.console_is_key_pressed(libtcod.KEY_UP):    
      playery -= 1  elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN):  
        playery += 1  elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT):      
    playerx -= 1  elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT):   
       playerx += 1 

完成了!这些是十字键,如果你想要使用其他的按键,这里有一个参考列表(然鹅这个链接需要翻墙。。。蛋疼) 接着我们又加入了让程序全屏的enter键和退出游戏的esc键

从现在开始,我们要分开展示即时制游戏和回合制游戏的代码 console_is_key_pressed 函数在即时游戏里是有用的,因为它检测到按键无延迟的按下。console_check_for_keypress则适合回合制游戏,对待按键就像打字一样。因此在第一次点击,它将会短暂的停止一会儿。 这就跟你打字时看到的反应一样。要不然你按下一个键就会导致程序认为你把这个键被重复按了3到4次!这对于除了移动之外的所有命令都很有用,因为移动这个功能很多人总是希望按着不动就会一直响应

现在划重点了:你可以用第一行代码来区分实时游戏和回合游戏!注意,console_check_for_keypress不会阻塞你的游戏,但是如果你把它换成下面这现在,主循环需要运行下列函数来使其开始工作。如果返回True,则我们从主循环中“跳出”,结束游戏。我们的主循环内部将如下所示:

libtcod.console_set_default_foreground(0, libtcod.white) 
    libtcod.console_put_char(0, playerx, playery, '@', libtcod.BKGND_NONE)   
    libtcod.console_flush()       #handle keys and exit game if needed 
    exit = handle_keys()   
  if exit:   
      break

为什么我们要把绘制放在处理按键输入之前呢,如果不这样做,在一个回合制游戏里,第一次刷新屏幕将在第一次之后,这样程序启动后将一片空白让玩家迷茫不已 还有一个原因,那就是我们会看到@在移动时后面还残留着一个@。那可不是我们想要的!我们想要先在上一个位置清除@然后再绘制新的,我们用在上一个位置上输入一个空格来实现这个功能。 我们把条代码放在 exit = handle_keys().之前(有点无力吐槽这样的刷新手段。。。也太复古了吧) 我们可以通过链接看到完整的代码 未知后事如何,且听下文分解


Graphics

Setting it up
Ok, now that we got that out of our way let's get our hands dirty!
Windows
Python
If you haven't already done so, download and install Python 2.7. Any version of Python 2, from 2.6 and above should be fine, but the latest update (of Python 2, not Python 3) is of course always preferable.
There are reports that for older versions of libtcod on 64-bit Windows (Windows 7) that the 32 bit version is preferable, since the 64 bit version of Python seems to cause problems with libtcod. This was been tested on Windows 10 with libtcod 1.6, and was not reproducible, so it's up to you.
It might be advisable to go with 32 bit just to keep things simple, and when you're gone through the tutorial look at switching to 64 bit if it matters to you to do so, and if you do encounter errors specifically related to this, report them on the libtcod bug tracker.
libtcod
Download the latest release of libtcod 1.6 and extract it somewhere. Be warned that both Python and libtcod must either be both 32 bit, or both 64 bit. If you get dll loading errors, getting this wrong is the most likely cause. libtcod will now (as of 1.6.2 and above) check they are compatible, and tell you if they are not.


Check if libtcod works
libtcod is compiled with the latest official release of Visual Studio. In an ideal world, it should just run, and if you have recently updated games installed from Steam or perhaps even some modern applications, it should. However, some people lack the support for that latest release of Visual Studio, and these steps help update your computer to allow libtcod to be run.
Within the libtcod release you just extracted, you will see a file called samples.exe.
Run samples.exe and verify that it appears to work. If it opens a colourful window, then it is now verified as working for you.
If it just doesn't start and instead you see a message about vcruntime140.dll being required, then you need to install the correct Visual Studio 2015 runtime.
Go to the latest Microsoft Visual Studio 2015 runtime download page, and download and install the runtime that matches the Python and libtcod you are using. If you are using 32 bit Python and libtcod, this will be the x86 runtime. If you are using the 64 bit Python and libtcod, this will be the x64 runtime. (Tip: If you think you might switch from 32 bit to 64 bit in the future, hedge your bets and install both runtimes to prevent future problems.)
Once you've installed the correct runtime, run samples.exe and verify that it now appears to work. If it still gives the same message, you didn't install the correct runtime. If it opens a colourful window, then it is now verified as working for you.
If it is not verified as working for you, you can open a libtcod bug report on BitBucket.
You've verified that libtcod is working? Great! You can move onto the next section.

Your project folder
Now create your project's folder. Inside it, create an empty file with a name of your choice. We're using firstrl.py. It'll make the tutorial easier to just use the same name, and you can always rename it later.
 


From within the libtcod build you downloaded above, select and copy the relevant DLLs.
 


From within the libtcod build you downloaded above, select and copy the libtcodpyfolder.
 


From within the libtcod build you downloaded above, select and copy the arial10x10.pngfont. If you choose a different one, you'll need to adjust how you do the tutorial accordingly. It's simpler to just use the same one as we do, and change it later, if it suits you to do so.
 


At this point, you should have a folder that looks like this:
 


You're ready to start editing firstrl.py!
Autotools platforms (Linux, MacOS, ...)
Python
The tutorial is written for Python 2, so ensure you have it installed and know what it is called.
SDL2
If your OS or OS distribution has a package that can be used for SDL2 development, then the best option is to install it. This will ensure that you can easily update it.
In the event that you cannot find a package, you can compile it yourself as a last resort. To do so, download the supported SDL2 revision, build and install it:
$ curl -o sdl.tar.gz http://http://hg.libsdl.org/SDL/archive/007dfe83abf8.tar.gz $ tar -xf sdl.tar.gz $ cd SDL-007dfe83abf8/ $ mkdir -p build $ cd build $ ../configure $ make $ sudomakeinstall
This will place the libraries at `/usr/local/lib/` and the development headers at `/usr/local/include/SDL2/`.
libtcod
Download the latest libtcod release and compile it:
wget https://http://bitbucket.org/libtcod/libtcod/downloads/20161228-libtcod-1.6.2.tbz2 $ tar xf 20161228-libtcod-1.6.2.tbz2 $ cd 20161228-libtcod-1.6.2 $ cd build/autotools/ $ autoreconf -i $ ./configure $ make $ cd ../..
Now you should be in the root libtcod directory. You can see the compiled library like:
find . -name "libtcod.so" ./build/autotools/.libs/libtcod.so
However, notice this .so is actually a link to this other .so.0.0.0 file in the same directory:
readlink ./build/autotools/.libs/libtcod.so libtcod.so.0.0.0
Your project folder
Now you're ready to make a directory for your new project, copy the compiled library and links, plus the python library and a font into it:
mkdir -p ~/tutorial $ cp -dr build/autotools/.libs/libtcod.so* python/libtcodpy data/fonts/arial10x10.png ~/tutorial/ $ cd ~/tutorial
You should be able to see something similar to this:
ls -lgo total 1388 -rw-rw-r-- 1 14870 Dec 31 15:57 arial10x10.png drwxrwxr-x 2 4096 Dec 31 15:57 libtcodpy lrwxrwxrwx 1 16 Dec 31 15:57 libtcod.so -> libtcod.so.0.0.0 lrwxrwxrwx 1 16 Dec 31 15:57 libtcod.so.0 -> libtcod.so.0.0.0 -rwxrwxr-x 1 1413856 Dec 31 15:57 libtcod.so.0.0.0
Now you're ready to start.
Choice of code editor
If you're just starting out with Python, you'll find that many Python coders just use a simple editor and run their scripts from a console to see any debugging output. Most Python coders don't feel the need to use a fancy IDE! On Windows, Notepad++ is an excellent bet; most Linux programmers already have an editor of choice. Almost all editors allow you to configure shortcut keys (like F5 for instance) to quickly run the script you're editing, without having to switch to a console.
See this page if you want to set up a Notepad++ shortcut with a couple of nice features for debugging, or if you tried to roll your own and hit the infamous "module not found" error.
Another quick note, if you're using IDLE. It doesn't seem to let libtcod clean up properly on exit, so it crashes when you end a script. This seems to be more of an IDLE problem than a libtcod problem so there's no fix in sight, for now. Using any of the setups recommended above will work just fine.

Showing the @ on screen
This first part will be a bit of a crash-course. The reason is that you need a few lines of boilerplate code that will initialize and handle the basics of a libtcod window. And though there are many options, we won't explain them all or this part will really start to drag out. Fortunately the code involved is not as much as in many other libraries!
First we import the library. The name libtcodpy is a bit funky (sorry Jice!) so we'll rename it to just libtcod.


import libtcodpy as libtcod


Then, a couple of important values. It's good practice to define special numbers that might get reused. Many people capitalize them to distinguish from variables that may change.
SCREEN_WIDTH = 80 SCREEN_HEIGHT = 50 LIMIT_FPS = 20



Now, something libtcod-specific: we're going to use a custom font! It's pretty easy. libtcod comes bundled with a few fonts that are usable right out of the box. Remember however that they can be in different formats, and you'll need to tell it about this. This one is "grayscale" and using the "tcod layout", most fonts are in this format and thus end with _gs_tc. If you wanna use a font with a different layout or make your own, the docs on the subject are really informative. You can worry about that at a later time though. Notice that the size of a font is automatically detected.


This is probably the most important call, initializing the window. We're specifying its size, the title (change it now if you want to), and the last parameter tells it if it should be fullscreen or not.


For a real-time roguelike, you wanna limit the speed of the game (frames-per-second or FPS). If you want it to be turn-based, ignore this line. (This line will simply have no effect if your game is turn-based.)
libtcod.sys_set_fps(LIMIT_FPS)



Now the main loop. It will keep running the logic of your game as long as the window is not closed.

while not libtcod.console_is_window_closed():


For each iteration we'll want to print something useful to the window. If your game is turn-based each iteration is a turn; if it's real-time, each one is a frame. Here we're setting the text color to be white. There's a good list of colors you can use here, along with some info about mixing them and all that. The zero is the console we're printing to, in this case the screen; more on that later.

libtcod.console_set_default_foreground(0, libtcod.white)


Don't forget the indentation at the beginning of the line, it's extra-important in Python. Make sure you don't mix tabs with spaces for indentation! This comes up often if you copy-and-paste code from the net, and you'll see an error telling you something about the indentation (that's a pretty big clue right there!). Choose one option and stick with it. In this tutorial we're using the 4-spaces convention, but tabs are easy to work with in many editors so they're a valid choice too.
Now print a character to the coordinates (1,1). Once more the first zero specifies the console, which is the screen in this case. Can you guess what that character is? No, it doesn't move yet!

libtcod.console_put_char(0, 1, 1, '@', libtcod.BKGND_NONE)


At the end of the main loop you'll always need to present the changes to the screen. This is called flushing the console and is done with the following line.

libtcod.console_flush()


Ta-da! You're done. Run that code and give yourself a pat on the back!

Common reasons the code won't run.

  • Python errors? Using Python 3?
    We said above that this tutorial is only for Python 2. So use Python 2, with Python 3 you are on your own. They're different languages, it won't just magically work!
  • On Windows? Getting the "Incompatible architecture" error?
    Make sure your Python and libtcod are either BOTH 32 bit, or BOTH 64 bit.
  • On Windows? Getting the "The specified module could not be found" error?
    You didn't verify that libtcod was working. Goback and do it
  • Still blocked for other reasons? Check out the problems page.

Note that since we don't have any input handling code, the game may crash on exit (it won't process the OS's requests to close). Oops! Don't worry though, this problem will go away as soon as we add keyboard support.
Here's the complete code so far.


Moving around
That was pretty neat, huh? Now we're going to move around that @ with the keys!
First, we need to keep track of the player's position. We'll use these variables for that, and take the opportunity to initialize them to the center of the screen instead of the top-left corner. This can go just before the main loop.
playerx = SCREEN_WIDTH/2 playery = SCREEN_HEIGHT/2


There are functions to check for pressed keys. When that happens, just change the coordinates accordingly. Then, print the @ at those coordinates. We'll make a separate function to handle the keys.

def handle_keys(): global playerx, playery #movement keysiflibtcod.console_is_key_pressed(libtcod.KEY_UP): playery -= 1 eliflibtcod.console_is_key_pressed(libtcod.KEY_DOWN): playery += 1 eliflibtcod.console_is_key_pressed(libtcod.KEY_LEFT): playerx -= 1 eliflibtcod.console_is_key_pressed(libtcod.KEY_RIGHT): playerx += 1

Done! These are the arrow keys, if you want to use other keys here's a reference (pay attention to the Python-specific notes).
While we're at it, why not include keys to toggle fullscreen mode, and exit the game? You can put this at the beginning of the function.

key = libtcod.console_check_for_keypress() if key.vk == libtcod.KEY_ENTER andkey.lalt:#Alt+Enter: toggle fullscreenlibtcod.console_set_fullscreen(notlibtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game


From now on, we'll show code for a real-time game with a green background, and code for a turn-based game with a blue background.
Notice a subtle difference here. The console_is_key_pressed function is useful for real-time games, since it checks if a key is pressed with no delays. console_check_for_keypress, on the other hand, treats the key like it's being typed. So after the first press, it will stop working for a fraction of a second. This is the same behavior you see when you type, otherwise pressing a key would result in you typing 3 or 4 letters! It's useful for all commands except movement, which you usually want to react as soon as possible with no delays, and continue for as long as you press the movement keys.
Now here's an important thing: you can use that first line to distinguish between real-time and turn-based gameplay! See, console_check_for_keypress won't block the game. But if you replace it with this line:
key = libtcod.console_wait_for_keypress(True)

Then the game won't go on unless the player presses a key. So effectively you have a turn-based game now.


The reason why we draw stuff before handling key input is that, in a turn-based game, the first screen is shown before the first key is pressed (otherwise the first screen would be blank).
One more thing! If you try that, you'll see that moving you leave around a trail of little @'s. That's not what we want! We need to clear the character at the last position before moving to the new one, this can be done by simply printing a space there. Put this just before exit = handle_keys().

libtcod.console_put_char(0, playerx, playery, ' ', libtcod.BKGND_NONE)

Here's a rundown of the whole code so far.
Go on to the next part.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值