|
タクヤ「第4回のように、テキストエディタで『Tag.xaml』を開いて全て選択コピーし、『Window1.xaml』の『Grid』タグの間に貼り付けて、『デバッグ>実行』メニューで剣士キャラと魔女キャラと地面が現れました。 前回のを応用して、魔女キャラも凹凸地形にあうようコーディングしました」
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//3Dが使えるようにする
using System.Windows.Media.Media3D;//追加
//タイマーが使えるようにする
using System.Windows.Threading;//追加
namespace WpfApplication3
{
/// summary
/// Window1.xaml の相互作用ロジック
/// summary
public partial class Window1 : Window
{
//タイマー
private DispatcherTimer intervalTimer = new DispatcherTimer();
//剣士キャラの位置
Vector3D pos = new Vector3D(1000, 0, 1000);
//剣士キャラの向き
float angle = 0;
//魔女キャラの位置
Vector3D pos2 = new Vector3D(0, 0, 0);
//魔女キャラの向き
float angle2 = 200;
public Window1()
{
InitializeComponent();
//30ミリ秒ごとに、『Update3DEvent』関数を呼び出す
intervalTimer.Interval = TimeSpan.FromMilliseconds(30);
intervalTimer.Tick += new EventHandler(Update3DEvent);
intervalTimer.Start();
}
//30ミリ秒ごとに呼ばれる関数
void Update3DEvent(object sender, EventArgs e)
{
//カメラ位置
Camera_Tag.Position =
new Point3D(pos.X + 3000, pos.Y + 1000, pos.Z + 3000);
//カメラの向き
Camera_Tag.LookDirection = new Vector3D(-3, -0.9, -3);
SwordsmanMove();
WitchMove();
}
//剣士キャラの操作はこちらに移転
private void SwordsmanMove()
{
if (Keyboard.IsKeyDown(Key.Right))
{
//キャラの角度を減算
angle -= 10;
//0度を下回ったら360度加算
if (angle < 0)
{
angle += 360;
}
}
if (Keyboard.IsKeyDown(Key.Left))
{
//キャラの角度を加算
angle += 10;
//1回転したら360度減算
if (angle >= 360)
{
angle -= 360;
}
}
//ディグリーからラジアンへ変換
float radian = toRadian(angle);
if (Keyboard.IsKeyDown(Key.Up))
{
//向いた方向へXとZ座標を加算
pos.X += (float)(Math.Sin(radian) * 10);
pos.Z += (float)(Math.Cos(radian) * 10);
}
if (Keyboard.IsKeyDown(Key.Down))
{
//向いた方向へXとZ座標を減算
pos.X -= (float)(Math.Sin(radian) * 10);
pos.Z -= (float)(Math.Cos(radian) * 10);
}
//3D行列
Matrix3D m = new Matrix3D();
//回転
Quaternion q = new Quaternion(new Vector3D(0, 1, 0), angle);
//回転を3D行列にセット
m.Rotate(q);
//3D行列に平行移動した位置posをセット
m.OffsetX = pos.X;
m.OffsetY = pos.Y;
m.OffsetZ = pos.Z;
//3D行列を3D変形行列にセット
MatrixTransform3D trans = new MatrixTransform3D(m);
//剣士キャラに移動した変形行列をセット
Character_Tag_Swordsman.Transform = trans;
//地面と当たり判定
//pointはキャラの位置
Point3D point = new Point3D(pos.X, pos.Y, pos.Z);
//剣士のレイの向き
Vector3D dir = new Vector3D(0, -1, 0);
//剣士キャラの位置からのレイのセット
RayHitTestParameters rayparams = new RayHitTestParameters(point, dir);
//レイが地面Character_Grass_Grassにヒットしたら
//ResultsOfHit関数を呼び出すようにセット
VisualTreeHelper.HitTest(
Character_Tag_Grass, null,
new HitTestResultCallback(ResultsOfHit), rayparams);
}
private void WitchMove()
{
//3D行列
Matrix3D m = new Matrix3D();
//回転
Quaternion q = new Quaternion(new Vector3D(0, 1, 0), angle2);
//回転を3D行列にセット
m.Rotate(q);
//3D行列に平行移動した位置posをセット
m.OffsetX = pos2.X;
m.OffsetY = pos2.Y;
m.OffsetZ = pos2.Z;
//3D行列を3D変形行列にセット
MatrixTransform3D trans = new MatrixTransform3D(m);
//魔女キャラに移動した変形行列をセット
Character_Tag_Witch.Transform = trans;
//魔女キャラを高い位置から地面と当たり判定
pos2.Y = 1000;
//pointはキャラの位置
Point3D point = new Point3D(pos2.X, pos2.Y, pos2.Z);
//魔女のレイの向き
Vector3D dir = new Vector3D(0, -1, 0);
//魔女キャラの位置からのレイのセット
RayHitTestParameters rayparams = new RayHitTestParameters(point, dir);
//レイが地面Character_Tag_Grassにヒットしたら
//ResultsOfHit2関数を呼び出すようにセット
VisualTreeHelper.HitTest(
Character_Tag_Grass, null,
new HitTestResultCallback(ResultsOfHit2), rayparams);
}
//地面と剣士キャラとの距離だけY座標を移動
private HitTestResultBehavior ResultsOfHit(HitTestResult myresult)
{
RayHitTestResult rayResult = myresult as RayHitTestResult;
if (rayResult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult
= rayResult as RayMeshGeometry3DHitTestResult;
//剣士のレイがヒットした場合
if (rayMeshResult != null)
{
pos.Y = pos.Y + 10 - rayMeshResult.DistanceToRayOrigin;
return HitTestResultBehavior.Stop;//Exit
}
}
return HitTestResultBehavior.Continue;
}
//地面と魔女キャラとの距離だけY座標を移動
private HitTestResultBehavior ResultsOfHit2(HitTestResult myresult)
{
RayHitTestResult rayResult = myresult as RayHitTestResult;
if (rayResult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult
= rayResult as RayMeshGeometry3DHitTestResult;
//魔女のレイがヒットした場合
if (rayMeshResult != null)
{
pos2.Y = pos2.Y + 10 - rayMeshResult.DistanceToRayOrigin;
return HitTestResultBehavior.Stop;//Exit
}
}
return HitTestResultBehavior.Continue;
}
//ディグリー(度)からラジアンへ変換
private float toRadian(float degree)
{
return (float)((float)degree / 360 * Math.PI * 2);
}
}
}
|
|