-
Notifications
You must be signed in to change notification settings - Fork 125
/
Camera.hx
151 lines (129 loc) · 3.79 KB
/
Camera.hx
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package haxepunk;
import haxepunk.math.Vector2;
/**
* @since 4.0.0
*/
class Camera
{
public var x:Float = 0;
public var y:Float = 0;
public var scale:Float = 1;
public var scaleX:Float = 1;
public var scaleY:Float = 1;
public function new(x:Float = 0, y:Float = 0)
{
this.x = x;
this.y = y;
}
/**
* Set the Camera's position. If provided, px and py determine the part of
* the screen to move to the given position; 0.5 will center the camera,
* and 1.0 will set the right edge.
*/
public inline function setTo(x:Float, y:Float, px:Float = 0, py:Float = 0)
{
this.x = x - ((HXP.width / fullScaleX) * px);
this.y = y - ((HXP.height / fullScaleY) * py);
}
/**
* Whether this graphic will be snapped to the nearest whole number pixel
* position when rendering. If this is true for either an individual
* Graphic or for the Camera, snapping will occur.
*/
public var pixelSnapping:Bool = false;
public var fullScaleX(get, never):Float;
inline function get_fullScaleX() return scale * scaleX;
public var fullScaleY(get, never):Float;
inline function get_fullScaleY() return scale * scaleY;
public var screenScaleX(get, never):Float;
inline function get_screenScaleX() return fullScaleX * HXP.screen.scaleX;
public var screenScaleY(get, never):Float;
inline function get_screenScaleY() return fullScaleY * HXP.screen.scaleY;
public var width(get, never):Float;
inline function get_width() return HXP.screen.width / screenScaleX;
public var height(get, never):Float;
inline function get_height() return HXP.screen.height / screenScaleY;
/**
* Return an X value that, after scaling, will result in an integer.
*/
public inline function floorX(x:Float) return Math.floor((x + 0.5) * screenScaleX) / screenScaleX;
/**
* Return a Y value that, after scaling, will result in an integer.
*/
public inline function floorY(y:Float) return Math.floor((y + 0.5) * screenScaleY) / screenScaleY;
var anchorTarget:Null<Vector2>;
var anchorX:Float = 0;
var anchorY:Float = 0;
/**
* Anchor the Camera to an Entity or other object with position. The
* Camera will keep the target in the specified part of the screen.
* @since 4.0.0
*/
public function anchor(?target:Vector2, anchorX:Float = 0.5, anchorY:Float = 0.5)
{
anchorTarget = target;
this.anchorX = anchorX;
this.anchorY = anchorY;
}
public function onCamera(entity:Entity):Bool
{
return entity.collideRect(entity.x, entity.y, x, y, HXP.width, HXP.height);
}
/**
* Cause the screen to shake for a specified length of time.
* @param duration Duration of shake effect, in seconds.
* @param magnitude Number of pixels to shake in any direction.
* @since 2.5.3
*/
public function shake(duration:Float = 0.5, magnitude:Int = 4)
{
if (_shakeTime < duration) _shakeTime = duration;
_shakeMagnitude = magnitude;
}
/**
* Stop the screen from shaking immediately.
* @since 2.5.3
*/
public function shakeStop()
{
_shakeTime = 0;
}
public function update()
{
if (anchorTarget != null)
{
var tx = anchorTarget.x,
ty = anchorTarget.y;
if (Std.isOfType(anchorTarget, Entity))
{
var e:Entity = cast anchorTarget;
tx = e.centerX;
ty = e.centerY;
}
x = tx - (HXP.width / fullScaleX * anchorX);
y = ty - (HXP.height / fullScaleY * anchorY);
}
// screen shake
if (_shakeTime > 0)
{
var sx:Int = Std.random(_shakeMagnitude * 2 + 1) - _shakeMagnitude;
var sy:Int = Std.random(_shakeMagnitude * 2 + 1) - _shakeMagnitude;
x += sx - _shakeX;
y += sy - _shakeY;
_shakeX = sx;
_shakeY = sy;
_shakeTime -= HXP.elapsed;
if (_shakeTime < 0) _shakeTime = 0;
}
else if (_shakeX != 0 || _shakeY != 0)
{
x -= _shakeX;
y -= _shakeY;
_shakeX = _shakeY = 0;
}
}
var _shakeTime:Float=0;
var _shakeMagnitude:Int=0;
var _shakeX:Int=0;
var _shakeY:Int=0;
}