SonolusHaniwa
  • 1. 概述
  • 2. ハニプレ
  • 3. ユメステ
  • 4. Stellarity
  • 5. Phigros
  • 首页

    • 1. 概述
  • 玩家

    • 2. 安装服务
    • 3. 配置文件标准
    • 4. 服务使用方法
  • 开发者

    • 5. 自定义搜索函数
    • 6. 自定义资源创建接口
    • 7. 插件开发标准
  • 其他

    • 8. 更新日志
    • 9. 关于 srp 资源包
  • 1. 搭建开发环境
  • 2. Sonolus 基础
  • 3. 配置项目信息
  • 4. 基本数据类型
  • 5. 函数与语句块
  • 6. 注意事项
  • 1. 游玩模式基础
  • Index

    • 1. Introduce
  • Basics

    • 1. Index
    • 2. Types
    • 3. Statements
    • 4. Resources
    • 5. Projects
    • 6. Commands
  • API

    • Index
    • Macros
    • Builtins
    • Engine Options
    • Engine UI
    • Play Mode
    • Tutorial Mode
    • Preview Mode
    • Watch Mode
  • 1. 概述
  • 2. ハニプレ
  • 3. ユメステ
  • 4. Stellarity
  • 5. Phigros
  • 首页

    • 1. 概述
  • 玩家

    • 2. 安装服务
    • 3. 配置文件标准
    • 4. 服务使用方法
  • 开发者

    • 5. 自定义搜索函数
    • 6. 自定义资源创建接口
    • 7. 插件开发标准
  • 其他

    • 8. 更新日志
    • 9. 关于 srp 资源包
  • 1. 搭建开发环境
  • 2. Sonolus 基础
  • 3. 配置项目信息
  • 4. 基本数据类型
  • 5. 函数与语句块
  • 6. 注意事项
  • 1. 游玩模式基础
  • Index

    • 1. Introduce
  • Basics

    • 1. Index
    • 2. Types
    • 3. Statements
    • 4. Resources
    • 5. Projects
    • 6. Commands
  • API

    • Index
    • Macros
    • Builtins
    • Engine Options
    • Engine UI
    • Play Mode
    • Tutorial Mode
    • Preview Mode
    • Watch Mode
  • 基础知识

    • 1. 搭建开发环境
    • 2. Sonolus 基础
    • 3. 配置项目信息
    • 4. 基本数据类型
    • 5. 函数与语句块
    • 6. 注意事项
  • 游玩模式

    • 1. 游玩模式基础

Sonolus 基础

原型与实体

注意

本段内容不适用于教程模式。

原型是一种实体的抽象概念,由引擎数据定义。在 Sonolus.h 中,您需要使用 Archetype 类的继承类来定义一种原型。

实体是一种原型的示例,由关卡数据定义。在 Sonolus.h 中,您可以通过 LevelData.h 中的 API 简易地生成包含多个实体的关卡数据。

在关卡初始化阶段,Sonolus 会遍历关卡数据中的实体。对于每个实体,会根据其指定的原型名生成对应原型的示例。

单个原型是由多个回调函数及其对应的调用顺序构成的,具体调用细节视游玩模式不同而不同。一般来说,在关卡初始化阶段,会调用每个实体的 preprocess 或其他回调函数,随后在游戏进行时的每一帧,会以特定的顺序与时机调用剩余回调函数。

回调函数调用顺序(*Order)是一个编译期常量,不可在引擎运行过程中修改。它决定了该回调函数在不同原型中的调用顺序。该值越小,意味着该原型中的该回调函数在同一执行周期中会更早执行,反之会更晚执行。

游戏帧/更新周期

注意

本段内容不适用于预览模式。

Sonolus 将每一帧作为一个更新周期。在该更新周期中,会以特定顺序彻底调用一遍未在初始化过程执行的回调函数。

开发者在每一更新周期都需要调用 Draw 函数绘制相关精灵,否则该更新周期绘制的精灵将在下一更新周期被清除。

开发者不需要在每一更新周期都调用 Play/SpawnEffect 函数播放音效和特效,只需要在合适的时机调用一次即可,Sonolus 不会清除上一更新周期播放的音效和特效。

数据存储

在 Sonolus.h 中,数据均存储在多个由一段简单的连续内存组成的区块内。

一般来说,所有回调函数具有对所有区块的读取权限,但只有部分回调函数具有对部分区块的写入权限。

通过 Sonolus.h 提供的低级函数,您可以简单地访问这些内存块。例如您可以通过 Get(blockId, offset) 函数获取 id 为 blockId 的区块上偏移为 offset 的变量,同时可以通过 Set(blockId, offset, value) 函数将 id 为 blockId 的区块上偏移为 offset 的变量设置为 value。

Sonolus.h 抽象化了这些低级操作并将其转化为了对开发者友好的 API。

部分区块的值可在游戏暂停时的菜单中查看(需要在设置中开启调试模式)。

针对于已激活实体的区块的值可在游戏暂停时的 Active Entities 中找到相关实体查看(需要在设置中开启调试模式)。

接下来将为您介绍常见的部分区块名及其作用。

注意

请注意各个区块的可见模式,在无另外提及的情况下默认为所有模式可见。

相关信息

在 Sonolus.h 中,您可以直接通过区块名来访问各区块数据,也可以通过区块名加上 Id 来获取区块 id。

RuntimeEnvironment

该区块包含了用户屏幕宽高比,音频偏移等运行时环境信息。

RuntimeUpdate

该区块包含了当前时间,缩放时间等当前更新周期的运行时信息。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

RuntimeTouchArray

该区块包含了当前帧的触摸(touch)信息以及触摸更新信息。

在 Sonolus.h 中,touchCount 全局变量代表触摸数量,touches 数组则包含所有触摸信息。touches 数组支持以 int 常量或 var 作为偏移量传入。

该区块仅在游玩模式下可见,其他模式不可见。

RuntimeUI

该区块包含了 Sonolus UI 组件信息,您需要通过手动修改该区块的值来控制 Sonolus UI 组件。

在 Sonolus.h 中,ui 全局变量包含了您可以控制的全部 Sonolus UI 组件。您可以简单地用 setUI 函数来修改单个 Sonolus UI 控件的属性值。

当然,您也可以通过在皮肤中导入组件图像,自行实现您自己的 UI 组件。但请在引擎配置中添加 Enable Sonolus UI 等相似选项,因为部分玩家更习惯使用 Sonolus UI 组件而非您的自定义 UI 组件。

RuntimeUIConfiguration

该区块包含了 Sonolus UI 组件的用户侧配置信息,您可以通过使用该区块的值来计算出 Sonolus UI 组件的属性值。

在 Sonolus.h 中,configuration 全局变量包含了所有 Sonolus UI 组件用户侧配置信息。

LevelMemory/TutorialMemory/PreviewData

该区块一般用于通用内存存储。

在 Sonolus.h 中,var 类型会自动分配该区块的内存,因此不推荐您自行分配该区块的内存。

LevelOption/PreviewOption

该区块包含了所有引擎选项值。

在 Sonolus.h 中,您可以通过 ToggleOption/SelectOption/SliderOption 来定义引擎选项供用户控制。关卡启动后所有选项的值将会自动写入到 LevelOption 区块。

该区块在教程模式下不可见,其他模式可见。

LevelBucket

该区块包含了所有已定义的桶信息,您需要通过手动修改该区块的值来控制桶的属性。

在 Sonolus.h 中,您可以简单地用 setBucket 函数来修改单个桶的属性值。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

LevelScore

该区块包含了所有原型在不同判定下的得分倍率,您需要通过手动修改该区块的值来控制原型在不同判定结果下的得分倍率。

在 Sonolus.h 中,您可以简单地用 setScore 函数来修改单个原型在不同判定下的得分倍率。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

EntityMemory

该区块一般用于实体内存存储。

在 Sonolus.h 中,var 类型会自动分配该区块的内存,因此不推荐您自行分配该区块的内存。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

EntitySharedMemory

该区块一般用于实体共享内存存储,其他实体可以读取该实体的共享内存。

在 Sonolus.h 中,您需要使用 var a = var(EntitySharedMemoryId, 0); 来手动分配该区块的内存。

该区块在教程模式下不可见,其他模式可见。

EntityData

该区块包含了该实体的实体数据。

在 Sonolus.h 中,您可以通过 defineImport 或 defineImportDetailed 来定义该原型将会包含的实体数据,Sonolus.h 会自动创建相应变量并自动分配 EntityData 区块内存,因此不推荐您自行分配该区块的内存。

该区块在教程模式下不可见,其他模式可见。

EntityInfo

该区块包含了该实体的详细信息,在所有回调函数中均不可修改。

在 Sonolus.h 中,您可以在原型内使用 info 全局变量来获取该实体的详细信息。

该区块在教程模式下不可见,其他模式可见。

EntityDespawn

该区块仅用于实体向 Sonolus 传递销毁信息。

在 Sonolus.h 中,您可以在原型内部分回调函数中使用 despawn.despawn = true; 来销毁该实体。

该区块仅在游玩模式下可见,其他模式不可见。

EntityInput

该区块仅用于实体向 Sonolus 传递判定信息。

在 Sonolus.h 中,您可以在原型内使用 input 全局变量来设置该实体的判定信息。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

EntitySharedMemoryArray

该区块包含了所有实体共享内存信息,您可以通过该区块来访问/修改其他实体的共享内存。

在 Sonolus.h 中,您可以通过 EntitySharedMemoryArray[entityId].generic[offset] 来访问/修改其他实体的共享内存。

该区块在教程模式下不可见,其他模式可见。

EntityDataArray

该区块包含了所有实体数据,您可以通过该区块来访问/修改其他实体的实体数据。

在 Sonolus.h 中,您可以通过 EntityDataArray[entityId].generic[offset] 来访问/修改其他实体的实体数据。

该区块在教程模式下不可见,其他模式可见。

EntityInfoArray

该区块包含了所有实体详细信息,在所有回调函数中均不可修改。

在 Sonolus.h 中,您可以通过 EntityInfoArray[entityId] 来访问其他实体的详细信息。

该区块在教程模式下不可见,其他模式可见。

ArchetypeLife

该区块包含了所有原型在不同判定下对 Sonolus 的生命值贡献,您需要通过手动修改该区块的值来控制原型在不同判定结果下对 Sonolus 的生命值贡献。

在 Sonolus.h 中,您可以在原型内使用 life 全局变量来设置该原型在不同判定结果下对 Sonolus 的生命值贡献。

该区块仅在游玩模式和观看模式下可见,其他模式不可见。

TemporaryMemory

该区块一般用于临时内存存储。

在 Sonolus.h 中,var 类型会自动分配该区块的内存,因此不推荐您自行分配该区块的内存。

皮肤精灵(Skin Sprite)

皮肤精灵本质上就是一张 png 图片,开发者可以使用 Draw 函数来将皮肤精灵绘制到 Sonolus 画面里。

在 Sonolus 中,任何模式均可以使用皮肤精灵来渲染画面。

相关信息

在 Sonolus.h 中,您可以将精灵图片放置于 skins 文件夹下,然后使用 defineSkinSprite(name) 函数来导入精灵。默认情况下 Sonolus.h 会寻找 /skins/{name}.png 作为该精灵的 png 图片。

也可以不放置在 skins 文件夹下,此时需要使用 defineSkinSprite(name, path) 函数来导入精灵。

只有被导入过的精灵才可以在 Sonolus 中被使用。

在 main 函数中,通过调用 PackSkin 函数,Sonolus.h 会自动打包皮肤精灵并在 dist 目录下生成对应的 SkinData 和 SkinTexture。

音效片段(Effect Clip)

音效片段本质上是一段 mp3 音频,开发者可以在特定的时间调用 Play 或 PlayScheduled 函数以在 Sonolus 中播放音效。

在 Sonolus 中,除了预览模式,均可以使用音效片段来播放音效。

相关信息

在 Sonolus.h 中,您可以将音效片段放置于 effects 文件夹下,然后使用 defineEffectClip(name) 函数来导入音效。默认情况下 Sonolus.h 会寻找 /effects/{name}.mp3 作为该音效的 mp3 片段。

也可以不放置在 effects 文件夹下,此时需要使用 defineEffectClip(name, path) 函数来导入音效。

只有被导入过的音效才可以在 Sonolus 中被使用。

在 main 函数中,通过调用 PackEffect 函数,Sonolus.h 会自动打包皮肤精灵并在 dist 目录下生成对应的 EffectData 和 EffectAudio。

特效(Particle Effect)

特效制作比较复杂,目前 Sonolus Studio 提供了特效编辑器,您可以在该网站中制作您自己的特效,然后上传到您自己的 Sonolus Server 服务器中。

开发者可以在特定的时间调用 SpawnParticleEffect 函数以在 Sonolus 中播放特效。

在 Sonolus 中,除了预览模式,均可以使用特效来反馈用户输入。

相关信息

在 Sonolus.h 中,您可以使用 defineParticleEffect(name) 函数来导入特效。

由于特效制作比较复杂,我们并不提供打包特效的方法。请使用 Sonolus Studio 自行制作特效并上传到服务器中。

只有被导入过的特效才可以在 Sonolus 中被使用。

桶(Bucket)

在 Sonolus 中,一个桶中包含了多个计入 combo 的实体,且每个计入 combo 的实体能且仅能被装入一个桶中。

在结果页面,Sonolus 会列举出每个桶,并将该桶中所有计入 combo 的实体的判定结果绘制成一张图供玩家参考。

在 Sonolus 中,只有游玩模式和观看模式需要用到桶。

相关信息

在 Sonolus.h 中,您可以使用 defineBucket 函数来定义一个桶。

您还可以使用在原型中通过给 input.bucketIndex 赋值来指定桶,并通过给 input.bucketValue 赋值来指定该实体的判定结果。

最近更新: 2025/5/4 07:56
Contributors: LittleYang0531
Prev
1. 搭建开发环境
Next
3. 配置项目信息