↑↓可前後移動蠍子
遊戲程式碼下載連結!!
http://webhd.xuite.net/_oops/a88488869/48q主程式部份
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace WindowsGame1
{
///
/// This is the main type for your game
/// public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
GameComponentNPC_Evade NPC_01;
GameComponentNPC_RotationY NPC_02;
InspectionCamera camera;
GameComponent_Grid Grid;
GameComponent_PC PC_01;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.IsMouseVisible = true;
this.Window.Title = "A、D、W、S、Z、X、Space 鍵;↑、↓、← 鍵";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
NPC_01 = new GameComponentNPC_Evade(this, Content.Load
("tortoise"));
Components.Add(NPC_01); // 由這裡 加入 DrawableGameComponent
camera = new InspectionCamera(this);
camera.cameraRotationX = 30;
this.Components.Add(camera);
Grid = new GameComponent_Grid(this);
this.Components.Add(Grid);
NPC_02 = new GameComponentNPC_RotationY(this, Content.Load("weapon5"));
NPC_02.World = Matrix.CreateScale(0.01f);
Components.Add(NPC_02); // 由這裡 加入 DrawableGameComponent
PC_01 = new GameComponent_PC(this, Content.Load("001"));
this.Components.Add(PC_01); // 由這裡 加入 DrawableGameComponent
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
NPC_01.EvadePosition = PC_01.Position;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
NPC_01.View = camera.view;
NPC_01.Projection = camera.projection;
Grid.view = camera.view;
Grid.projection = camera.projection;
NPC_02.View = camera.view;
NPC_02.Projection = camera.projection;
PC_01.View = camera.view;
PC_01.Projection = camera.projection;
base.Draw(gameTime);
}
}
}
烏龜副程式部份
namespace WindowsGame1
{
///
/// This is a game component that implements IUpdateable.
///
public class GameComponentNPC_Evade : Microsoft.Xna.Framework.DrawableGameComponent
{
Model myModel; //宣告一個 模型物件 全域變數
Matrix[] transforms; // 宣告一個 骨架轉換矩陣 全域變數
//public Matrix World = Matrix.Identity;
public float Scale = 0.02f; // 3D 模型的縮放比例
public Vector3 Position = new Vector3(3, 0, 0); // 開始位置
public float Yaw = 0; // 目前的徑度
public float Yaw_initial = 0; // 開始的Y軸旋轉矯正徑度
public Vector3 Wander_Center = new Vector3(0, 0, 0); // 漫遊的中心點
public float Wander_Radius = 4; // 漫遊的半徑距離
public Matrix View = Matrix.CreateLookAt(new Vector3(0.0f, 2.0f, 2.0f),
Vector3.Zero,
Vector3.Up);
public Matrix Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
1.333f, 1.0f, 10000.0f);
Random rd = new Random();
public Vector3 EvadePosition = new Vector3(3, 0, 0); // 閃躲的位置
public float EvadeRadius = 2; // 開始閃躲的半徑距離
public float CaughtRadius = 0.6f; // 已經被追逐到的距離
public GameComponentNPC_Evade(Game game, Model model)
: base(game)
{
// TODO: Construct any child components here
myModel = model;
}
///
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
///
public override void Initialize()
{
// TODO: Add your initialization code here
transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);
base.Initialize();
}
///
/// Allows the game component to update itself.
/// ///
Provides a snapshot of timing values.
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
Vector3 vectorToCenter = Wander_Center - Position;
float len = Vector3.Distance(Wander_Center, Position);
Vector3 vectorToChase = EvadePosition - Position;
float ChaseLen = Vector3.Distance(EvadePosition, Position);
if (ChaseLen < EvadeRadius)
{
float Yaw2 = (float)Math.Atan2(vectorToChase.X, vectorToChase.Z) +
MathHelper.Pi;
float diff = Yaw2 - Yaw;
while (diff < -MathHelper.Pi) diff += MathHelper.TwoPi;
while (diff > MathHelper.Pi) diff -= MathHelper.TwoPi;
float r = 0.02f * MathHelper.Pi;
diff = MathHelper.Clamp(diff, -r, r);
Yaw = Yaw + diff;
while (Yaw < -MathHelper.Pi) Yaw += MathHelper.TwoPi;
while (Yaw > MathHelper.Pi) Yaw -= MathHelper.TwoPi;
if (ChaseLen > CaughtRadius)
{
Vector3 step = new Vector3(0, 0, 0.01f);
Position += Vector3.Transform(step, Matrix.CreateRotationY(Yaw));
}
}
else
{
if (len > Wander_Radius)
{
float Yaw2 = (float)Math.Atan2(vectorToCenter.X, vectorToCenter.Z);
float diff = Yaw2 - Yaw;
float r = 0.01f * MathHelper.Pi * len / Wander_Radius;
//float r = 0.01f * MathHelper.Pi;
diff = MathHelper.Clamp(diff, -r, r);
Yaw = Yaw + diff;
}
else
Yaw += MathHelper.Lerp(-0.05f, 0.05f, (float)rd.NextDouble());
while (Yaw < -MathHelper.Pi) Yaw += MathHelper.TwoPi;
while (Yaw > MathHelper.Pi) Yaw -= MathHelper.TwoPi;
Vector3 step = new Vector3(0, 0, 0.01f);
Position += Vector3.Transform(step, Matrix.CreateRotationY(Yaw));
}
base.Update(gameTime);
}
//protected override void Draw(GameTime gameTime)
public override void Draw(GameTime gameTime)
{
foreach (ModelMesh mesh in myModel.Meshes)
{
// 設定網格的呈現效果 (世界、觀測、投影矩陣)
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateScale(Scale) *
Matrix.CreateRotationY(Yaw_initial) *
Matrix.CreateRotationY(Yaw ) *
Matrix.CreateTranslation(Position);
effect.View = View;
effect.Projection = Projection;
}
// 畫出在 模型 中的 某一個 網格
mesh.Draw();
}
}
}
}
蠍子副程式部份
namespace WindowsGame1
{
///
/// This is a game component that implements IUpdateable.
///
public class GameComponentNPC_RotationY : Microsoft.Xna.Framework.DrawableGameComponent
{
Model myModel; //宣告一個 模型物件 全域變數
Matrix[] transforms; // 宣告一個 骨架轉換矩陣 全域變數
public Matrix World = Matrix.Identity;
public Matrix View = Matrix.CreateLookAt(new Vector3(0.0f, 2.0f, 2.0f),
Vector3.Zero,
Vector3.Up);
public Matrix Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
1.333f, 1.0f, 10000.0f);
float RotationY = 0;
public GameComponentNPC_RotationY(Game game, Model model)
: base(game)
{
// TODO: Construct any child components here
myModel = model;
}
///
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
///
public override void Initialize()
{
// TODO: Add your initialization code here
transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);
base.Initialize();
}
///
/// Allows the game component to update itself.
/// ///
Provides a snapshot of timing values.
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
RotationY += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
base.Update(gameTime);
}
//protected override void Draw(GameTime gameTime)
public override void Draw(GameTime gameTime)
{
foreach (ModelMesh mesh in myModel.Meshes)
{
// 設定網格的呈現效果 (世界、觀測、投影矩陣)
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(MathHelper.ToRadians(RotationY)) *
World;
effect.View = View;
effect.Projection = Projection;
}
// 畫出在 模型 中的 某一個 網格
mesh.Draw();
}
}
}
}
方格地板副程式
namespace WindowsGame1
{
///
/// This is a game component that implements IUpdateable.
///
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent
{
public int gridSize = 12; // 每邊有 幾格
public float gridScale = 1.0f; // 每格 的 寬
public Color gridColor = new Color(0xFF, 0xFF, 0xFF, 0xFF); // 格線 的顏色 內定是黑色
VertexBuffer vertexBuffer; // 頂點緩衝區
VertexDeclaration vertexDeclaration; // 頂點格式 (每個頂點 包含什麼內容)
BasicEffect effect; // 產出時會用到的 效果
int vertexCount; // 頂點 數目
GraphicsDevice device; //繪圖設備
public Matrix world = Matrix.Identity; // 世界 觀測 投影 矩陣
public Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 20.0f, 20.0f),
Vector3.Zero,
Vector3.Up);
public Matrix projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
1.333f, 1.0f, 10000.0f);
public GameComponent_Grid(Game game)
: base(game)
{
// TODO: Construct any child components here
this.device = game.GraphicsDevice;
}
///
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
///
public override void Initialize()
{
// TODO: Add your initialization code here
effect = new BasicEffect(device, null); // 效果
vertexCount = (gridSize + 1) * 4; // 每邊的頂點數 比 每邊的格數 多一,共有四個邊
// 每個頂點 包含 位置 和 顏色 ,先空出 vertexCount 個 頂點
VertexPositionColor[] vertices = new VertexPositionColor[vertexCount];
float length = (float)gridSize * gridScale; // 邊長 等於 格數 乘以 格寬
float halfLength = length * 0.5f; // 半邊長 因為是要 以原點為中心 左右 各半
int index = 0; // 頂點 索引
// 定義頂點位置 頂都是 躺在 X Z 平面上
for (int i = 0; i <= gridSize; ++i)
{
vertices[index++] = new VertexPositionColor(
new Vector3(-halfLength, 0.0f, i * gridScale - halfLength),
gridColor); // 左邊的頂點
vertices[index++] = new VertexPositionColor(
new Vector3(halfLength, 0.0f, i * gridScale - halfLength),
gridColor); // 右邊的頂點
vertices[index++] = new VertexPositionColor(
new Vector3(i * gridScale - halfLength, 0.0f, -halfLength),
gridColor); // 上緣的頂點
vertices[index++] = new VertexPositionColor(
new Vector3(i * gridScale - halfLength, 0.0f, halfLength),
gridColor); // 下緣的頂點
}
// 建立 頂點緩衝區
vertexBuffer = new VertexBuffer(device, vertexCount * VertexPositionColor.SizeInBytes,
BufferUsage.WriteOnly);
// 將 頂點資料 複製入 頂點緩衝區 內
vertexBuffer.SetData(vertices);
// 頂點格式
vertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
base.Initialize();
}
///
/// Allows the game component to update itself.
/// ///
Provides a snapshot of timing values.
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
// 效果 三大矩陣 設定
effect.World = world;
effect.View = view;
effect.Projection = projection;
effect.VertexColorEnabled = true; // 使用 頂點顏色 效果
device.VertexDeclaration = vertexDeclaration; // 頂點格式
device.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes); // 頂點來源
effect.Begin(); // 效果 開始
foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes)
{
CurrentPass.Begin();
device.DrawPrimitives(PrimitiveType.LineList, 0, vertexCount / 2); // 兩兩畫線 所以只有 vertexCount/2 條線
CurrentPass.End();
}
effect.End();
}
}
}
神劍副程式部份
namespace WindowsGame1
{
///
/// This is a game component that implements IUpdateable.
///
public class GameComponent_PC : Microsoft.Xna.Framework.DrawableGameComponent
{
Model myModel; //宣告一個 模型物件 全域變數
Matrix[] transforms; // 宣告一個 骨架轉換矩陣 全域變數
public Vector3 FrontVector = new Vector3(0, 0, 1); //3D 物件的 往前向量
public Vector3 Position = new Vector3(0.0f, 0.0f, 0.0f); // 3D 物件的 位置
public float Yaw = 0.0f; // 第一人稱的Y軸旋轉角度
public float YawDelta = 100.0f; // 旋轉角度 的 增減量
public float MoveDelta = 2; // 前後走 的 增減量
public Matrix View = Matrix.CreateLookAt(new Vector3(0.0f, 20.0f, 20.0f),
Vector3.Zero,
Vector3.Up);
public Matrix Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
1.333f, 1.0f, 10000.0f);
public GameComponent_PC(Game game, Model model)
: base(game)
{
// TODO: Construct any child components here
myModel = model;
}
///
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
///
public override void Initialize()
{
// TODO: Add your initialization code here
transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);
base.Initialize();
}
///
/// Allows the game component to update itself.
/// ///
Provides a snapshot of timing values.
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
KeyboardState newState; // 宣告一個KeyboardState 結構的變數
newState = Keyboard.GetState(); //得到目前鍵盤每一個按鍵的狀況
if (newState.IsKeyDown(Keys.Right)) Yaw -= YawDelta * elapsedTime; //判斷Right鍵是否已經被按下
if (newState.IsKeyDown(Keys.Left)) Yaw += YawDelta * elapsedTime; //判斷Left鍵是否已經被按下
if (newState.IsKeyDown(Keys.Up)) //判斷Up鍵是否已經被按下
{
Position += Vector3.Transform(-MoveDelta * elapsedTime * FrontVector,
Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)));
}
if (newState.IsKeyDown(Keys.Down)) //判斷Down鍵是否已經被按下
{
Position += Vector3.Transform(MoveDelta * elapsedTime * FrontVector,
Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)));
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
foreach (ModelMesh mesh in myModel.Meshes)
{
// 設定網格的呈現效果 (世界、觀測、投影矩陣)
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateScale(0.01f) *
Matrix.CreateRotationY(MathHelper.ToRadians(Yaw)) *
Matrix.CreateTranslation(Position); //
effect.View = View;
effect.Projection = Projection;
}
// 畫出在 模型 中的 某一個 網格
mesh.Draw();
}
}
}
}