LL谱面分析和难度标定

先介绍一下LL谱面的存储方式:TimeLine序列(简称TL序列),TL序列中的每一个元素(即音符)可以由一个C语言中的结构体来表示:

struct note{
int line; //音符位置
double time; //音符按下时间
double elapseTime; //音符从按下到抬起经过的时间,只有L型音符该项不为零
};

用比较数学化的表示方法来表示一下TL序列的各个属性:

音符的索引(下标)集合\(\mathbf{N}\);
音符的位置组成的序列\(p_N=\lbrace p_{n}\mid n\in\mathbf{N}\rbrace\);
音符的按下或抬起时刻组成的序列\(t_N=\lbrace t_{n}\mid n\in\mathbf{N}\rbrace\);
表明该音符应该是按下还是抬起的序列\(s_{N}=\lbrace s_{n}\mid n\in\mathbf{N}\rbrace\),\(s_n=0\)表示第n个音符应按下,\(s_n=1\)表示第n个音符应抬起。

我们将\(p_N\)
分为两部分:左手部分
\(p_I=\lbrace p_{i}\mid i\in\mathbf{I}\rbrace\)
和右手部分
\(p_J=\lbrace p_{j}\mid j\in\mathbf{J}\rbrace\)
,其中
\(\mathbf{I}=\lbrace i \mid i \in \mathbf{N} \land p_i \lt 5 \rbrace\)

\(\mathbf{J}=\lbrace j \mid j \in \mathbf{N} \land p_j \ge 5 \rbrace\)

与之对应,将\(t_N\)
也分为两部分:
\(t_I=\lbrace t_{i}\mid i\in\mathbf{I}\rbrace\)

\(t_J=\lbrace t_{j}\mid j\in\mathbf{J}\rbrace\)

不过这样得到的左手部分和右手部分有一定毛病,因为不一定每一个5号位Note都得用右手去打。以后会有更科学的定义(现在还没想好,憋打我!)。

有了\(p_I\)、\(p_J\)、\(t_I\)和\(t_J\),就可以初步定义一个衡量难度的函数了。

先考虑双指玩家(双指玩家即在游戏过程中仅使用两根手指的玩家,包括拇指党、食指党等等),则在游戏过程中玩家需不断转移手指,游戏的难度即与手指的转移速度、加速度等因素有关。

下图为小编实测的Live界面的各项参数(整数为像素,分数为比例形式),原谅我懒得在图里面打字……

这里我们要推导出的难度公式是与设备无关的,这样才能使每一个谱面的难度值唯一。

设\(\Delta p_I\)和\(\Delta p_J\)分别为\(p_I\)和\(p_J\)的一阶差分,空闲时序列\(\Delta t_I\)和\(\Delta t_J\)为\(t_I\)和\(t_J\)的一阶差分,则

于是玩家左手在时刻\(t\)的速度可定义为:
$$
\left. v_l \right|_t =
\begin{cases}
\frac{\Delta p_i}{\Delta t_i}, & i>1,i \in \mathbf{I} \\
0, & i=1
\end{cases}
$$
其中\(t_i\)为\(t_I\)中的不大于\(t\)的最大值。
加速度近似为:
$$
\left. a_l \right|_t =
\begin{cases}
\frac{\Delta^2 p_i}{\Delta t_i^2}, & i>2,i \in \mathbf{I} \\
0, &i=1 \mbox{ or } i=2
\end{cases}
$$
其中\(\Delta^2 l_I\)是\(l_I\)的二阶差分。
定义左手难度函数:
$$
D_l(t)=c_v \left. v_l \right|_t+c_a \left. a _l\right|_t
$$
相似地定义右手难度函数:
$$
D_r(t)=c_v \left. v_r \right|_t+c_a \left. a _r\right|_t
$$
其中\(c_v\)和\(c_a\)分别为两个常数,控制速度和加速度在难度中的权重。

我们知道玩家在Live时是先看好未来的几个圈的位置再做出决定的,也就是说,未来的几个圈的分布会对读谱难度产生影响。

定义谱面下落速度\(v_d\)为一个音符从中心运动到目标位置所需时间\(t_d\)的倒数。

玩家所能看见的未来的几个Note的时刻构成的集合为\(\mathbf{T}_s=\lbrace t_n \mid 0 \lt t_n-t \le t_d \rbrace\),当然太小的note和离手太近的note玩家会很少注意,所以不同位置note对读谱难度影响不同。定义一个函数\(d_n(t)\),表示即将到来的序号为n的note对当前读谱难度的加成。则可以定性给出:
$$
d_n(t)=
\begin{cases}
c_d, & 0 \le t_n-t \lt t_s \\
2c_d, & t_s \le t_n-t \lt t_d \\
0, & \mbox{others}
\end{cases}
$$
其中\(x=\frac{t-t_n+t_d}{t_d}\),\(c_d\)为常数,\(t_s\)为玩家反应时间,一般可取\(t_s=0.1s\)。

可以定义这样的一个瞬时难度函数:
$$
D(t)=D_l(t)+D_r(t)+\sum_{t_n \in \mathbf{T}_s} d_n(t)
$$
它可以比较科学地确定游戏过程中某个时刻的难度。


正在更新中

LL谱面分析和难度标定的更多相关文章

  1. 年度游戏圈2018白皮书解析手游折扣app哪个好及靠谱程度分析

    2018年,随着全国暂停游戏版本的审核和发布<综合防控儿童青少年近视实施方案>(控制新的在线游戏数量),游戏行业受到的影响不小. 在游戏产业中,游戏行业2018年的收入同比增长5.2%,远 ...

  2. Linux内核源码分析方法

    一.内核源码之我见 Linux内核代码的庞大令不少人“望而生畏”,也正因为如此,使得人们对Linux的了解仅处于泛泛的层次.如果想透析Linux,深入操作系统的本质,阅读内核源码是最有效的途径.我们都 ...

  3. Chrome渲染分析之Timeline工具的使用

    原文http://www.th7.cn/web/html-css/201406/42043.shtml Timeline工具栏提供了对于在装载你的Web应用的过程中,时间花费情况的概览,这些应用包括处 ...

  4. javascript函数式编程一例分析

    js像其他动态语言一样是可以写高阶函数的,所谓高阶函数是可以操作函数的函数.因为在js中函数是一个彻彻底底的对象,属于第一类公民,这提供了函数式编程的先决条件. 下面给出一个例子代码,出自一本js教程 ...

  5. Android版数据结构与算法(四):基于哈希表实现HashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 存储键值对我们首先想到HashMap,它的底层基于哈希表,采用数组存储数据,使用链表来解决哈希碰撞,它是线程不安全的,并且存储的key只能有一个为 ...

  6. 相机标定问题-Matlab & Py-Opencv

    一.相机标定基本理论 1.相机成像系统介绍 图中总共有4个坐标系: 图像坐标系:Op    坐标表示方法(u,v)                 Unit:Dots(个) 成像坐标系:Oi      ...

  7. 空间谱专题02:波束形成(Beamforming)

    作者:桂. 时间:2017-08-22  10:56:45 链接:http://www.cnblogs.com/xingshansi/p/7410846.html 前言 本文主要记录常见的波束形成问题 ...

  8. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  9. 20155232《网络对抗》Exp4 恶意代码分析

    20155232<网络对抗>Exp4 恶意代码分析 1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门 ...

随机推荐

  1. npm-bluebird使用

    API 注意 时刻注意return; 使用Promise.promisify简化对test(val, function(err, result){})的处理; 尽量避免使用deferred objec ...

  2. Spring--通过注解来配置bean【转】

    Spring通过注解配置bean 基于注解配置bean 基于注解来配置bean的属性在classpath中扫描组件 组件扫描(component scanning):Spring能够从classpat ...

  3. WPS 表格筛选两列相同数据

    选出B列中的数据是否在A列中出现:用countif 函数,在 B列右侧插入一列,C1输入 = countif 区域中选择 B列的内容区域(选择后加 按F4),条件选择B列所在的内容区域(选择后按F4) ...

  4. 在DrawingVisual上绘制圆形的进度条,类似于IOS系统风格。

    1.说明:在WPF中,文件下载时需要显示下载进度,由于系统自带的条型进度条比较占用空间,改用圆形的进度条,需要在DrawingVisual上呈现. 运行的效果如图: private Point Get ...

  5. DataTable 的使用

    DataTable CFHMXdt = new DataTable(); CFHMXdt.Columns.Add("group", typeof(System.String));  ...

  6. First step to Signal —— in Linux C Programing

    1. What's signal 信号是软件中断,提供了一种处理异步事件的方法.(见<Unix环境高级编程>)一般使用时需包含 signal.h 库. 每个信号命名由SIG开头,实际值为正 ...

  7. Python In Action:三、再来一个扩展例子,保证不难

    在窗口显示一张图片,代码如下: import wx class Frame(wx.Frame): """Frame class that displays an imag ...

  8. 03.深入javascript

    函数返回值 函数返回值和函数传参正好相反,函数传参是我们可以把一些东西传到函数里面去,函数返回值是函数可以把一些东西传到外面来. <script> function show() { re ...

  9. iOS CADisplayLink 定时器的使用

    CADisplayLink 是一个能让我们以和屏幕刷新频率相同的频率将内容刻画到屏幕上的定时器,在应用中创建一个新的CADisplayLink对象,把他添加到一个runloop中,并且给他提供一个ta ...

  10. IOS网络第五天 AFN-02-文件上传,底部弹出窗体,拍照和相册获取图片上传

    ************** #import "HMViewController.h" #import "AFNetworking.h" @interface ...