PICO-8学习日志Week1.2

1.3 认识PICO-8代码

        在上一篇里面我花了较大的篇幅来介绍了PICO-8,在我们熟悉了各类操作之后,就可以上手来制作自己的第一个游戏了。在那之前,让我们来认识一下PICO-8的Game Loop:

PICO-8 uses three specially-named functions to create what's called a game loop. The _init() function happens one time, then _update() and _draw() happen in a loop until your game ends. Here's the basic structure of the PICO-8 game loop and what each functions does:

 

        上面是Dylan在文章中对Game Loop的介绍,其实说的直白一点,就是PICO-8代码运行的流程:PICO-8为制作者定义了三个函数: _init(), _update(), _draw(),在游戏启动后,_init()内的代码首先运行,并且只运行一次,然后就是_update()和_draw()的交替循环运行,一个循环内,_update()内的代码首先执行,然后是_draw()内的代码,这是一个循环,然后就是下一个循环,_update()执行,_draw()执行……这样的循环在一秒内会发生30次,从而使游戏画面能实现变化。

        除了这三个函数,我们还可以定义其他的函数,基本格式:

        function 函数名()

        end

        现在我们就可以试着制作出一个小“游戏”:

function _init()
 make_player()
end

function _update()
 move_player()
end

function _draw()
 cls() --clear screen
 draw_player()
end

function make_player()
 px=64
 py=64
 psprite=1
end

function move_player()
 if (btn(0)) px-=1 --left
 if (btn(1)) px+=1 --right
 if (btn(2)) py-=1 --up
 if (btn(3)) py+=1 --down
end

function draw_player()
 spr(psprite,px,py)
end

       

        将这段代码复制到代码区,然后别忘了绘制你的小精灵:

 

        按下Ctrl+R运行,这个时候按下↑↓←→,我们的小精灵就可以实现自由移动了。

        现在我们回过头来分析一下代码:除了刚才提到的三个基本函数,这段代码里面害定义了三个函数,分别是make_player(), move_player(), draw_player():

function make_player()
 px=64
 py=64
 psprite=1
end

        首先是make_player(),这个函数实际上只给定了三个参数,后面的draw_player()才会用到这三个参数:

function draw_player()
 spr(psprite,px,py)
end

        这里的spr()就是绘制精灵的函数,它需要三个参数,分别是精灵编号、X轴坐标,Y轴坐标,在draw_player()里面,三个参数全部是make_player()里面定义好的,所以在这里面可以直接用。

        游戏运行之后地图是一个128*128的正方形,左上角为原点,沿直线往右X坐标递增,沿直线往下Y坐标递增,所以(64, 64)这个坐标正好是屏幕的正中心,这也是为什么刚才我们运行游戏之后,精灵出现在了屏幕的正中心,如果我们修改一下px和py的值,比如改成(0, 0),精灵就会生成在屏幕的左上角。

        值得一提的是,真正的地图尺寸并不是128*128, 我试着给了px和py很大的值9999999999,编辑器没有报错,游戏正常运行,我也给了速度一个很大的值,在经过漫长的跋涉之后,我的小精灵出现在了目前的屏幕中(因为速度太快实际上只是一闪而过),这也从侧面说明,实际的地图大小有可能是不设上限的。

        坐标值同样也可以是负值,小精灵也会出现在对应的位置。如何拖动摄像机,显示出更多的地图,这就是我们后面需要探究的问题了。

        至于精灵的编号,这个就是在绘制界面可以看见的东西:

        

        要让精灵动起来,我们还需要第三个函数:

function move_player()
 if (btn(0)) px-=1 --left
 if (btn(1)) px+=1 --right
 if (btn(2)) py-=1 --up
 if (btn(3)) py+=1 --down
end

         这里就是很简单的通过if()函数来实现X、Y坐标的增加从而让精灵“运动起来”,btn()是对按键输入的监视器,下面是按键与编号的对应关系:

        

        在我们的PC上,从0到5对应的就是“←”、“→”、“↑”、“↓”、“Z”、"X"。

        在前文提过,Game Loop每秒发生30次,这里的move_player()最后也是要放到Game Loop中的,所以当我们连续按着某一个按键时,一秒内可以读入30次,对应的按键事件也会发生30次。反映在这段代码中就是小精灵会以30pix/s的速度在地图上运动。

        另外一提,每秒钟30次的刷新也就是我们通常所说的30帧,如果我们设置一个稍微大一点的速度,精灵的运动看起来就不那么连续了。

        现在,我们再回过头来看这段代码在三个基本函数里干了些什么:

function _init()
 make_player()
end

function _update()
 move_player()
end

function _draw()
 cls() --clear screen
 draw_player()
end

         首先是_init(),里面是make_player(),这样在一开始编译器就知道了三个参数的值;然后在_update()里面是move_player(),这样在我们按下按钮之后坐标值就可以及时更新;在_draw()里面除了draw_player()还有一个cls()函数——这个函数用来清屏,同样也是必不可少的,我们可以试试去掉cls()之后运行游戏:

         

        这样的结果说明在没有cls()指令的情况下,上一个循环所绘制的图形在下个循环依旧存在。

        在了解了每一个代码块的作用后,我们就可以知道这个“游戏”的运作逻辑了:首先是_init()里面设定了三个初始值,然后进入Game Loop,_update()函数读取按键并且修改坐标值,_draw()函数清除上一个循环的画面,然后在新的坐标绘制精灵……循环一直进行,直到我们退出游戏。

        这里思考一个小问题:_update()函数和_draw()函数里面的代码是否可以调换?

        从名字里面来看好像是不行的,update在编程里面一般是更新的意思,在这里就是数值更新;draw就是绘制的意思,在这个代码里面他们做了各自想做的事,并且配合默契;另外我们开头就说过_update()和_draw()有先后关系,_update()先于_draw()执行,这样一来关于这个问题的答案好像已经确定是不行了,因为没有_update()更新数值_draw()不太可能在正确的地方绘制出新的精灵。

        然而真的是这样吗?如果我们实际操作一下就会发现,游戏和之前一模一样。

        这就说明了两个事情:首先,编辑器并没有给_update()和_draw()划定特定的功能,只是让他们先后循环运行,更新数值的工作可以让_draw()来做,同样,绘图的工作也可以交给_update(),注意我之前是说“他们想做的事”,而不是“他们应该做的事”。执行的先后问题在不断的循环过程中好像也没有太大的意义,在上个循环中更新的数值传递给下个循环,下个循环利用上个循环的数据作图,然后更新数值,在传入下下个循环……工作模式是基本上没有变化的。就好比你和你的朋友在围着柱子绕圈,他也可以是在你的前面,也可以是在你的后面。

        不过为了代码的可读性,我们还是应该老老实实的让它们做各自想做的事。

        这一篇我用了3k多字介绍了Dylan书中两页的内容,大概讲清楚了PICO-8代码运作的一些基础的东西,并且制作了一个并不是游戏的游戏。

        下一篇我们还会跟随Dylan的脚步,来制作第一个真正的游戏。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PICO-8中,地图可以使用`tmap()`或`map()`函数来绘制。这两个函数都可以用于在屏幕上显示地图,但它们的用法略有不同。 `tmap()`函数可以使用任何颜色为地图定义一个tileset(瓷砖集合),然后使用这些瓷砖绘制地图。这使得您可以使用多个不同的颜色来创建一系列不同的瓷砖,并将它们组合成地图。 `map()`函数则使用单个颜色定义地图,其中每个像素都表示地图上的一个单元格。这使得创建地图变得非常简单和直观。 下面是一个使用`map()`函数绘制地图的示例代码。假设我们有一个32x32的地图,每个单元格大小为8x8像素: ``` --定义地图数据 local map_data = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, } --绘制地图 function _draw() map(0, 0, 0, 0, 32, 32, map_data) end ``` 在这个例子中,我们首先定义了一个包含地图数据的表`map_data`,其中1表示墙,0表示地面。然后我们在`_draw()`函数中使用`map()`函数绘制地图。 `map()`函数的第一个参数是地图左上角的x坐标,第二个参数是地图左上角的y坐标。第三个参数是地图中每个单元格的宽度,第四个参数是每个单元格的高度。第五个参数是地图的宽度,第六个参数是地图的高度。最后一个参数是包含地图数据的表。 希望这个示例可以帮助您了解如何在PICO-8中绘制地图!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值