制作一款打飞机游戏教程4:角色移动

首先,让我们回顾一下目前的进展。我们的初始原型计划是这样的:我们完成了性能优化,确定了子弹的数量(大约500颗),以及这些背景元素对性能的影响(大约占用了25%的预算)。我们还完成了评分原型的制作,现在可以制作理论上无限长的关卡,尽管实际制作时关卡可能会变得相当重复。我们确定了一个良好的关卡目标长度是6分钟,并且已经开发了实现这一目标的技术。

接下来的任务

接下来,我们需要创建一个紧凑的瓦片集,并计划制作第五个原型,即结合滚动和移动原型的关卡。但今天,我们的主要任务是制作第三个原型:确保基本的移动和射击感觉良好。

实现基本移动

为了实现这一目标,我们首先创建了一个新的文件,并定义了几个基本的函数:updatedrawfunction。然后,我设置了一个飞船精灵,并创建了两个变量pxpy来控制飞船的位置。接下来,我使用键盘按键来控制飞船的移动,并设置了一个速度变量spd来调整飞船的移动速度。

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- t: make basic movement feel nice
-- t: normalized diagonals
-- t: make shooting feel nice!


-- 0 - stop
-- 1 - left
-- 2 - right
--3  - l+r = stop
-- 4 - up
-- 5  - diag l/u
-- 6  - diag r/u
--7  - l+u+r = u
-- 8 - down
-- 9  - diag l/d
-- 10 - diag r/d
--11 - l+d+r = d
--12 - u+d = stop
--13 - l+u+d = l
--14 - r+u+d = r

-----
-- 1 - ⬅️
-- 2 - ➡️
-- 3 - ⬆️
-- 4 - ⬇️

-- 5 - ⬅️⬆️
-- 6 - ⬆️➡️
-- 7 - ➡️⬇️
-- 8 - ⬅️⬇️

butarr={1,2,0,3,5,6,3,4,8,7,4,0,1,2,0}

dirx={-1,1, 0,0, -1, 1,1,-1 }
diry={ 0,0,-1,1, -1,-1,1,1 }

butarr[0]=0

function _init()
 px,py=64,64
 spd=0.3
 cls(0)
end

function _draw()
 cls(12)
 --spr(5,px,py,2,2)
 pset(px,py,8)
 
 local btnv=btn()&0b1111
 print(btn(),5,5,7)
 print(btnv,5,11,7)
 print(butarr[btnv],5,17,7)
 
 if butarr[btnv]>=5 then
  print("diaginal",5,23,7)
 end
end

function _update60()
 local dir=butarr[btn()&0b1111]
 if dir>0 then
  px+=dirx[dir]*spd
  py+=diry[dir]*spd
 end
 
end
__gfx__
00000000000000011000000000000001100000000000000110000000000000011000000000000001100000000000000000000000000000000000000000000000
00000000000000167100000000000016710000000000001661000000000000167100000000000016710000000000000000000000000000000000000000000000
00700700000000111d100000000000111d1000000000011111100000000001d111000000000001d1110000000000000000000000000000000000000000000000
00077000000001ccc1100000000001ccc1100000000001cccc1000000000011ccc1000000000011ccc1000000000000000000000000000000000000000000000
0007700000001c77cc11000000001c77cc11000000001c77ccc10000000011c77cc10000000011c77cc100000000000000000000000000000000000000000000
0070070000001c7c1c11000000001c7c1c11000000001c7cc1c10000000011c7c1c10000000011c7c1c100000000000000000000000000000000000000000000
0000000000001c111c11100000011c111c11100000111c1111c11100000111c111c11000000111c111c100000000000000000000000000000000000000000000
0000000000001c111c17100000011c111c17100000171c1111c17100000171c111c11000000171c111c100000000000000000000000000000000000000000000
0000000000011cc17116100000161cc1171610000016117117116100000161711cc16100000161171cc110000000000000000000000000000000000000000000
000000000001d1c711d6d1000016d1c77116d10001d6d117711d6d10001d61177c1d6100001d6d117c1d10000000000000000000000000000000000000000000
00000000001ddd111d6d7d1001dddd1111dd6710176d6d1111d6d6710176dd1111dddd1001d7d6d111ddd1000000000000000000000000000000000000000000
00000000001dd6ddd6d66d1001dd66dddd6d66101666d6dddd6d66610166d6dddd66dd1001d66d6ddd6dd1000000000000000000000000000000000000000000
00000000001d676676d6dd1001d6676676d6dd101dd6d676676d6dd101dd6d6766766d1001dd6d676676d1000000000000000000000000000000000000000000
00000000000176d167d1110000117dd1171111000111171661711110001111711dd7110000111d761d6710000000000000000000000000000000000000000000
000000000000151155d110000001655155d11000000161511516100000011d551556100000011d55115100000000000000000000000000000000000000000000
00000000000001111111000000001111111100000000111111110000000011111111000000001111111000000000000000000000000000000000000000000000
遇到的问题:对角线移动时的“鹅卵石”现象

在测试过程中,我发现当飞船以较慢的速度沿对角线移动时,会出现一种不连贯的、类似“鹅卵石”的视觉效果。这是因为PICO-8的分辨率较低,像素较大,当飞船不处于像素中心时,沿对角线移动会触及多个像素,导致移动路径看起来不连贯。

解决方案:重写控制系统

为了解决这个问题,我决定重写控制系统。首先,我使用btn()函数来获取按键的数值,并通过二进制运算剥离出与方向键相关的部分。然后,我创建了一个映射表(buttR),将按键数值转换为自定义的方向编号。接着,我创建了两个数组(drxdry),用于存储不同方向下xy坐标的变化量。

通过这些改动,我现在可以轻松地识别飞船是否在对角线方向上移动。

解决方案
  • 重写控制系统‌:
    • 使用btn()函数获取按键数值,并通过二进制运算剥离出与方向键相关的部分。
    • 创建映射表(buttR)将按键数值转换为自定义的方向编号。
    • 创建数组(drxdry)存储不同方向下xy坐标的变化量。
  • 解决“鹅卵石”问题‌:
    • 在每次更新位置时,将飞船的像素位置重置为像素中心(px = floor(px) + 0.5,同理处理py)。
    • 这种方法确保了无论飞船从哪个位置开始,沿对角线移动时都能平滑地穿越像素边界。
规范化对角线移动
  • 实现方法‌:调整drxdry数组中的值,使得对角线移动时xy坐标的变化量相等(如使用0.7或0.75作为变化量)。
  • 测试与调整‌:通过实际测试不同的变化量,找到既平滑又符合预期的移动速度。
 运动速度的调整
  • 研究背景‌:通过对比不同射击游戏的移动速度,分析适合PICO-8的移动速度。
  • 数据收集‌:记录不同游戏在60帧每秒下穿越整个屏幕所需的帧数,并转换为PICO-8等效像素速度。
  • 确定速度‌:基于分析和测试,确定了一个合适的移动速度(如14像素/帧)。
银行动画(Banking Animation)
  • 目的‌:增加飞船移动时的视觉反馈,使移动看起来更自然。
  • 实现方法‌:创建多帧动画,根据飞船的移动方向选择不同的动画帧。
  • 优化‌:通过变量控制动画速度,并使用mid()函数确保动画值在合理范围内,避免溢出或不足。
pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- t: make basic movement feel nice
--    ❎: fixed cobblestoning
--    ❎: what is a good movement speed
--    t: do banking

-- t: make shooting feel nice!

-- x: normalized diagonals

butarr={1,2,0,3,5,6,3,4,8,7,4,0,1,2,0}

dirx={-1,1, 0,0, -0.7, 0.7,0.7,-0.7}
diry={ 0,0,-1,1, -0.7,-0.7,0.7,0.7}

butarr[0]=0

shiparr={1,3,5,7,9}
shipspr=3.5

function _init()
 px,py=64,64
 spd=1.4
 lastdir=0
 
 cls(0)
end

function _draw()
 cls(12)
 spr(shiparr[flr(shipspr)],px,py,2,2)
 --pset(px,py,8)
 
 local btnv=btn()&0b1111
 print(btn(),5,5,7)
 print(btnv,5,11,7)
 print(butarr[btnv],5,17,7)
 print(shipspr,5,23,7)
end

function _update60()
 local dir=butarr[btn()&0b1111]
 
 if lastdir!=dir and dir>=5 then
  --anti-cobblestone
  px=flr(px)+0.5
  py=flr(py)+0.5
 end
 
 local dshipspr=3.5
 
 if dir>0 then
  px+=dirx[dir]*spd
  py+=diry[dir]*spd
  
  if dirx[dir]<0 then
   dshipspr=1
  elseif dirx[dir]>0 then
   dshipspr=5.95
  end
 end
 
 local bankspd=0.5
  
 if dshipspr<shipspr then
  shipspr-=bankspd
 elseif dshipspr>shipspr then
  shipspr+=bankspd
 end
 
 shipspr=mid(1,shipspr,5.95)
 
 lastdir=dir
end
__gfx__
00000000000000011000000000000001100000000000000110000000000000011000000000000001100000000000000000000000000000000000000000000000
00000000000000167100000000000016710000000000001661000000000000167100000000000016710000000000000000000000000000000000000000000000
00700700000000111d100000000000111d1000000000011111100000000001d111000000000001d1110000000000000000000000000000000000000000000000
00077000000001ccc1100000000001ccc1100000000001cccc1000000000011ccc1000000000011ccc1000000000000000000000000000000000000000000000
0007700000001c77cc11000000001c77cc11000000001c77ccc10000000011c77cc10000000011c77cc100000000000000000000000000000000000000000000
0070070000001c7c1c11000000001c7c1c11000000001c7cc1c10000000011c7c1c10000000011c7c1c100000000000000000000000000000000000000000000
0000000000001c111c11100000011c111c11100000111c1111c11100000111c111c11000000111c111c100000000000000000000000000000000000000000000
0000000000001c111c17100000011c111c17100000171c1111c17100000171c111c11000000171c111c100000000000000000000000000000000000000000000
0000000000011cc17116100000161cc1171610000016117117116100000161711cc16100000161171cc110000000000000000000000000000000000000000000
000000000001d1c711d6d1000016d1c77116d10001d6d117711d6d10001d61177c1d6100001d6d117c1d10000000000000000000000000000000000000000000
00000000001ddd111d6d7d1001dddd1111dd6710176d6d1111d6d6710176dd1111dddd1001d7d6d111ddd1000000000000000000000000000000000000000000
00000000001dd6ddd6d66d1001dd66dddd6d66101666d6dddd6d66610166d6dddd66dd1001d66d6ddd6dd1000000000000000000000000000000000000000000
00000000001d676676d6dd1001d6676676d6dd101dd6d676676d6dd101dd6d6766766d1001dd6d676676d1000000000000000000000000000000000000000000
00000000000176d167d1110000117dd1171111000111171661711110001111711dd7110000111d761d6710000000000000000000000000000000000000000000
000000000000151155d110000001655155d11000000161511516100000011d551556100000011d55115100000000000000000000000000000000000000000000
00000000000001111111000000001111111100000000111111110000000011111111000000001111111000000000000000000000000000000000000000000000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值