I Wanna Edition

I wanna be the Engine Nikaple Edition

镜像备份!!!!!!

一个完整的 I Wanna 衍生游戏制作框架。

引擎功能

  • 多人联机支持
  • 多语言支持
  • 集中管理的音乐系统
  • 方便的调试功能
  • 快捷的内置聊天室
  • 更友好的错误信息
  • ……

联机

如何禁用

在脚本 setGlobals 中,将设置 global.game_mode = MODE_SINGLE_PLAYER 即可。(默认不禁用)

……


音乐

果引擎使用了 Super Sound 音乐系统,在它的支持下,你可以从外部读取声音文件,并且可以暂停与继续播放音乐(这是 GM 自带函数所做不到的)。

Super Sound 支持的音乐格式仅限 ogg 与 wav,推荐使用 ogg 格式( wav 格式的音乐占用空间太大)。因此,在使用音乐前需要将其转换为 ogg 格式,这可以借助 狸窝全能视频转换器在线转码网站 来完成。

音乐播放主要涉及到两个脚本: music_initmusic_config ,它们都在Scripts -> audio文件夹下。

  • music_init 用来从外部文件夹中读取音乐至游戏中;
  • music_config 会在各个房间刚开始时调用一次,决定各个房间中需要播放的音乐。

音乐的存放位置可以通过 setGlobalsMinor 中的 global.music_directory 设置,默认为 Data/Music

升级到 2.0

在果引擎升级到 2.0 版之后,播放音乐的脚本名称更加统一了:

1
2
3
4
5
6
7
8
9
10
// 音乐与音效均可以使用 music_play 播放
music_play(sndBlockChange)
music_play(BGM_BOSS1)
// 音乐与音效均可以使用 music_stop 停止
music_stop(sndDeath)
music_stop(curMusic)
// 音乐还能够使用相关脚本循环、暂停、继续播放
music_loop(BGM_Stage1)
music_pause(BGM_Stage1)
music_resume(BGM_Stage1)

房间音乐的设置方法

以下两种方法任选其一,同时使用时分房间设置的 BGM 会覆盖集中设置的 BGM。在果引擎中, /Data/Music 目录下的所有音乐都会被默认自动加载,并将其 id 以全局变量名 BGM_文件名 储存。因此在制作游戏的过程中,最好不要使用 BGM_ 开头的变量名,否则很可能发生冲突。音乐加载具体说明如下:

  • Death.ogg 会被自动读取为 BGM_Death
  • faQ.ogg 会被自动读取为 BGM_faQ
  • myMusic.ogg 会被自动读取为 BGM_myMusic

注意,由于 GM 引擎限制,自动加载的音乐名称均只由 0-9, A-Z, a-z, 下划线”_” 构成,如果文件名中含有其他字符,需要手动调用 music_load 函数加载。

分房间设置(新手推荐)

在房间中放入 objPlayMusic (位于 rooms 文件夹下)并设置相关参数即可,如果你想将音乐文件夹中的 faQ.ogg 设置为当前房间的 BGM,则:

Creation Code 参数:

1
2
// 当前房间的 BGM
bgm = BGM_faQ // <- 在文件名前面加上 BGM_ 即可

由于此处的 BGM_faQ 为全局变量,而不是 GM 中的资源名,所以在 GM 中呈现的是变量的颜色(黑色),这并不影响音乐文件的正常播放。

集中设置

  • music_config 中,仿照示例增加代码播放音乐,例如:

    1
    2
    3
    4
    5
    // add your code here
    case myRoom:
    music_play(BGM_myMusic);
    break;
    // ...

    注意后面的 break 不可省略!

对音乐进行骚操作

如果你需要暂停、跳转播放、区域循环等高级功能,可以对需要使用高级功能的音乐使用非流模式加载。即:

1
2
globalvar BGM_myMusic;
BGM_myMusic = music_load('myMusic', 0)

之后,便可以使用 SS_SetSoundPosition 等函数对 BGM_myMusic 进行处理而不受缓冲区大小限制。

BOSS 房间的 BGM 处理

在 BOSS 房间中,你可能想要自己控制 BGM 播放的时机。可以按照下面的方法设置:

  1. 先找到脚本 isBossRoom ,并设定相关房间为 BOSS 房(参照脚本即可)。

  2. 在你需要播放 BOSS 战音乐时,调用:

1
music_play(myMusic);

如果需要在流式播放模式下将某首音乐设置为非流式播放,可以在 music_init最下方 加上 BGM_myMusic = music_load('myMusic', false) (将 myMusic 更换为音乐文件的名称)即可。

另外,在默认设置下,BOSS 房间中不可暂停。如果需要允许暂停,可以到 setGlobalsMinor 脚本中修改 global.enable_pause_in_boss_room = true 即可。

Creation Code

如何使用 Creation Code

在引擎中,大量存在着通用 object,它们通过放置在房间之后的 Creation Code 来实现差异化功能。具体使用方法为:

  1. 打开房间编辑器,将 object 摆放到房间中

  2. 根据 GameMaker 版本的不同,添加 Creation Code 的方式也不同

    • GameMaker 8.0:Ctrl + 右键 -> Creation Code...
    • GameMaker 8.1:右键 -> Creation Code...

果引擎中的 Creation Code 规范

Creation Code 中,存在着许多通用代码,记住它们将能帮助你更快更好地使用引擎,归类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
--------------- 通用 ---------------
spr = 需要更换的精灵(sprite_index
ind = 精灵编号(image_index
ispd = 精灵播放速度(image_speed
xs = 水平缩放(image_xscale
ys = 竖直缩放(image_yscale
trg = 触发器编号
h = 触发横向速度
v = 触发纵向速度
spd = 触发速度
dir = 触发方向
origin = 旋转/缩放中心
time = 时间(以帧为单位)
num = 编号(boss编号,道具编号等)
noDes = 出房间后是否不销毁(默认为出房间后直接销毁)
noSync = 是否不同步(默认同步)
dis = 出房间后销毁前移动的距离(默认为 0

------------- 路径相关 -------------
pth = 路径编号
spd = 速度
enda = 路径结束事件(参考常量表)
scl = 路径放大倍数
move = 是否防止剧透(玩家死亡之后会沿着当前方向移动,不会停止/转弯)

------------- 传送相关 -------------
r = 目标房间
kind = 转场效果(可选)
num = 目标 playerStart 的编号(可选)
mode = warp 模式('normal'/'border',默认为'normal'
text = warp 上方文字(可选)
color = warp 上方文字颜色(可选)

触发系统

触发是 I Wanna 中各种坑实现的基础。果引擎 2.0 版重写了触发系统以提高运行时效率,使用起来几乎与原来一致。

简介

触发系统主要包含两种 object:触发器与触发对象,它们通过 触发事件 联系到一起。该系统的运作方式可概括为下图:

  • 触发器指一类会响应 player 动作的 object,它可以在某种条件下发出带有一定标记(trg)的 触发事件。包括:

    • 隐形的 trigger,当 player 与之相碰撞时,发出 触发事件
    • 延时的 trigger,当 player 与之相碰撞之后,过一段时间再发出 触发事件
    • 可见的 button,当 player 射击击中时,发出 触发事件
  • 触发对象是一类可以响应 触发事件object,包括:

    • 在触发后会运动的刺
    • 在触发后会运动的板子
    • 在触发后会被创建的隐形砖
    • 在触发后会做任何动作的任意 object

trg 与 key 一体化

在之前的版本中,keyTrigger 经常用于回头坑,因为它在指定 trgfreeTrigger 触发之前不会对 player 的任何动作作出反应。而在 2.0 版中,freeTriggerkeyTrigger 合并为了 objTriggerobjTrigger 的使用方法与 freeTrigger 完全一致。并且,当在 Creation Code 中指定 key 时,即可当做 keyTrigger 使用。

普通 objTrigger:

1
2
trg = 1
ys = 6

当作 keyTrigger 使用:

1
2
3
trg = 2
key = 1
ys = 6

为了更方便地调试触发机关,在调试模式objTrigger 会有一些额外的处理。

playerKiller 均可被触发?

这也是果引擎 2.0 版中触发系统最明显的变化。你可以将任意 playerKiller 放置在房间中,然后使用 trg 使其触发。支持 4 种模式:

  • 速度
  • 路径
  • 缩放
  • 旋转
速度模式

触发之后会以指定速度运动。有两种触发方式:

  • 横向/纵向速度触发:

    Creation Code 参数:

    1
    2
    3
    4
    5
    6
    // 必填,触发器编号
    trg = 1
    // 可选,横向速度
    h = 4
    // 可选,纵向速度
    v = 4
  • 速度/方向触发:

    Creation Code 参数:

    1
    2
    3
    4
    5
    6
    // 必填,触发器编号
    trg = 1
    // 必填,速度
    spd = 6
    // 可选,方向,默认向右
    dir = 45
路径模式

触发之后会沿着给定路径运动。

Creation Code 参数:

1
2
3
4
5
6
7
8
9
10
11
12
// 必填,触发器编号
trg = 1
// 必填,路径名称
pth = pCircle
// 必填,路径运动速度
spd = 5
// 可选,路径缩放大小
scl = 1
// 可选,路径结束动作
enda = PATH_ACTION_STOP
// 是否防止剧透(玩家死亡之后会沿着当前方向移动,不会停止/转弯)
move = true
缩放模式

触发之后会参照指定中心进行放大/缩小。公共参数如下:

Creation Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 必填,触发器编号
trg = 1
// tarx / tary 至少有一个不为空
// 可选,x 方向缩放量
tarx = 3
// 可选,y 方向缩放量
tary = 3
// 可选,使用的精灵
spr = sprSpikeUp
// 可选,快速设置缩放中心(会被 cx/cy 覆盖)
origin = 5
// 可选,缩放中心与精灵中心的横向偏移量
cx = 0
// 可选,缩放中心与精灵中心的纵向偏移量
cy = 0

其中,origin 的值为 1 - 9,分别对应精灵的左上角,中上,右上角……见下:

1
2
3
1 2 3
4 5 6
7 8 9

触发方式有两种:

  • 缩放时间触发:

    Creation Code 参数:

    1
    2
    // 必填,缩放到目标缩放量所需要的时间(帧)
    time = 50
  • x, y 缩放速度触发:

    Creation Code 参数:

    1
    2
    3
    // xsp 与 ysp 不能都为空
    xsp = 0.04 // 触发之后 x 方向的缩放速度
    ysp = 0.04 // 触发之后 y 方向的缩放速度

对于这几个参数的额外说明:

假设你需要将某刺在 1 秒内缩放到原来的 3 倍大小,那么 tarx,tary 的值均为 3。

  • 对于缩放时间方式,time = 50;
  • 对于缩放速度方式,xsp 与 ysp 的值均为:(3 – 1) / 50 = 0.04。
旋转模式

触发之后会沿着指定中心旋转一定角度。

Creation Code 参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 必填,触发器编号
trg = 7
// 必填,旋转角度
ang = 90
// 必填,旋转时间
time = 20
// 可选,使用的精灵
spr = sprSpikeUp
// 可选,快速设置缩放中心(会被 cx/cy 覆盖)
origin = 5
// 可选,旋转中心与 spr 中心的横向偏移量
cx = 0
// 可选,旋转中心与 spr 中心的纵向偏移量
cy = 0

其中,origin 的值为 1 - 9,分别对应精灵的左上角,中上,右上角……见下:

1
2
3
1 2 3
4 5 6
7 8 9

?> 当 playerKiller 被直接摆放在房间外时,引擎会自动设置 noDes = true,确保它能被正确地创建。

时序触发器

object 可以在 Objects -> triggers -> objSequenceTrigger 找到。用于触发一些按特定顺序出现的坑。

应用场景举例:

player 碰到时直接触发 trg = 1触发事件,1 秒之后触发 trg = 2触发事件

1
2
3
trg[1] = 1
time[1] = 50
trg[2] = 2

player 碰到时不触发任何事件,1 秒之后触发 trg = 1 的触发事件,3 秒之后触发 trg = 2 的触发事件:

1
2
3
4
5
trg[1] = 9999
time[1] = 50
trg[2] = 1
time[2] = 100
trg[3] = 2

调试模式以及报错

当游戏以调试模式运行时,objTrigger 会显示当前的 trg 以及 key 以便观察:

objTriggerobject 的 Creation Code 中没有 trg ,或者 trg0 时,引擎会捕捉到这类错误并抛出一个错误,如:

trigger error

此时在位于 rOnlineSpike (384, 480) 处的 objTrigger 的 Creation Code 中补充必要的参数即可。