XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
迈克·弗雷斯查尔 著
xna@return42.com
http://www.learnxna.com/pages/XNABook.aspx
第三章 输入控制
本章我们将学习游戏输入控制的基础。内容涵盖键盘、鼠标、游戏手柄的交互控制(即用手柄控制游戏和游
戏让控制手柄震动等)。同时你还会在本章中学习如何巧妙的定位和设置你的游戏的玩法。因为 Xbox 只支持手
柄输入,所以你的游戏支持何种输入设备你有以下四个选项:
1. 让游戏只支持 Xbox 360 和有 Xbox 360 兼容手柄的 PC;
2. 让游戏只支持带有键盘和鼠标的 PC(译者注:呵呵,有些老外买机子不买鼠标键盘只买游戏手柄,专
门用来玩游戏);
3. 既支持键盘鼠标也支持 Xbox 360 兼容手柄;
4. 用键盘和鼠标模拟 360 手柄以实现支持上述两种控制方法。
当然,每个选项都有自己的优缺点。
只支持与 Xbox360 兼容的游戏手柄
优点:
z 更简单、更容易;
z 一个控制方案让指令更简单;
z 所有的用户将会有同样的经历。
缺点:
z 只有拥有 Xbox360 类型手柄的用户才能玩游戏;
z 对更高级的控制方案或选项的访问变少了。
只支持键盘和鼠标
优点:
z 可以支持 100 多个按键;
z 与手柄相比,鼠标的控制更加精确;
z 包含“仅 Xbox360 兼容手柄”的所有优点。
缺点:
z 很明显,你的游戏不能在 Xbox 360 上运行,也不适合仅拥有 Xbox360 兼容手柄的 PC。
用两套代码实现既支持键盘鼠标也支持 Xbox360 兼容的手柄
优点:
z 为玩家提供最好的游戏环境;
z 能够最大限度的利用这两个系统;
z 提供最大的灵活性。
缺点:
z 使工作量加倍,所有代码须输入两次;
z 代码更多,更加复杂,更容易出现 bug。
用键盘和鼠标模拟 360 手柄以实现支持上述两种控制方法
第 1 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
优点:
z 最大化占有市场,不用 Xbox360 的兼容手柄也使游戏能在 Xbox 360 和 PC 上运行;
z 只用编写和维护一套代码;
z 比写两套代码简单一些。
缺点:
z 手柄的某些功能受限无法发挥。
本章,我们将学习如何独立使用键盘、鼠标以及手柄输入。在后续章节中我们将学习如何用鼠标和键盘来模
拟手柄。我希望你现在还不要对次期望过大,在你学会了本章所将的几种方法后,你定会想出适合你游戏的最佳
方案。
模板
个人简介word模板免费下载关于员工迟到处罚通告模板康奈尔office模板下载康奈尔 笔记本 模板 下载软件方案模板免费下载
代码
本章中所有的范例程序都建立在以下简单的代码基础之上的。这些代码是在黑色屏幕的中间画一个红球,这
个红球是简单的位图,不是透明的。
_________________________________________________________________________________________________________________
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Components;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace BasicGame
{
partial class BasicGame : Microsoft.Xna.Framework.Game
{
Texture2D _ballTexture;
SpriteBatch _spriteBatch;
Vector2 _ballPosition;
public BasicGame()
{
InitializeComponent();
_ballTexture = Texture2D.FromFile(graphics.GraphicsDevice,
"../../Graphics/ball.bmp");
_spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
// start the ball in the middle of the screen
int ballWidth = _ballTexture.Width;
int ballHeight = _ballTexture.Height;
int screenWidth = graphics.GraphicsDevice.Viewport.Width;
int screenHeight = graphics.GraphicsDevice.Viewport.Height;
_ballPosition = new Vector2(screenWidth / 2 - ballWidth / 2, screenHeight
/ 2 - ballHeight / 2);
第 2 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
}
protected override void Update()
{
}
protected override void Draw()
{
if (!graphics.EnsureDevice())
return;
graphics.GraphicsDevice.Clear(Color.Black);
graphics.GraphicsDevice.BeginScene();
DrawComponents();
_spriteBatch.Begin();
_spriteBatch.Draw(_ballTexture, _ballPosition, Color.White);
_spriteBatch.End();
graphics.GraphicsDevice.EndScene();
graphics.GraphicsDevice.Present();
}
void MoveSpriteLeft()
{
if (_ballPosition.X > 0)
_ballPosition.X -= 5;
}
void MoveSpriteRight()
{
if (_ballPosition.X < graphics.GraphicsDevice.Viewport.Width -
_ballTexture.Width)
_ballPosition.X += 5;
}
void MoveSpriteUp()
{
if (_ballPosition.Y > 0)
_ballPosition.Y -= 5;
}
void MoveSpriteDown()
{
if (_ballPosition.Y < graphics.GraphicsDevice.Viewport.Height -
_ballTexture.Height)
_ballPosition.Y += 5;
}
第 3 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
}
}
_____________________________________________________________________________________
此时你应该相当熟悉这些代码。本章我们所关注的关键之处就是Update()函数。现在,正如你所见,这个
函数中什么也没有。下面我们会在里面加一些东西。如果你上述代码中每一步都是正确的,那么程序运行的结果
就会如下图所示:
别激动!下面我们再让这个红球在屏幕上移动。在XNA中,游戏状态的驱动大部分是由输入完成的。每次你
检测手柄或键盘状态时,它都会告诉你它现在的内部状态。例如,如果你按下“A”键,它就会告诉你现在“A”
键被按下去了。然而,如果你想知道“A”键是否已经被释放,就需要继续跟踪上一次的状态。下面让我们看看
如何用键盘控制这个红球。
基本的键盘输入
正如我前面所讲,键盘是一种驱动游戏状态的设备。也就是说每次场景Update()被调用时,你就能获得键
盘当前的按键状态。如果你想跟踪某个按键的变化,则需要保存它上一次的读键状态。
在本章前面讲到的代码中做如下更改:
1.增加以下变量:
_____________________________________________________________________
List
_previousKeysDown;
_____________________________________________________________________
2.在构造函数增加下面一行:
_____________________________________________________________________
第 4 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
_previousKeysDown = new List();
_____________________________________________________________________
3.在Game类中增加如下功能:
_____________________________________________________________________
void HandleKey(Keys key)
{
// We are only processing each time any of the arrow keys are pressed down.
// If they were already held down, they are ignored until they are released.
switch (key)
{
case Keys.Left:
{
this.MoveSpriteLeft();
break;
}
case Keys.Right:
{
this.MoveSpriteRight();
break;
}
case Keys.Up:
{
this.MoveSpriteUp();
break;
}
case Keys.Down:
{
this.MoveSpriteDown();
break;
}
}
}
_____________________________________________________________________
4.最后,用以下代码替换Update()函数:
_____________________________________________________________________
protected override void Update()
{
// Check the current state of the keyboard
KeyboardState currentState = Keyboard.GetState();
// Get an array of all currently pressed keys
Keys[] currentlyPressed = currentState.GetPressedKeys();
第 5 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
// Loop through all keys that are currently being pressed
foreach (Keys key in currentlyPressed)
{
// If no keys where pressed last frame...
if (_previousKeysDown.Count == 0)
{
HandleKey(key);
}
else
{
// we need to loop through all the previously pressed keys to see if key
// state has changed
for (int i = 0; i < _previousKeysDown.Count; i++)
{
if (key == _previousKeysDown[i])
{
// this key was already pressed last frame, lets ignore it
}
else
{
HandleKey(key);
}
}
}
}
_previousKeysDown.Clear();
foreach (Keys key in currentlyPressed) _previousKeysDown.Add(key);
}
_____________________________________________________________________
做了上面的改动之后,游戏运行结果表示你可以用键盘上的方向键在屏幕上移动这个红球。每次当你按下一
个方向键时,这个红球就会在相应方向上移动5个像素。现在已经完成想做的事情了,让我们复习一下整个过程。
首先,将_previousKeysDown 这个变量成员和此行添加到构造函数中,它将会创建一个Keys类型的表,
这个表用来跟踪上一次的按键状态。
下面是HandleKeys()函数:
_____________________________________________________________________
void HandleKey(Keys key)
{
// We are only processing each time any of the arrow keys are pressed down.
// If they were already held down, they are ignored until they are released.
switch (key)
{
case Keys.Left:
{
第 6 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
this.MoveSpriteLeft();
break;
}
case Keys.Right:
{
this.MoveSpriteRight();
break;
}
case Keys.Up:
{
this.MoveSpriteUp();
break;
}
case Keys.Down:
{
this.MoveSpriteDown();
break;
}
}
}
_____________________________________________________________________________________
上述函数的扩展性很强。它接受一个表示按键的Keys类型的值作为参数,如果参数是方向键,它调用相应
的函数将精灵在指定的方向上移动。在Keys类型中对键盘上所有的键都定义了一个与其对应的值(包括许多你
没有见过的键,如F22键……)。
HandleKey()每次处理一个键,所以它处理组合键是安全的。比如,若Up和Left键同时被按下,则处理
它们时HandleKey()都会被调用(译者注:这时,精灵就会向左上方移动)。
游戏中主要工作都在Update()函数中完成,下面我们就详细看看它。
_________________________________________________________________________________________________
protected override void Update()
{
// Check the current state of the keyboard
KeyboardState currentState = Keyboard.GetState();
_________________________________________________________________________________________________
上述代码得到键盘当前的按键状态,就如同拍了一张照。哪个键被按下了呢?别急,先把按键状态保存到变
量currentState中,然后:
______________________________________________________________________
Keys[] currentlyPressed = currentState.GetPressedKeys();
______________________________________________________________________
这里定义了一个Keys类型的数组,然后保存当前按键状态。而Keys是表示键盘上所有键集合的一个枚举类
型。
当Update()被调用时,我们就得到了键盘上所有键的按键状态。
接下来,我们轮流处理每一个按下的键:
______________________________________________________________________
foreach (Keys key in currentlyPressed)
第 7 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
{
if (_previousKeysDown.Count == 0)
{
HandleKey(key);
}
else
{
for (int i = 0; i < _previousKeysDown.Count; i++)
{
if (key == _previousKeysDown[i])
{
// this key was already pressed last frame, lets ignore it
}
else
{
HandleKey(key);
}
}
}
}
______________________________________________________________________
这些代码实际上很有扩展性。每个键被压下时,我们都要检测:
z 在上一次 Update()被调用时,是否没有任何键被按下;
z 在上一次 Update()被调用时,该键是否已经被压下但还有被释放。
在上一次 Update()被调用时,如果没有压下任何键,我们就调用 HandleKey()函数。同时,在上一次
Update()被调用时,如果某键已经被压下但还有被释放,我们就可以忽略它。如果压下一个新键,仍然调用
HandleKey()函数。
注:
当按下一个方向键时,为什么我的精灵不移动呢?
其实这是故意设计的。有时你只想捕捉一个独立的按键动作。然而,如果你想每次按键时都能更新游戏,
删除 If(key==_previousKeysDown)后,当你按下方向键时,精灵就会平滑地在屏幕上移动了。
这些都是处理键盘输入的基础知识。如果你想检测组合键,比如想检测 ALT 键是否被压下,这很简单。如
在检测左方向被按下时,想检测 ALT是否被压下,可以进行如下操作:
________________________________________________________________________________________________
case Keys.Left:
{
if(Keys.Alt) // Do alt key processing
this.MoveSpriteLeft();
break;
}
第 8 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
________________________________________________________________________________________________
基本的鼠标输入
在 XNA 中,鼠标和键盘一样,都能驱动游戏的状态。对许多做 WinForms 编程的人来说,这个概念也许相当
陌生。每次当鼠标移动或按下按钮,是不是触发一个事件,这决于程序员如何控制鼠标当前的动作。在理论上,
对鼠标和键盘的处理很相似,你应该很容易就能理解的。
我们继续学习本章前面所讲到的模板程序。假设鼠标输入与键盘输入在本质上不一样,那么所做的事情也会
有一点不相同。我们设定红球跟随鼠标移动(事实上,像鼠标指针一样)。按下鼠标左键就会在屏幕上贴一个红球,
右击鼠标就将最后一次贴的红球删除。
请如下更改模板程序来捕获鼠标输入。
增加成员变量:
_________________________________________________________________________________________________
System.Collections.ArrayList _stampedSpriteLocations;
_________________________________________________________________________________________________
在构造函数结尾增加下面两行:
_________________________________________________________________________________________________
Mouse.WindowHandle = Window.Handle;
_stampedSpriteLocations = new System.Collections.ArrayList();
_________________________________________________________________________________________________
用如下代码替换 Update()方法:
_________________________________________________________________________________________________
protected override void Update()
{
MouseState state = Mouse.GetState();
_ballPosition.X = state.X;
_ballPosition.Y = state.Y;
if (state.LeftButton == ButtonState.Pressed)
AddImageStamp(state.X, state.Y);
if (state.RightButton == ButtonState.Pressed)
RemoveLastImageStamp();
}
_________________________________________________________________________________________________
增加以下两个函数:
_________________________________________________________________________________________________
private void AddImageStamp(int x, int y)
{
_stampedSpriteLocations.Add(new Vector2(x,y));
}
第 9 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
private void RemoveLastImageStamp()
{
if (_stampedSpriteLocations.Count > 0)
_stampedSpriteLocations.RemoveAt(_stampedSpriteLocations.Count - 1);
}
_________________________________________________________________________________________________
最 后 , 在 Draw() 中 的 _spriteBatch.Draw(_ballTexture, _ballPosition, Color.White); 之 后 和
_spriteBatch.End(); 之前加入以下代码:
_________________________________________________________________________________________________
foreach (Vector2 pos in _stampedSpriteLocations)
{
_spriteBatch.Draw(_ballTexture, pos, Color.White);
}
_________________________________________________________________________________________________
编译并运行程序,鼠标左键单击数次之后,你会看到:
红球会跟随鼠标移动,每当单击鼠标左键屏幕上就会多一个红球。而单击鼠标右键则会按与添加时相反的顺
序依次删除红球。怎么样,处理鼠标输入很简单吧。
下面让我们分析一下刚才所写的代码:
第 10 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
_________________________________________________________________________________________________
System.Collections.ArrayList _stampedSpriteLocations;
_________________________________________________________________________________________________
这里定义了一个动态数组来保存每一次单击鼠标左键时鼠标的位置。
_________________________________________________________________________________________________
Mouse.WindowHandle = Window.Handle;
_stampedSpriteLocations = new System.Collections.ArrayList();
_________________________________________________________________________________________________
上面第一行代码的意义是将鼠标与当前窗口关联起来。看起来这行是多余的(XNA 可能会自动帮你完成这项
工作),但是为安全起见,还是写上为好。第二行初始化了保存鼠标左击位置的数组。
下面是新的 Update()函数:
_________________________________________________________________________________________________
protected override void Update()
{
MouseState state = Mouse.GetState();
_ballPosition.X = state.X;
_ballPosition.Y = state.Y;
if (state.LeftButton == ButtonState.Pressed)
AddImageStamp(state.X, state.Y);
if (state.RightButton == ButtonState.Pressed)
RemoveLastImageStamp();
}
_________________________________________________________________________________________________
类似之前对键盘的处理,每次 Update()被调用时,我们都需要在其里面将鼠标的 X 坐标与 Y 坐标(相对当
前窗口的左上角)保存到局部变量里。
下一步我们检测当前鼠标左键是否被按下。如果按下的话,将当前鼠标的坐标作为参数传递给新创建的函数
AddImagesStamp()。紧接着,检测右键是否被按下。如果按下,则调用 RemoveLastImageStamp()。注意:无论
你按下左键还是右键,这两个函数都会被多次调用。
这两个函数如下:
_________________________________________________________________________________________________
private void AddImageStamp(int x, int y)
{
_stampedSpriteLocations.Add(new Vector2(x,y));
}
private void RemoveLastImageStamp()
{
if (_stampedSpriteLocations.Count > 0)
_stampedSpriteLocations.RemoveAt(_stampedSpriteLocations.Count - 1);
}
_________________________________________________________________________________________________
如单击鼠标左键,会调用 AddImageStamp()在数组中增加一个表示所画红球位置的 Vector2 对象。如单击右
键,则会检查数组_stampedSpriteLocations 中是否有该对象,若有则删除最后一个。而多次右击则会删除多个
对象。
第 11 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
最后我们将所有的球画在屏幕上:
_________________________________________________________________________________________________
foreach (Vector2 pos in _stampedSpriteLocations)
{
_spriteBatch.Draw(_ballTexture, pos, Color.White);
}
_________________________________________________________________________________________________
对于_stampedSpriteLocations 中的每一个位置,我们都在屏幕上绘制一个红球。应该记住这些代码必须放
在 SpriteBatch.Start()和 SpriteBatch.End()之间。
注:
当游戏以窗口模式运行时,既使鼠标已经超出游戏窗口范围,XNA 也不会提示。而在全屏模式下,将不会
出现这个问题。比如,鼠标已经移到窗口左边很远的地方,而程序中得到的 X 坐标一直是 0。这虽然可以通过
代码来来避免,但确实也是一个问题。
基本的手柄输入
首先你需要一个兼容的游戏手柄才能运行下边的示例代码。获取手柄的输入同获取键盘输入一样都需要轮流
检测按键状态,所以以下代码同获取键盘输入的代码几乎一样,只有 Update()中的代码有变化,如下:
_________________________________________________________________________________________________
protected override void Update()
{
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);
if (currentGamePadState.IsConnected == true)
{
if (currentGamePadState.DPad.Left == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.X < 0)
this.MoveSpriteLeft();
if (currentGamePadState.DPad.Right == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.X > 0)
this.MoveSpriteRight();
if (currentGamePadState.DPad.Down == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.Y < 0)
this.MoveSpriteDown();
if (currentGamePadState.DPad.Up == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.Y > 0)
this.MoveSpriteUp();
if (currentGamePadState.Buttons.A == ButtonState.Pressed)
_ballPosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 -
第 12 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
_ballTexture.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2 -
_ballTexture.Height / 2);
}
}
_________________________________________________________________________________________________
上述代码和处理键盘输入的代码作用相同。但不同的是:没有用方向键控制小球的移动,而是用手柄左边的
方向摇杆或者方向按键。同时,任何时候你按下手柄上的 A 键,小球都会回到屏幕中央。
编译并运行后,你会看到类似下边的画面:
让我回过头来看看上述代码:
_________________________________________________________________________________________________
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);
if (currentGamePadState.IsConnected == true)
_________________________________________________________________________________________________
Update()函数被调用时,得到游戏手柄当前的按键状态。这就可以知道手柄上的方向摇杆正在被扳向哪个方
向以及哪个按键被键下等等。但这里和处理键盘的代码最重要的区别就是:调用 GetState()时有一个参数
PlayerIndex。
什么是 PlayerIndex 呢?就像许多拥有 Xbox 360 的玩家一样,你可以同时给系统安装 4 个游戏手柄。
PlayerIndex 可以枚举表示这四个手柄的枚举值:One、Two、Three、Four 以及 Any。在程序中要处理哪个手柄
第 13 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
你可以通过它来指定。可以用枚举值 Any 来响应任何一个手柄的操作,如按下 Start 键暂停游戏。
下面一行if (currentGamePadState.IsConnected == true) 用来判断游戏开始时安装的手柄是否连接正常,
因为即使是在无线游戏手柄被广泛使用的今天,这种情况还会经常发生。如果你像我一样经常遇到这种情况,也
不要感到惊讶,因为大多数人和我们一样。如果检测到手柄没有连接,应该暂停游戏并弹出一个消息:“Controller
X was just unplugged”,以等待玩家重新连接手柄。
_________________________________________________________________________________________________
{
if (currentGamePadState.DPad.Left == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.X < 0)
this.MoveSpriteLeft();
if (currentGamePadState.DPad.Right == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.X > 0)
this.MoveSpriteRight();
if (currentGamePadState.DPad.Down == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.Y < 0)
this.MoveSpriteDown();
if (currentGamePadState.DPad.Up == ButtonState.Pressed ||
currentGamePadState.ThumbSticks.Left.Y > 0)
this.MoveSpriteUp();
_________________________________________________________________________________________________
假设手柄连接正常,接下来检测手柄上的摇杆或方向键的操作,如果他们都像左(译者注:即摇杆被扳向左
边,或者左方向键被按下),就把精灵向左移动;同样如果它们都向右,则把精灵向右移动。依次类推。
有没有注意到摇杆的检测和方向键检测的区别?方向键的检测结果是一个 BOOL 值,要么按下要么没有按下。
然而,摇杆的检测结果则是一个数值。为什么呢?
摇杆的检测结果是一个连续变化的数值,也就是说它并不是开或关这么简单的事情。例如,
currentGamePadState.ThumbSticks.Left.X 值的范围是从-1.0到+1.0。-1.0表示摇杆一直被扳向左方,而+1.0
则表示被扳向右方。0表示摇杆既没有被扳向左也没有被扳向右。在游戏对速度或压力处理的灵敏度方面,负数
越小表示向左移动越快或向左扳动时需要更大的力,而正数越大则表示向右移动越快或向右扳动时需要更大的
力。因此,如果currentGamePadState.ThumbSticks.Left.X的值是-0.3,表示玩家向左扳动摇杆时只用了30%的
力。
如果你创建的是一个3D游戏,那么你应该处理玩家在Y轴上的操作。如果你创建第一人称射击游戏,don’t
give me the option to make pushing down the same as looking up, 那么我是不会购买你的游戏的,因为这
些FPS游戏的操作机制早已植入了玩家们的大脑,不可能改变。
_____________________________________________________________________________________
if (currentGamePadState.Buttons.A == ButtonState.Pressed) _
ballPosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 -
_ballTexture.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2 -
_ballTexture.Height / 2);
}
}
第 14 页 共 17 页
XNA 入门指南 —— 迈克·弗雷斯查尔 著
http://www.XnaDev.cn 中国 XNA 开发网 译
______________________________________________________________________________________________________
上面代码意为:如果玩家按下手柄上的 A 键,则将红球移到屏幕中央。
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
本章将述了游戏中对键盘、鼠标、手柄输入的处理以及这三种处理之间的明显区别,也算是你写游戏的一个
良好的起点。在以后,我们将会更详细地讲述手柄的输入处理,同样也会用示例代码讲述对所有输入设备的处理。
而下一章将会讲述音频处理,也可能会将到许多读者要求的 3D 方面的知识。
法律许可
下面是和法律相关的内容。本书中的所有术语和版权均归其原公司所有。我,迈克·弗雷斯查尔,愿意让所
有人都能分享本书。你可以以任何方式保留和发布本书。但是,未经书面许可,请勿修改。除了发布本书的网站
上的广告所得之外,严禁转售或从本书中谋利。为尊重作者,请在发布时注明作者(译者注:同时,为尊重译者,
请发布时也注明“由中国XNA开发网http://www.XnaDev.cn 翻译”)。任何时间都有权撤销上述许可。
Mech Commander 2 最终用户许可
协议
离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载
使用 Mech Commander 2 共享资源的受限许可证书
这个许可控制你对此游戏软件的使用。如果你使用此游戏,你就要接受此协议。相反,如果你不接受此协议,
那么你就不能使用此游戏。
1. 定义
(A) “翻印”、“转载”、“发布”这三个词在美国版权法中意义相同。
(B) “你”,指获得此游戏软件许可的人。
(C) “已注册的专利”,指本许可协议中,在微软公司已发行的软件上直接注明的微软专利。
2. 授权
(A). 版权的授予——这取决于本许可协议中的相关术语,包括下面第三部分的条件和限制。你可以复制、
传播此游戏,编写此游戏的派生作品(译者注:即通过对原游戏的增删改而制作的游戏,下同),
以及发布该游戏或此游戏的派生作品,因为微软授予了你一个非独家的(译者注:即并非只有你一
个人所拥有的,下同)、世界范围内的、无版税的版权许可。
(B). 专利权的授予——这取决于本许可协议中的相关术语,包括下面第三部分的条件和限制。你可以制
作、完成、使用、学习、销售、代售和(或)对其他此游戏或此游戏的派生作品的处理,因为微软
授予了你一