利用排列序列提升游戏动画的真实感
在游戏开发中,我们经常需要处理重复的动画序列,以增加游戏的真实感。例如,在海战游戏中,我们可能会有一组军舰停泊在港湾,它们的桅杆或甲板时不时地需要摇晃,以模拟海风的影响。实现这种效果有多种方法,例如完全随机选择某艘军舰播放动画,或者按照固定的顺序依次播放。亦或者让几个敌方小兵随机开火,。然而,这两种方法各有其缺点。本文将介绍如何利用排列序列(Permutation Sequence)来构造一种确定性但不可预测的动画播放方式,从而提升游戏的真实感。
传统方法的不足
完全随机选择:
每次随机选择一艘军舰播放动画。
可能导致某些军舰很长时间都不会被选中,影响动画均衡性。
固定循环顺序:
按照 A → B → C → D → A → B → C → D 的顺序播放动画。
看上去过于机械,缺乏随机性,导致沉浸感下降。
利用排列序列的方案
为了克服上述问题,我们可以利用排列序列(Permutation Sequence)来生成军舰的动画播放顺序。排列序列指的是在一个List(逆天的敏感词,jihe都不行)的所有排列中,以一定规则获取某个特定的排列。
如何生成排列序列? 假设有 4 艘军舰 {A, B, C, D},我们希望在每个回合中按照不同的顺序选择它们播放动画。例如:
第 1 轮: A → B → C → D
第 2 轮: A → B → D → C
第 3 轮: A → C → B → D
第 4 轮: A → C → D → B
……
我们可以按照字典序生成所有排列,然后在每个回合中依次选择一个新的排列。
字典序索引和获取排序 计算某个排列的字典序索引 字典序索引是指一个特定排列在所有可能排列中的排名。例如,对于 {A, B, C, D} 的所有排列,排列 ABCD 的索引是 0,排列 ACBD 的索引是 5。
🧮计算公式如下:
其中:
- t[j]t[j] 是排列中的元素。
- AjA_j 是剩余未被选择的元素。
- n!n! 代表阶乘。
根据索引获取特定排列 如果我们想获取某个特定索引下的排列(如索引 5),可以使用如下方法:
- 计算当前索引所在的阶乘范围。
- 确定排列中每个元素的位置。
- 逐步缩小问题规模,直到构造完整排列。
C# 代码实现
- 生成所有排列序列
class Program
{
static void Permute(List<char> elements, int start, List<string> result)
{
if (start == elements.Count - 1)
{
result.Add(new string(elements.ToArray()));
return;
}
for (int i = start; i < elements.Count; i++)
{
(elements[start], elements[i]) = (elements[i], elements[start]);
Permute(elements, start + 1, result);
(elements[start], elements[i]) = (elements[i], elements[start]); // 回溯
}
}
static void Main()
{
List<char> ships = new List<char> { 'A', 'B', 'C', 'D' };
List<string> permutations = new List<string>();
Permute(ships, 0, permutations);
foreach (var p in permutations)
{
Console.WriteLine(p);
}
}
}
- 计算字典序索引
using System;
using System.Collections.Generic;
class Program
{
static int Factorial(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
result *= i;
return result;
}
static int GetPermutationIndex(List<char> elements, string target)
{
int index = 0;
int n = elements.Count;
List<char> available = new List<char>(elements);
for (int i = 0; i < n; i++)
{
int rank = available.IndexOf(target[i]);
index += rank * Factorial(n - i - 1);
available.RemoveAt(rank);
}
return index;
}
static void Main()
{
List<char> ships = new List<char> { 'A', 'B', 'C', 'D' };
string target = "ACBD";
Console.WriteLine("Permutation Index: " + GetPermutationIndex(ships, target));
}
}
3.使用泛型集成
using System;
using System.Collections.Generic;
// List<char> ships = new List<char> { 'A', 'B', 'C', 'D' };
// PermutationSequence<char> sequence = new PermutationSequence<char>(ships);
// List<char> permutation = sequence.GetPermutation(5);
// Console.WriteLine("Permutation at index 5: " + string.Join("", permutation));
// int index = sequence.GetPermutationIndex(new List<char> { 'A', 'C', 'B', 'D' });
// Console.WriteLine("Index of ACB: " + index);
public class PermutationSequence<T>
{
private List<T> elements;
private List<List<T>> permutations;
public PermutationSequence(List<T> elements)
{
this.elements = new List<T>(elements);
this.permutations = new List<List<T>>();
GeneratePermutations(this.elements, 0);
}
private void GeneratePermutations(List<T> list, int start)
{
if (start == list.Count - 1)
{
permutations.Add(new List<T>(list));
return;
}
for (int i = start; i < list.Count; i++)
{
(list[start], list[i]) = (list[i], list[start]);
GeneratePermutations(list, start + 1);
(list[start], list[i]) = (list[i], list[start]); // 回溯
}
}
public List<T> GetPermutation(int index)
{
if (index < 0 || index >= permutations.Count)
throw new ArgumentOutOfRangeException(nameof(index), "Index out of range");
return permutations[index];
}
public int GetPermutationIndex(List<T> target)
{
int index = 0;
int n = elements.Count;
List<T> available = new List<T>(elements);
for (int i = 0; i < n; i++)
{
int rank = available.IndexOf(target[i]);
index += rank * Factorial(n - i - 1);
available.RemoveAt(rank);
}
return index;
}
private int Factorial(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
result *= i;
return result;
}
}
结论
使用排列序列来决定动画播放顺序,可以避免纯随机可能导致的不均衡,同时也能避免固定循环导致的机械感。这种方法在游戏动画、角色 AI 行为序列、战斗动作编排等场景中都有很好的应用价值。
通过计算字典序索引,我们可以对排列进行索引管理,使得动画播放有序且可控,而不会显得刻板或完全随机。这种“确定性混沌”的方法能显著提高游戏的沉浸感,使游戏世界更加真实。
参考 ——《游戏编程精粹6》-2.4 适用于游戏开发的序列索引技术
作者:世纪末的魔术师
出处:https://www.cnblogs.com/Firepad-magic/
Unity最受欢迎插件推荐:点击查看
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2016-02-10 Unity初探之黑暗之光(1)