Silverlight 2.5D “.NET研究”RPG游戏技巧与特效处理:(十二)魔法系统

简介:   世界首款Silverlight – MMORPG:震撼登场!伴着与XNA合体后的Silverlight 5 强势发布,一波Silverlight网游研发海啸即将席卷全球!   多磨的好事依旧让人激动,于是一不小心写下10款全新的魔法效果旨在祝贺。

  世界首款Silverlight – MMORPG<<窝窝世界>>震撼登场!伴着与XNA合体后的Silverlight 5 强势发布,一波Silverlight网游研发海啸即将席卷全球! 

  多磨的好事依旧让人激动,于是一不小心写下10款全新的魔法效果旨在祝贺。今天的教程不会让你失望,没错,又是一场超豪华魔法盛宴!接下来您将看到的是本教程ARPG Demo战斗实景,一切灵感与临摹均来源于近期即将内测的2.5D大作《倩女幽魂Online》(以下左边为倩女幽魂实景,右边为Demo对应实景)。野蛮冲撞之幻象刺杀!自适配地形之雷电风行!完美冰冻之暴风狂雪!环形突击之圆月斩!随机多段连环突刺~毒化!自定义波浪发散之烈火轰炸!连续多段灼烧之陨石坠落!扇形范围之石化穿梭箭! 

  在线演示Demo地址:http://silverfuture.cn/

  那么回溯到本节的主题:魔法系统是如何创建的呢?首先,我们可以将魔法和技能看做同一系统;魔法的原理与AI系统类似,从简单切入主要划分为“规则”与“使用”两个部分。“规则”包括魔法的基础性质/属性(等级、施放条件、抵抗条件、威力、附加效果、特效、物理引擎、粒子系统等等),魔法的分类(以元素为基础,日系的如气、水、火、土、光明、黑暗;中式的金、木、水、火、土,相生相克。以作用为根据,BuffDeBuff、召唤、复制、魔幻等等),以及魔法的炼化(金钱/经验/使用次数升级;装备加成;组合拆分等等)。而“使用”则面向所有不同类型的魔法从触发开始到完成所有伤害这整个流程。

  规则这部分属于策划的范畴我们暂且放它一边,本节的重点是向大家讲解Silverlight MMORPG中魔法施放的整个流程。

  首先是触发,主角施法过程通常由玩家操作鼠标右键或通过键盘的快捷键触发:

 
  
/// <summary>
/// 游戏中鼠标右键按下
/// </summary>
void LayoutRoot_MouseRightButtonDown( object sender, MouseButtonEventArgs e) {
e.Handled
= true ;
Point p
= e.GetPosition(space);
leader.Target
= null ;
leader.TurnTowardsTo(p);
leader.Casting(
new 上海徐汇企业网站制作> MagicArgs() {
Code
= Convert.ToInt32(((ComboBoxItem)comboBox39.SelectedItem).Tag),
Level
= Convert.ToInt32(((ComboBoxItem)comboBox38.SelectedItem).Tag),
SpaceLayer
= leader.SpaceLayer,
Scale
= leader.Scale,
Position
= leader.Position,
Destination
= p,
});
}
而非控角色则通常由 AI引导触发:
 
 
/// <summary>
/// 角色行为执行
/// </summary>
void role_ActionDecide( object sender, EventArgs e) {
RoleBase attacker
= sender as RoleBase;
RoleBase target
= attacker.Target;
if (attacker.IsHostileTo(target) && attacker.IsVisible) {
// 怯懦行为简单表现为不主动追击,发现被攻击时立刻逃跑
if (target.ActionAI == ActionAIs.Cowardice) {
target.Target
= null ;
target.MoveTo(
new Point(ObjectBase.RandomSeed.Next(( int )(target.Position.X - target.SightRange), ( int )(target.Position.X + target.SightRange)), ObjectBase.RandomSeed.Next(( int )(target.Position.Y - target.SightRange), ( int )(target.Position.Y + target.SightRange))));
}
if (target.InCircle(attacker.Position, attacker.AttackRange)) {
attacker.TurnTowardsTo(target.Position);
#region 测试用,一定机会释放魔法/技能
if (attacker.Action == Actions.Casting) { return ; }
if (ObjectBase.RandomSeed.Next( 100 ) < ( int )slider13.Value) {
......
attacker.Casting(
new MagicArgs() {
Code
= code,
Level
= ObjectBase.RandomSeed.Next( 1 , 4 ),
SpaceLayer
= attacker.SpaceLayer,
Scale
= attacker.Scale,
Position
= attacker.Position,
Destination
= target.Position,
});
}
else {
attacker.Attack();
}
#endregion
......
}
else if (target.InCircle(attacker.Position, attacker.SightRange) || attacker.ActionAI == ActionAIs.Persistent) {
// 固执行为简单表现为抓住一个目标一直追击,直至自己或目标死亡为止
attacker.MoveTo( new Point(ObjectBase.RandomSeed.Next(( int )(target.Position.X - attacker.AttackRange), ( int )(target.Position.X + attacker.AttackRange)), ObjectBase.RandomSeed.Next(( int )(target.Position.Y - attacker.AttackRange), ( int )(target.Position.Y + attacker.AttackRange))));
}
else {
attacker.Target
= null ;
attacker.Stop();
}
}
}

  接下来是动作播放,角色控件内部播放施法动作,无论是2D还是3D模型,当播放到“放出”关键帧时解析魔法配置并触发DoCasting事件:

 
 
// 不同动作处理
switch (Action) {
case Actions.Attack:
if (frame.Current == frames.AttackEffect) {
if (DoAttack != null ) { DoAttack( this , e); }
}
break ;
case Actions.Casting:
if (frame.Current == frames.AttackEffect) {
if (DoCasting != null ) {
// 解析等级魔法具体参数
XElement info = Infos[ " Magic " ].DescendantsAndSelf( " Magics " ).Elements().Single(X => X.Attribute( " Code " ).Value == magicArgs.Code.ToString());
magicArgs.AnimationCode
= ( int )(info.Attribute( " AnimationCode " ));
magicArgs.MagicType
= (MagicTypes)( int )info.Attribute( " MagicType " );
magicArgs.MagicLayer
= (MagicLayers)( int )info.Attribute( " MagicLayer " );
magicArgs.MagicPosition
= (MagicPositions)( int )info.Attribute( " MagicPosition " );
magicArgs.AdditionalEffect
= (AdditionalEffects)( int )info.Attribute( " AdditionalEffect " );
magicArgs.SpecialEffect
= (SpecialEffects)( int )info.Attribute( " SpecialEffect " );
XElement levelInfo
= info.Element( " Levels " ).Elements().Single(X => X.Attribute( " ID " ).Value == magicArgs.Level.ToString());
magicArgs.DamageMin
= ( int )(levelInfo.Attribute( " DamageMin " ));
magicArgs.DamageMax
= ( int )(levelInfo.Attribute( " DamageMax " ));
magicArgs.Radius
= ( int )(levelInfo.Attribute( " Radius " ));
magicArgs.Number
= ( int )(levelInfo.Attribute( " Number " ));
DoCasting(
this , new DoCastingEventArgs() { MagicArgs = magicArgs });
}
}
break ;
}

  在角色所注册的DoCasting事件中通过反射来创建魔法实例并运行重写MagicBaseRun方法:

 
 
// 角色开始技能/魔法攻击
void role_DoCasting( object sender, DoCastingEventArgs e) {
RoleBase caster
= sender as RoleBase;
// 通过反射来加载并实例化各类型魔法
Assembly assembly = Assembly.Load( " Components,Version=1.0.0.0 " );
MagicBase magic
= assembly.CreateInstance( string .Format( " Components.Magic.{0} " , e.MagicArgs.MagicType.ToString())) as MagicBase;
magic.Run(caster, space, e.MagicArgs);
}

  依据魔法参数中的魔法类型,选择相应的具体魔法类执行具体逻辑,比如魔法实体及子魔法实体的创建、移动、特效显示、伤害处理等等,以一个圆形范围的群攻魔法为例,其逻辑组成代码如下: 

 
 
namespace Components.Magic {
/// <summary>
/// 圆形范围魔法
/// </summary>
public sealed class CircleMagic : MagicBase {

public override void Run(RoleBase caster, Space space, MagicArgs args) {
args.Position
= args.MagicPosition == MagicPositions.Position ? args.Position : args.Destination;
Point p
= space.Terrain.GetCoordinateFromPosition(args.Position);
if (space.Terrain.InEffectiveRange(p)) {
if ((args.S上海闵行企业网站制作paceLayer == SpaceLayers.Ground && space.Terrain.Matrix[( int )p.X, ( int )p.Y] != 0 ) || args.SpaceLayer == SpaceLayers.Sky) {
AnimationBase magic
= new AnimationBase() { Code = args.AnimationCode, SpaceLayer = args.SpaceLayer, Position = args.Position, Z = args.MagicLayer == MagicLayers.Ground ? - 1 : ( int )args.Position.Y };
EventHandler handler
= null ;
magic.Disposed
+= handler = delegate {
magic.Disposed
-= handler;
space.RemoveAnimation(magic);
};
space.AddAnimation(magic);
}
}
// space.Wave(args.Position);
for ( int i = space.AllRoles().Count - 1 ; i >= 0 ; i -- ) {
RoleBase target
= space.AllRoles()[i];
if (caster.IsHostileTo(target) && target.InCircle(args.Position, args.Radius * args.Scale)) {
Targets.Add(target);
}
}
// 对精灵表中所有精灵进行魔法/技能伤害
foreach (RoleBase role in Targets) {
caster.CastingToHurt(role, args);
}
Targets.Clear();
}

}
}

   一款网游能够吸引玩家的几大模块不外乎魔法、装备与探索;随着个人电脑性能跨越式飙升,当下网游更青睐以画面取悦玩家;没错,确实是屡试不爽。而魔法又是网游画面与体验的形象代言。可见,在网游开发中如能把握住魔法工序的每道细节,比如魔法与障碍的碰撞检测、动态运动轨迹、自适应及随机性、分帧处理架构、修饰及特效的组合布局等等,那么你的团队打造出一款世界顶级的网游必定指日可待,还在垂涎魔兽世界而望其项背吗?你也能做到的!

  再返回本文的开头,或许你会说这样的画面哪能和倩女幽魂Online比呀?

  请记住了,我们只是Silverlight Game Engine Developer,你懂的。Silverlight 5 目前已完美集成了XNA3D API,我相信如果您拥有一只美工水准堪称媲美雷火工作室的美术团队,使用Silverlight 5绝对能够研发出与之一拼的极品网游,甚至超越。

  创新工厂给当下国内网游的定义是“太重。没错,轻量化的网游正需要像Silverlight这样高研发效率、高性能、完全动态布局的RIA来实现;Silverlight 2.5D/3D网游时代已扬帆起航,4月28日,《WOWO世界》出中国乃至世界的第一步!所有的一切都是从零开始,完全自主的知识产权,完全自主研发的核心引擎、辅助工具,高度上海网站建设可维护性与拓展性,零外部依赖;俗话说的好:拽在自己手中的东西才最踏实,而Silverlight让我们开发者从心记忆着每个工序流程,没错,一切都属于你。我们可以面朝世界昂首呐喊:Silverlight 网游,中国造!

  这才是我们国人的骄傲!

  兵法曰:兵贵神速。不需要“十年一剑”,一年足矣。缔造的神话只有伴着酸甜苦辣走来的我们深刻体会。今日,当3D页游领域依旧仿若白纸一张时,我相信谁都迫切渴望通过最短的时间攻占世界前沿技术之巅峰!

  Silverlight 5 正预言着这么一个奇迹:中国的网游将在世界重新崛起,变革便在今朝!

  本节源码请到目录中下载

  在线演示地址:http://silverfuture.cn

目录
相关文章
|
2月前
|
关系型数据库 C# 数据库
.NET 8.0 开源在线考试系统(支持移动端)
【10月更文挑战第27天】以下是适用于 .NET 8.0 的开源在线考试系统(支持移动端)的简介: 1. **基于 .NET Core**:跨平台,支持多种数据库,前后端分离,适用于多操作系统。 2. **结合 Blazor**:使用 C# 开发 Web 应用,支持响应式设计,优化移动端体验。 3. **基于 .NET MAUI**:跨平台移动应用开发,一套代码多平台运行,提高开发效率。 开发时需关注界面设计、安全性与稳定性。
|
2月前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。
|
3月前
|
JSON 安全 数据安全/隐私保护
从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用
【9月更文挑战第22天】在.NET 8中,从零开始搭建权限管理系统并使用JWT(JSON Web Tokens)创建Token是关键步骤。JWT是一种开放标准(RFC 7519),用于安全传输信息,由头部、载荷和签名三部分组成。首先需安装`Microsoft.AspNetCore.Authentication.JwtBearer`包,并在`Program.cs`中配置JWT服务。接着,创建一个静态方法`GenerateToken`生成包含用户名和角色的Token。最后,在控制器中使用`[Authorize]`属性验证和解析Token,从而实现身份验证和授权功能。
160 3
|
4月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
51 8
|
4月前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
59 5
|
4月前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
184 0
|
4月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
54 0
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
44 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
65 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
49 0