3 using Microsoft.Xna.Framework;
4 using Microsoft.Xna.Framework.Input;
13 private float? defaultZoom;
16 get {
return defaultZoom ?? (GameSettings.CurrentConfig.EnableMouseLook ? 1.3f : 1.0f); }
19 defaultZoom = MathHelper.Clamp(value, 0.5f, 2.0f);
23 private float zoomSmoothness = 8.0f;
26 get {
return zoomSmoothness; }
27 set { zoomSmoothness = Math.Max(value, 0.01f); }
29 private float moveSmoothness = 8.0f;
32 get {
return moveSmoothness; }
33 set { moveSmoothness = Math.Max(value, 0.01f); }
36 private float minZoom = 0.1f;
39 get {
return minZoom; }
40 set { minZoom = MathHelper.Clamp(value, 0.001f, 10.0f); }
43 private float maxZoom = 2.0f;
46 get {
return maxZoom; }
47 set { maxZoom = MathHelper.Clamp(value, 1.0f, 10.0f); }
54 private Matrix transform, shaderTransform, viewMatrix;
55 private Vector2 position;
56 private float rotation;
58 private float angularVelocity;
59 private float angularDamping;
60 private float angularSpring;
62 private Vector2 prevPosition;
63 private float prevZoom;
67 private float shakeTimer;
71 private float globalZoomScale = 1.0f;
74 private float targetZoom;
75 private Vector2 velocity;
89 (
int)(center.X - newWidth / 2.0f),
90 (
int)(center.Y + newHeight / 2.0f),
100 get {
return rotation; }
103 if (!MathUtils.IsValid(value))
return;
110 get {
return angularVelocity; }
113 if (!MathUtils.IsValid(value))
return;
114 angularVelocity = value;
137 get {
return transform; }
142 get {
return shaderTransform; }
147 zoom = prevZoom = targetZoom = 1.0f;
149 position = Vector2.Zero;
178 private void CreateMatrices()
188 viewMatrix = Matrix.CreateTranslation(
new Vector3(res.X / 2.0f, res.Y / 2.0f, 0));
189 float newGlobalZoomScale = (float)
new Vector2(GUI.UIWidth,
Resolution.Y).Length() / GUI.ReferenceResolution.Length();
190 if (globalZoomScale > 0.0f)
192 Zoom *= newGlobalZoomScale / globalZoomScale;
193 targetZoom *= newGlobalZoomScale / globalZoomScale;
194 prevZoom *= newGlobalZoomScale / globalZoomScale;
196 globalZoomScale = newGlobalZoomScale;
207 Vector2 interpolatedPosition = interpolate ? Timing.Interpolate(prevPosition, position) : position;
209 float interpolatedZoom = interpolate ? Timing.Interpolate(prevZoom, zoom) : zoom;
212 (
int)(interpolatedPosition.Y +
WorldView.Height / 2.0),
215 transform = Matrix.CreateTranslation(
216 new Vector3(-interpolatedPosition.X, interpolatedPosition.Y, 0)) *
217 Matrix.CreateScale(
new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
218 Matrix.CreateRotationZ(rotation) * viewMatrix;
220 shaderTransform = Matrix.CreateTranslation(
222 -interpolatedPosition.X -
Resolution.X / interpolatedZoom / 2.0f,
223 -interpolatedPosition.Y -
Resolution.Y / interpolatedZoom / 2.0f, 0)) *
224 Matrix.CreateScale(
new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
226 viewMatrix * Matrix.CreateRotationZ(-rotation);
243 prevPosition = position;
248 private Vector2 previousOffset;
255 public void MoveCamera(
float deltaTime,
bool allowMove =
true,
bool allowZoom =
true,
bool allowInput =
true,
bool? followSub =
null)
257 prevPosition = position;
260 float moveSpeed = 20.0f / zoom;
264 Vector2 moveCam = Vector2.Zero;
267 Vector2 moveInput = Vector2.Zero;
270 if (GUI.KeyboardDispatcher.Subscriber ==
null && allowInput &&
MovementLockTimer <= 0.0f)
275 if (GameSettings.CurrentConfig.KeyMap.Bindings[
InputType.Left].IsDown()) { moveInput.X -= 1.0f; }
276 if (GameSettings.CurrentConfig.KeyMap.Bindings[
InputType.Right].IsDown()) { moveInput.X += 1.0f; }
277 if (GameSettings.CurrentConfig.KeyMap.Bindings[
InputType.Down].IsDown()) { moveInput.Y -= 1.0f; }
278 if (GameSettings.CurrentConfig.KeyMap.Bindings[
InputType.Up].IsDown()) { moveInput.Y += 1.0f; }
281 velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
287 if (closestSub !=
null)
289 moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
297 Vector2 diffViewCenter;
299 targetZoom = MathHelper.Clamp(
310 Zoom = MathHelper.Lerp(
Zoom, targetZoom, deltaTime * 10.0f);
318 Vector2 offset = mousePos -
Resolution.ToVector2() / 2;
321 if (offset.LengthSquared() > 1.0f) offset.Normalize();
322 float offsetUnscaledLen = offset.Length();
337 if (offset.LengthSquared() > 0.001f) { offset = previousOffset; }
341 previousOffset = offset;
347 float zoomOutAmount = GetZoomAmount(offset);
349 float scaledZoom = MathHelper.Lerp(
DefaultZoom,
MinZoom, zoomOutAmount) * globalZoomScale;
351 float newZoom = scaledZoom * (MathHelper.Lerp(0.3f * (1f - Math.Min(globalZoomScale, 1f)), 0f,
352 (GameSettings.CurrentConfig.EnableMouseLook) ? (
float)Math.Sqrt(offsetUnscaledLen) : 0.3f) + 1f);
360 Vector2 diff = (
TargetPos + offset) - position;
364 rotation += angularVelocity * deltaTime;
365 angularVelocity *= (1.0f - angularDamping);
366 angularVelocity += -rotation * angularSpring;
368 angularDamping = 0.05f;
369 angularSpring = 0.2f;
378 shakeTimer += deltaTime * 5.0f;
379 Vector2 noisePos =
new Vector2((
float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0) - 0.5f, (
float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0.5f) - 0.5f);
382 Shake = MathHelper.Lerp(
Shake, 0.0f, deltaTime * 2.0f);
392 velocity = Vector2.Zero;
393 angularVelocity = 0.0f;
399 get {
return position; }
402 if (!MathUtils.IsValid(value))
412 Vector2 worldCoords = Vector2.Transform(coords, Matrix.Invert(transform));
413 return new Vector2(worldCoords.X, -worldCoords.Y);
418 coords.Y = -coords.Y;
420 return Vector2.Transform(coords, transform);
423 private float GetZoomAmount(Vector2 offset)
425 return Math.Min(offset.Length() / 1000.0f, 1.0f);
430 return GetZoomAmount(previousOffset);
Vector2 WorldToScreen(Vector2 coords)
bool Freeze
Resets to false each time the MoveCamera method is called.
void MoveCamera(float deltaTime, bool allowMove=true, bool allowZoom=true, bool allowInput=true, bool? followSub=null)
Vector2 ScreenToWorld(Vector2 coords)
void UpdateTransform(bool interpolate=true, bool updateListener=true)
void ClientWrite(in SegmentTableWriter< ClientNetSegment > segmentTableWriter, IWriteMessage msg)
void Translate(Vector2 amount)
float GetZoomAmountFromPrevious()
void SetResolution(Point res)
static CharacterHealth?? OpenHealthWindow
static Character? Controlled
Triggers a "conversation popup" with text and support for different branching options.
Responsible for keeping track of the characters in the player crew, saving and loading their orders,...
static bool? IsCommandInterfaceOpen
virtual Vector2 WorldPosition
static int GraphicsHeight
static GameScreen GameScreen
static Sounds.SoundManager SoundManager
static Submarine FindClosest(Vector2 worldPosition, bool ignoreOutposts=false, bool ignoreOutsideLevel=true, bool ignoreRespawnShuttle=false, CharacterTeamType? teamType=null)
If has value, the sub must match the team type.
void WriteSingle(Single val)