public class DemoPlayer : MActor { /// ----------------------------------------------- /// PRECACHING & STATIC DATA VALUES /// ----------------------------------------------- public static string ClassName = "DemoPlayer"; private static bool HasCached = false; public static void Precache() { HasCached = MPrecacher.Precache(ClassName, HasCached); } /// static private MModel StaticModel = MPrecacher.PrecacheModel(ClassName, "Arrow.xml"); /// ----------------------------------------------- /// ----------------------------------------------- /// private float m_WalkSpeed = 6.0f; [Description("The speed at which the DemoPlayer walks, in meters per second.")] public float WalkSpeed { get { return m_WalkSpeed; } set { m_WalkSpeed = value; } }
public DemoPlayer(MWorld world) : base(world) { Precache(); // we'll create the DemoPlayer in slightly different ways // depending on whether we're in Reality Builder or in the actual Game if (!MHelpers.IsGameApp()) { // In Reality Builder, let's load up the arrow model as this Actor's MyModel so that we have some // visual representation of where our relatively abstract DemoPlayer is going to begin // We won't bother creating this MyModel in Game-mode however, // because the DemoPlayer is just a very basic avatar with no external view MyModel = new MModel(); StaticModel.CreateNewInstance(MyModel); // In Reality Builder, we want these basic Engine Physics states, // they're for dragging around the DemoPlayer representative model with no gravity on it CollisionFlags = COLLISION_FLAGS.CF_PASSABLE_BBOX; PhysicsFlags = PHYSICS_FLAGS.PHYS_NOT_AFFECTED_BY_GRAVITY; } else { // In-game, let's set this DemoPlayer as the GameCore's avatar, // so that the GameCore will call its input and camera updating functions during the World Tick! GameCore.Game.LocalAvatar = this; // In-game, we want these basic Engine Physics states, // they're ideal for a wall-sliding, stair-climbing, pushable character in the world CollisionFlags = COLLISION_FLAGS.CF_BBOX; PhysicsFlags = PHYSICS_FLAGS.PHYS_PUSHABLE | PHYSICS_FLAGS.PHYS_ONBLOCK_CLIMBORSLIDE; } // set the demoplayer's collision box size SetCollisionBox(new MVector(-DemoPlayerBoxWidth, -DemoPlayerBoxHeight / 2, -DemoPlayerBoxWidth), new MVector(DemoPlayerBoxWidth, DemoPlayerBoxHeight / 2, DemoPlayerBoxWidth)); }
/// <summary> /// This function is called by the GameCore.cs in Tick when you declare this Actor to be the GameCore's avatar /// </summary> public override void ProcessInput() { // if the user currently has a gui active, just bail out and ensure the cursor is visible if (MHelpers.HasAnyGUIopen()) { MHelpers.SetCursorVisible(true); return; } // no cursor when actually controlling the Player MHelpers.SetCursorVisible(false); // calculate Player Rotation according to mouse yaw and pitch Rotation = MMatrix.LookTowards(MVector.MakeDirection(MInput.mouseYaw, MInput.mousePitch, 0)); MVector newDirection = new MVector(); // User's new attempted direction //basic movement inputs // strafing left and right if (GameInput.ControlDown(GameInput.KEY_STRAFE_LEFT)) newDirection += 0.5f * (-Rotation.GetRight()); else if (GameInput.ControlDown(GameInput.KEY_STRAFE_RIGHT)) newDirection += 0.5f * (Rotation.GetRight()); // moving forward and backwards if (GameInput.ControlDown(GameInput.KEY_WALK_FORWARD)) newDirection += Rotation.GetDir(); else if (GameInput.ControlDown(GameInput.KEY_WALK_BACKWARD)) newDirection -= Rotation.GetDir(); newDirection.y = 0; // demoplayer movement has no Y component if (CurrentState == STATE_ONGROUND) Accelerate(newDirection.Normalized(), WalkSpeed, 46); // ground acceleration else Accelerate(newDirection.Normalized(), WalkSpeed, 7); // air acceleration // check if the jump key is pressed, and if the user's feet are on the ground, jump him if (GameInput.ControlJustPressed(GameInput.KEY_JUMP) && CurrentState == STATE_ONGROUND) Velocity.y = JumpVelocity; }
/// <summary> /// This function is called by the GameCore.cs in Tick when you declare this Actor to be the GameCore's avatar /// </summary> public override void UpdateCamera() { // just set the camera to the DemoPlayer's Location plus half the height of the bbox up, // so that his eyes are located at the top of the bbox // and use his Rotation too. MCameraHandler.setToView(Location + new MVector(0, m_DemoPlayerBoxHeight / 2, 0), Rotation); }
/// <summary> /// Our Quake-style walk acceleration function /// </summary> protected void Accelerate(MVector wishdir, float wishspeed, float accel) { // apply acceleration towards desired direction, with removal of over-acceleration. float addspeed, currentspeed; //calculate the acceleration vecetor to add to achieve the desired velocity direction currentspeed = Velocity.Dot(wishdir); if (wishspeed == currentspeed) return; // add time-scaled acceleration if (wishspeed > currentspeed) addspeed = accel * MHelpers.DeltaTime; else addspeed = -accel * MHelpers.DeltaTime; // limit acceleration to exact needed value to achieve desired speed if ((currentspeed + addspeed > wishspeed && wishspeed > currentspeed) || (currentspeed + addspeed < wishspeed && wishspeed < currentspeed)) addspeed = wishspeed - currentspeed; // add the calculated acceleration amount in the desired direction to our current Velocity Velocity += addspeed * wishdir; }
/// <summary> /// Called right after the World renders, to allow custom canvas drawing with regards to this Actor /// In the DemoPlayer's case, we'll draw a very simple HUD /// </summary> public override void PostRender(MCamera camera) { // Some way cool HUD text MCanvas.TextCenteredf(MCanvas.MediumFont, MHelpers.ColorFromRGBA(200, 255, 255, 190), 512, 740, "I am a DemoPlayer."); }
/// <summary> /// Disposal of the Actor's resources, called when the Actor is destroyed, /// namely by having its LifeTime set to 0, having Destroy() called on it, or upon World unloading/app shutdown /// </summary> protected override void DisposeResources() { // if this actor is currently the GameCore's local avatar, // it's good C# programming practice to nullify the local avatar reference // when this Actor is disposed of. if (GameCore.Game.LocalAvatar == this) GameCore.Game.LocalAvatar = null; base.DisposeResources(); }
//=========== (C) Copyright 2004, Artificial Studios. All rights reserved. ================ /// DemoPlayer: A simple example avatar that processes input and updates the camera /// /// A tutorial that describes the creation of this class is located at: /// http://reality.artificialstudios.com/twiki/bin/view/Main/DemoPlayer /// /// Author: Jeremy Stieglitz //========================================================================================= #region Using directives using System; using ScriptingSystem; using System.ComponentModel; #endregion public class DemoPlayer : MActor { /// ----------------------------------------------- /// PRECACHING & STATIC DATA VALUES /// ----------------------------------------------- public static string ClassName = "DemoPlayer"; private static bool HasCached = false; public static void Precache() { HasCached = MPrecacher.Precache(ClassName, HasCached); } /// static private MModel StaticModel = MPrecacher.PrecacheModel(ClassName, "Arrow.xml"); /// ----------------------------------------------- /// ----------------------------------------------- /// private float m_WalkSpeed = 6.0f; [Description("The speed at which the DemoPlayer walks, in meters per second.")] public float WalkSpeed { get { return m_WalkSpeed; } set { m_WalkSpeed = value; } } private float m_JumpVelocity = 8.0f; [Description("The Y velocity with which the DemoPlayer jumps off the ground.")] public float JumpVelocity { get { return m_JumpVelocity; } set { m_JumpVelocity = value; } } private float m_DemoPlayerBoxWidth = 0.4f; [Description("The width of the DemoPlayer's bounding box, in meters.")] public float DemoPlayerBoxWidth { get { return m_DemoPlayerBoxWidth; } set { m_DemoPlayerBoxWidth = value; } } private float m_DemoPlayerBoxHeight = 2; [Description("The height of the DemoPlayer's bounding box, in meters. \nThe DemoPlayer's eyes will be located at the top of this height.")] public float DemoPlayerBoxHeight { get { return m_DemoPlayerBoxHeight; } set { m_DemoPlayerBoxHeight = value; } } /// <summary> /// ctor /// </summary> public DemoPlayer(MWorld world) : base(world) { Precache(); // we'll create the DemoPlayer in slightly different ways // depending on whether we're in Reality Builder or in the actual Game if (!MHelpers.IsGameApp()) { // In Reality Builder, let's load up the arrow model as this Actor's MyModel so that we have some // visual representation of where our relatively abstract DemoPlayer is going to begin // We won't bother creating this MyModel in Game-mode however, // because the DemoPlayer is just a very basic avatar with no external view MyModel = new MModel(); StaticModel.CreateNewInstance(MyModel); // In Reality Builder, we want these basic Engine Physics states, // they're for dragging around the DemoPlayer representative model with no gravity on it CollisionFlags = COLLISION_FLAGS.CF_PASSABLE_BBOX; PhysicsFlags = PHYSICS_FLAGS.PHYS_NOT_AFFECTED_BY_GRAVITY; } else { // In-game, let's set this DemoPlayer as the GameCore's avatar, // so that the GameCore will call its input and camera updating functions during the World Tick! GameCore.Game.LocalAvatar = this; // In-game, we want these basic Engine Physics states, // they're ideal for a wall-sliding, stair-climbing, pushable character in the world CollisionFlags = COLLISION_FLAGS.CF_BBOX; PhysicsFlags = PHYSICS_FLAGS.PHYS_PUSHABLE | PHYSICS_FLAGS.PHYS_ONBLOCK_CLIMBORSLIDE; } // set the demoplayer's collision box size SetCollisionBox(new MVector(-DemoPlayerBoxWidth, -DemoPlayerBoxHeight / 2, -DemoPlayerBoxWidth), new MVector(DemoPlayerBoxWidth, DemoPlayerBoxHeight / 2, DemoPlayerBoxWidth)); } /// <summary> /// This function is called by the GameCore.cs in Tick when you declare this Actor to be the GameCore's avatar /// </summary> public override void ProcessInput() { // if the user currently has a gui active, just bail out and ensure the cursor is visible if (MHelpers.HasAnyGUIopen()) { MHelpers.SetCursorVisible(true); return; } // no cursor when actually controlling the Player MHelpers.SetCursorVisible(false); // calculate Player Rotation according to mouse yaw and pitch Rotation = MMatrix.LookTowards(MVector.MakeDirection(MInput.mouseYaw, MInput.mousePitch, 0)); MVector newDirection = new MVector(); // User's new attempted direction //basic movement inputs // strafing left and right if (GameInput.ControlDown(GameInput.KEY_STRAFE_LEFT)) newDirection += 0.5f * (-Rotation.GetRight()); else if (GameInput.ControlDown(GameInput.KEY_STRAFE_RIGHT)) newDirection += 0.5f * (Rotation.GetRight()); // moving forward and backwards if (GameInput.ControlDown(GameInput.KEY_WALK_FORWARD)) newDirection += Rotation.GetDir(); else if (GameInput.ControlDown(GameInput.KEY_WALK_BACKWARD)) newDirection -= Rotation.GetDir(); newDirection.y = 0; // demoplayer movement has no Y component if (CurrentState == STATE_ONGROUND) Accelerate(newDirection.Normalized(), WalkSpeed, 46); // ground acceleration else Accelerate(newDirection.Normalized(), WalkSpeed, 7); // air acceleration // check if the jump key is pressed, and if the user's feet are on the ground, jump him if (GameInput.ControlJustPressed(GameInput.KEY_JUMP) && CurrentState == STATE_ONGROUND) Velocity.y = JumpVelocity; } /// <summary> /// This function is called by the GameCore.cs in Tick when you declare this Actor to be the GameCore's avatar /// </summary> public override void UpdateCamera() { // just set the camera to the DemoPlayer's Location plus half the height of the bbox up, // so that his eyes are located at the top of the bbox // and use his Rotation too. MCameraHandler.setToView(Location + new MVector(0, m_DemoPlayerBoxHeight / 2, 0), Rotation); } /// <summary> /// Our Quake-style walk acceleration function /// </summary> protected void Accelerate(MVector wishdir, float wishspeed, float accel) { // apply acceleration towards desired direction, with removal of over-acceleration. float addspeed, currentspeed; //calculate the acceleration vecetor to add to achieve the desired velocity direction currentspeed = Velocity.Dot(wishdir); if (wishspeed == currentspeed) return; // add time-scaled acceleration if (wishspeed > currentspeed) addspeed = accel * MHelpers.DeltaTime; else addspeed = -accel * MHelpers.DeltaTime; // limit acceleration to exact needed value to achieve desired speed if ((currentspeed + addspeed > wishspeed && wishspeed > currentspeed) || (currentspeed + addspeed < wishspeed && wishspeed < currentspeed)) addspeed = wishspeed - currentspeed; // add the calculated acceleration amount in the desired direction to our current Velocity Velocity += addspeed * wishdir; } /// <summary> /// Called right after the World renders, to allow custom canvas drawing with regards to this Actor /// In the DemoPlayer's case, we'll draw a very simple HUD /// </summary> public override void PostRender(MCamera camera) { // Some way cool HUD text MCanvas.TextCenteredf(MCanvas.MediumFont, MHelpers.ColorFromRGBA(200, 255, 255, 190), 512, 740, "I am a DemoPlayer."); } /// <summary> /// Disposal of the Actor's resources, called when the Actor is destroyed, /// namely by having its LifeTime set to 0, having Destroy() called on it, or upon World unloading/app shutdown /// </summary> protected override void DisposeResources() { // if this actor is currently the GameCore's local avatar, // it's good C# programming practice to nullify the local avatar reference // when this Actor is disposed of. if (GameCore.Game.LocalAvatar == this) GameCore.Game.LocalAvatar = null; base.DisposeResources(); } }