-
Notifications
You must be signed in to change notification settings - Fork 0
/
OffsetCalculator.cs
114 lines (87 loc) · 3.79 KB
/
OffsetCalculator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using SuperBitBros.Entities.Blocks;
using SuperBitBros.Entities.DynamicEntities;
using SuperBitBros.OpenGL.OGLMath;
using System;
using System.Collections.Generic;
namespace SuperBitBros
{
public class OffsetCalculator
{
public const double MAX_CORRECTION_SPEED = 15;
public Vec2d Value { get; private set; }
public List<Rect2d> visionBoxes = new List<Rect2d>();
public OffsetCalculator()
{
Value = Vec2d.Zero;
}
public void Change(Vec2d off)
{
Value = new Vec2d(off);
}
public void Calculate(Rect2d target, int window_width, int window_height, double mapW, double mapH, bool moveDown, bool capCorrection = true)
{
Rect2d cameraBox = GetOffsetBox(window_width, window_height);
Vec2d playerPos = target.GetMiddle();
// Wenn man aus der Mittleren Box rausläuft - Offset Verschieben
//###############################################################################
Vec2d moveCorrection = cameraBox.GetDistanceTo(playerPos);
if (moveDown && moveCorrection.Y == 0 && playerPos.Y != cameraBox.tl.Y)
{
moveCorrection.Y -= 5;
}
// Offset NICHT verschieben wenn amn damit die Grenzen der aktuellen Zone verletzten Würde
//###############################################################################
Vec2d zoneCorrection = GetVisionZoneCorrection(Value + moveCorrection, playerPos, window_width, window_height);
Vec2d realCorrection = moveCorrection + zoneCorrection;
if (capCorrection)
realCorrection.DoMaxLength(MAX_CORRECTION_SPEED);
if (realCorrection.GetLength() < 0.001)
realCorrection = Vec2d.Zero;
Value += realCorrection;
}
private Vec2d GetVisionZoneCorrection(Vec2d offset, Vec2d playerPos, int window_width, int window_height)
{
Rect2d windowBox = new Rect2d(offset, window_width, window_height);
foreach (Rect2d vrect in visionBoxes)
{
if (vrect.Includes(playerPos))
{
double corrY_bottom = Math.Max(vrect.bl.Y - windowBox.bl.Y, 0);
double corrY_top = Math.Min(vrect.tr.Y - windowBox.tr.Y, 0);
double corrX_left = Math.Max(vrect.bl.X - windowBox.bl.X, 0);
double corrX_right = Math.Min(vrect.tr.X - windowBox.tr.X, 0);
Vec2d correction = Vec2d.Zero;
if (!(corrY_top != 0 && corrY_bottom != 0))
{
if (corrY_top != 0)
correction.Y = corrY_top;
else
correction.Y = corrY_bottom;
}
if (!(corrX_left != 0 && corrX_right != 0))
{
if (corrX_left != 0)
correction.X = corrX_left;
else
correction.X = corrX_right;
}
return correction;
}
}
return Vec2d.Zero;
}
public Rect2d GetOffsetBox(int window_width, int window_height)
{
Rect2d result = new Rect2d(Value, window_width, window_height);
result.TrimNorth(Block.BLOCK_HEIGHT * 2);
result.TrimEast(Block.BLOCK_WIDTH * 8);
result.TrimSouth(Block.BLOCK_HEIGHT * 2 + Player.PLAYER_HEIGHT / 2.0);
result.TrimWest(Block.BLOCK_WIDTH * 8);
return result;
}
public void AddVisionBoxes(List<Rect2d> boxes)
{
visionBoxes.AddRange(boxes);
}
}
}