您的位置:首页 > 编程语言 > C#

Silverlight.XNA(C#)跨平台3D游戏研发手记:(十)3D 场景与控制设计①

2012-05-23 17:33 429 查看
模型和骨骼动画仅仅是开启3D游戏的敲门砖,置入基于摄像机的场景设计方能呈现最完美的3D游戏。本节,我们依旧从简单着手,一步步创建基于模型的3D游戏场景。

XNA4.0学习指南(中文)》是一本绝对值得一看的好书,对于3D游戏的基础知识、概念以及简单应用讲解非常全面。比如书中提到关于XNA内置了创建摄像机的方案代码,根据该提示我们便可轻松实现一个名为Camera3D的类:

虚拟拇指摇杆

/// <summary>
/// 基于虚拟拇指摇杆的控制器
/// </summary>
public sealed class Controller : Object2D {

Texture2D rtexture, ltexture, backStick;
const int maxThumbstickDistance = 50;
const int distanceThumbsticks = 50;
Vector2 rightCornerPosition, leftCornerPosition;
Vector2 rightBackStick, leftBackStick;
Vector2 rightPosition, leftPosition;
Vector2 rightThumbstickCenter, leftThumbstickCenter;

public Controller(ContentManager content, Vector2 size)
: base(content) {
backStick = content.Load<Texture2D>("Image/BackgroundStick");
rtexture = content.Load<Texture2D>("Image/RStick");
ltexture = content.Load<Texture2D>("Image/LStick");
Vector2 middleTexture = new Vector2(rtexture.Width / 2, rtexture.Height / 2);

rightThumbstickCenter = new Vector2(size.X - distanceThumbsticks - middleTexture.X, size.Y - distanceThumbsticks - middleTexture.Y);
leftThumbstickCenter = new Vector2(distanceThumbsticks + middleTexture.X, size.Y - distanceThumbsticks - middleTexture.Y);

rightCornerPosition = rightThumbstickCenter - middleTexture;
leftCornerPosition = leftThumbstickCenter - middleTexture;

rightBackStick = rightCornerPosition - new Vector2(distanceThumbsticks, distanceThumbsticks);
leftBackStick = leftCornerPosition - new Vector2(distanceThumbsticks, distanceThumbsticks);
}

/// <summary>
/// 获取或设置操作模式(精确度)
/// </summary>
public ControlModes ControlMode { get; set; }

/// <summary>
/// 获取或设置左侧虚拟拇指摇杆位置
/// </summary>
public Vector2 LeftThumbstick {
get {
//缩放向量计算触摸位置的中心,缩放最大摇杆距离
Vector2 l = (leftPosition - leftThumbstickCenter) / maxThumbstickDistance;
//如果长度大于1,转化为单位矢量
if (l.LengthSquared() > 1f) { l.Normalize(); }
return l;
}
}

/// <summary>
/// 获取或设置右侧虚拟拇指摇杆位置
/// </summary>
public Vector2 RightThumbstick {
get {
Vector2 l = (rightPosition - rightThumbstickCenter) / maxThumbstickDistance;
if (l.LengthSquared() > 1f) { l.Normalize(); }
return l;
}
}

public override void Update(GameTimerEventArgs e) {
TouchLocation? leftTouch = null, rightTouch = null;
TouchCollection touches = TouchPanel.GetState();
foreach (TouchLocation touch in touches) {
switch (ControlMode) {
case ControlModes.Accurate:
if (Math.Pow((touch.Position.X - leftThumbstickCenter.X), 2) + Math.Pow((touch.Position.Y - leftThumbstickCenter.Y), 2) <= Math.Pow(backStick.Width / 2, 2)) {
leftTouch = touch;
leftPosition = touch.Position;
continue;
}
if (Math.Pow((touch.Position.X - rightThumbstickCenter.X), 2) + Math.Pow((touch.Position.Y - rightThumbstickCenter.Y), 2) <= Math.Pow(backStick.Width / 2, 2)) {
rightTouch = touch;
rightPosition = touch.Position;
continue;
}
break;
case ControlModes.Rough:
if (touch.Position.X <= TouchPanel.DisplayWidth / 2 && touch.Position.Y >= TouchPanel.DisplayHeight / 3) {
leftTouch = touch;
leftPosition = touch.Position;
continue;
}
if (touch.Position.X > TouchPanel.DisplayWidth / 2 && touch.Position.Y >= TouchPanel.DisplayHeight / 3) {
rightTouch = touch;
rightPosition = touch.Position;
continue;
}
break;
}
if (leftTouch.HasValue && rightTouch.HasValue) { break; }
}
if (!leftTouch.HasValue) { leftPosition = leftThumbstickCenter; }
if (!rightTouch.HasValue) { rightPosition = rightThumbstickCenter; }
}

public override void Draw(GameTimerEventArgs e, SpriteBatch spriteBatch) {
if (RightThumbstick.Length() > 0) {
spriteBatch.Draw(backStick, rightBackStick, Color.White);
}
spriteBatch.Draw(rtexture, rightCornerPosition + RightThumbstick * distanceThumbsticks, Color.White);
if (LeftThumbstick.Length() > 0) {
spriteBatch.Draw(backStick, leftBackStick, Color.White);
}
spriteBatch.Draw(ltexture, leftCornerPosition + LeftThumbstick * distanceThumbsticks, Color.White);
}

}
}

在本节的Demo中,左手遥控杆用于移动角色。需要说明一点,基于XNA右手坐标系下,一个场景模型从3DMAX中默认坐标系中导入进游戏,角色若要在其表面上移动,改变的不是X、Y值,而是X、Z值,Y值代表实际高低深度,这与后面章节将要讲到的HeightMap有很大区别:



右手遥控杆则用来旋转摄像机和角色(模拟PC中的鼠标右键按住不放时的场景旋转功能),实际游戏开发中大家可以在此基础上作更进一步设计,比如单击、双击、长时按压以实现主角攻击、射击、特技、魔法等行为,使得遥控杆功能得以最大化,满足游戏更多的操控需求:



本节源码中集成了EngineNine源码的核心部分,源码下载地址:(WP)SLXnaGame2

手记小结:本节主要讲解了基于不同视角的3D场景搭建以及传统的基于遥控杆的游戏操控功能实现,也算是非常简单的3D游戏开发入门级场景设计知识。后续章节我将在本节源码的基础上进行深度拓展,通过搭建出各种类型的经典3D游戏Demo案例向大家展示SL.XNA在跨平台3D游戏开发方面的强大与高效,敬请关注。

推荐参考:NowpaperWilliams关于Windows Phone的游戏开发博客。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐