Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul pointer #3210

Merged
merged 9 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
317 changes: 214 additions & 103 deletions flixel/input/FlxPointer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,165 +7,276 @@ import flixel.util.FlxStringUtil;

class FlxPointer
{
/** The position in the world */
public var x(default, null):Int = 0;
/** The position in the world */
public var y(default, null):Int = 0;

/** The world position relative to the main camera's scroll position */
@:deprecated("screenX is deprecated, use viewX, instead")
public var screenX(default, never):Int = 0;
/** The world position relative to the main camera's scroll position */
@:deprecated("screenY is deprecated, use viewY, instead")
public var screenY(default, never):Int = 0;

/**
* The world position relative to the main camera's scroll position, `cam.viewMarginX` or
* `cam.viewMarginLeft` is the left edge of the camera and `cam.viewMarginRight` is the right
*
* @since 5.9.0
*/
public var viewX(default, null):Int = 0;
/**
* The world position relative to the main camera's scroll position, `cam.viewMarginY` or
* `cam.viewMarginTop` is the top edge of the camera and `cam.viewMarginBottom` is the bottom
*
* @since 5.9.0
*/
public var viewY(default, null):Int = 0;

/**
* The position relative to the `FlxGame`'s position in the window,
* where `0` is the left edge of the game and `FlxG.width` is the right
*
* @since 5.9.0
*/
public var gameX(default, null):Int = 0;
/**
* The position relative to the `FlxGame`'s position in the window,
* where `0` is the top edge of the game and `FlxG.height` is the bottom
*
* @since 5.9.0
*/
public var gameY(default, null):Int = 0;

public var screenX(default, null):Int = 0;
public var screenY(default, null):Int = 0;

var _globalScreenX:Int = 0;
var _globalScreenY:Int = 0;
@:deprecated("_globalScreenX is deprecated, use gameX, instead") // 5.9.0
var _globalScreenX(get, set):Int;
@:deprecated("_globalScreenY is deprecated, use gameY, instead") // 5.9.0
var _globalScreenY(get, set):Int;

var _rawX(default, null):Float = 0;
var _rawY(default, null):Float = 0;

static var _cachedPoint:FlxPoint = new FlxPoint();

public function new() {}

/**
* Fetch the world position of the pointer on any given camera.
* NOTE: x and y also store the world position of the pointer on the main camera.
* Fetch the world position of the pointer on any given camera
*
* **Note:** Fields `x` and `y` also store this result
*
* @param Camera If unspecified, first/main global camera is used instead.
* @param point An existing point object to store the results (if you don't want a new one created).
* @return The touch point's location in world space.
* @param camera If unspecified, `FlxG.camera` is used, instead
* @param result An existing point to store the results, if unspecified, one is created
*/
public function getWorldPosition(?Camera:FlxCamera, ?point:FlxPoint):FlxPoint
public function getWorldPosition(?camera:FlxCamera, ?result:FlxPoint):FlxPoint
{
if (Camera == null)
{
Camera = FlxG.camera;
}
if (point == null)
{
point = FlxPoint.get();
}
getScreenPosition(Camera, _cachedPoint);
point.x = _cachedPoint.x + Camera.scroll.x;
point.y = _cachedPoint.y + Camera.scroll.y;
return point;
if (camera == null)
camera = FlxG.camera;

getViewPosition(camera, result);
result.addPoint(camera.scroll);
return result;
}

/**
* Fetch the screen position of the pointer on any given camera.
* NOTE: screenX and screenY also store the screen position of the pointer on the main camera.
*
* @param Camera If unspecified, first/main global camera is used instead.
* @param point An existing point object to store the results (if you don't want a new one created).
* @return The touch point's location in screen space.
* The position relative to the game's position in the window, where `(0, 0)` is the
* top-left edge of the game and `(FlxG.width, FlxG.height)` is the bottom-right
*
* **Note:** Fields `gameX` and `gameY` also store this result
*
* @param result An existing point to store the results, if unspecified, one is created
* @since 5.9.0
*/
public function getScreenPosition(?Camera:FlxCamera, ?point:FlxPoint):FlxPoint
public function getGamePosition(?result:FlxPoint):FlxPoint
{
if (Camera == null)
{
Camera = FlxG.camera;
}
if (point == null)
{
point = FlxPoint.get();
}

point.x = (_globalScreenX - Camera.x + 0.5 * Camera.width * (Camera.zoom - Camera.initialZoom)) / Camera.zoom;
point.y = (_globalScreenY - Camera.y + 0.5 * Camera.height * (Camera.zoom - Camera.initialZoom)) / Camera.zoom;

return point;
if (result == null)
return FlxPoint.get();

return result.set(Std.int(_rawX), Std.int(_rawY));
}

/**
* Fetch the screen position of the pointer relative to given camera's viewport.
* Fetch the world position relative to the main camera's `scroll` position, where
* `(cam.viewMarginLeft, cam.viewMarginTop)` is the top-left of the camera and
* `(cam.viewMarginRight, cam.viewMarginBottom)` is the bottom right
*
* **Note:** Fields `viewX` and `viewY` also store this result
*
* @param Camera If unspecified, first/main global camera is used instead.
* @param point An existing point object to store the results (if you don't want a new one created).
* @return The touch point's location relative to camera's viewport.
* @param camera If unspecified, `FlxG.camera` is used, instead
* @param result An existing point to store the results, if unspecified, one is created
*/
@:access(flixel.FlxCamera)
public function getPositionInCameraView(?Camera:FlxCamera, ?point:FlxPoint):FlxPoint
public function getViewPosition(?camera:FlxCamera, ?result:FlxPoint):FlxPoint
{
if (Camera == null)
Camera = FlxG.camera;

if (point == null)
point = FlxPoint.get();

point.x = (_globalScreenX - Camera.x) / Camera.zoom + Camera.viewMarginX;
point.y = (_globalScreenY - Camera.y) / Camera.zoom + Camera.viewMarginY;

return point;
if (camera == null)
camera = FlxG.camera;
if (result == null)
result = FlxPoint.get();
result.x = Std.int((gameX - camera.x) / camera.zoom + camera.viewMarginX);
result.y = Std.int((gameY - camera.y) / camera.zoom + camera.viewMarginY);
return result;
}


/**
* Fetch the position of the pointer relative to given camera's `scroll` position, where
* `(cam.viewMarginLeft, cam.viewMarginTop)` is the top-left of the camera and
* `(cam.viewMarginRight, cam.viewMarginBottom)` is the bottom right of the camera
*
* **Note:** Fields `viewX` and `viewY` also store this result for `FlxG.camera`
*
* @param camera If unspecified, `FlxG.camera` is used, instead
* @param result An existing point to store the results, if unspecified, one is created
*/
@:deprecated("getScreenPosition is deprecated, use getViewPosition, instead") // 5.9.0
public function getScreenPosition(?camera:FlxCamera, ?result:FlxPoint):FlxPoint
{
if (camera == null)
camera = FlxG.camera;

if (result == null)
result = FlxPoint.get();

result.x = (gameX - camera.x + 0.5 * camera.width * (camera.zoom - camera.initialZoom)) / camera.zoom;
result.y = (gameY - camera.y + 0.5 * camera.height * (camera.zoom - camera.initialZoom)) / camera.zoom;

return result;
}

/**
* Fetch the position of the pointer relative to given camera's `scroll` position, where
* `(cam.viewMarginLeft, cam.viewMarginTop)` is the top-left of the camera and
* `(cam.viewMarginRight, cam.viewMarginBottom)` is the bottom right of the camera
*
* **Note:** Fields `viewX` and `viewY` also store this result for `FlxG.camera`
*
* @param camera If unspecified, `FlxG.camera` is used, instead.
* @param result An existing point to store the results, if unspecified, one is created
* @return The pointer's location relative to camera's viewport.
*/
@:deprecated("getPositionInCameraView is deprecated, use getViewPosition, instead") // 5.9.0
public function getPositionInCameraView(?camera:FlxCamera, ?result:FlxPoint):FlxPoint
{
if (camera == null)
camera = FlxG.camera;

if (result == null)
result = FlxPoint.get();

result.x = (gameX - camera.x) / camera.zoom + camera.viewMarginX;
result.y = (gameY - camera.y) / camera.zoom + camera.viewMarginY;

return result;
}

/**
* Returns a FlxPoint with this input's x and y.
*/
public function getPosition(?point:FlxPoint):FlxPoint
public function getPosition(?result:FlxPoint):FlxPoint
{
if (point == null)
point = FlxPoint.get();
return point.set(x, y);
if (result == null)
return FlxPoint.get(x, y);

return result.set(x, y);
}

/**
* Checks to see if some FlxObject overlaps this FlxObject or FlxGroup.
* If the group has a LOT of things in it, it might be faster to use FlxG.overlaps().
* WARNING: Currently tilemaps do NOT support screen space overlap checks!
* Checks to see if this pointer overlaps some `FlxObject` or `FlxGroup`.
*
* @param ObjectOrGroup The object or group being tested.
* @param Camera Specify which game camera you want. If null getScreenPosition() will just grab the first global camera.
* @return Whether or not the two objects overlap.
* @param objectOrGroup The object or group being tested
* @param camera Helps determine the world position. If unspecified, `FlxG.camera` is used
*/
@:access(flixel.group.FlxTypedGroup.resolveGroup)
public function overlaps(ObjectOrGroup:FlxBasic, ?Camera:FlxCamera):Bool
public function overlaps(objectOrGroup:FlxBasic, ?camera:FlxCamera):Bool
{
var result:Bool = false;

var group = FlxTypedGroup.resolveGroup(ObjectOrGroup);
// check group
final group = FlxTypedGroup.resolveGroup(objectOrGroup);
if (group != null)
{
group.forEachExists(function(basic:FlxBasic)
for (basic in group.members)
{
if (overlaps(basic, Camera))
if (basic != null && overlaps(basic, camera))
{
result = true;
return;
return true;
}
});
}
else
{
getWorldPosition(Camera, _cachedPoint);
var object:FlxObject = cast ObjectOrGroup;
result = object.overlapsPoint(_cachedPoint, true, Camera);
}
return false;
}

return result;
// check object
getWorldPosition(camera, _cachedPoint);
final object = cast (objectOrGroup, FlxObject);
return object.overlapsPoint(_cachedPoint, true, camera);
}

/**
* Directly set the underyling screen position variable. WARNING! You should never use
* this unless you are trying to manually dispatch low-level mouse / touch events to the stage.
*/
@:deprecated("setGlobalScreenPositionUnsafe is deprecated, use setRawPositionUnsafe, instead")
public inline function setGlobalScreenPositionUnsafe(newX:Float, newY:Float):Void
{
_globalScreenX = Std.int(newX / FlxG.scaleMode.scale.x);
_globalScreenY = Std.int(newY / FlxG.scaleMode.scale.y);

updatePositions();
setRawPositionUnsafe(newX, newY);
}

public function toString():String

/**
* Directly set the underyling position variable. WARNING! You should never use
* this unless you are trying to manually dispatch low-level mouse / touch events to the stage.
* @since 5.9.0
*/
@:haxe.warning("-WDeprecated")
public function setRawPositionUnsafe(x:Float, y:Float)
{
return FlxStringUtil.getDebugString([LabelValuePair.weak("x", x), LabelValuePair.weak("y", y)]);
_rawX = x / FlxG.scaleMode.scale.x;
_rawY = y / FlxG.scaleMode.scale.y;

updatePositions();
}

/**
* Helper function to update the cursor used by update() and playback().
* Updates the x, y, screenX, and screenY variables based on the default camera.
*/
function updatePositions():Void
{
getScreenPosition(FlxG.camera, _cachedPoint);
screenX = Std.int(_cachedPoint.x);
screenY = Std.int(_cachedPoint.y);

getGamePosition(_cachedPoint);
gameX = Std.int(_cachedPoint.x);
gameY = Std.int(_cachedPoint.y);

getViewPosition(FlxG.camera, _cachedPoint);
viewX = Std.int(_cachedPoint.x);
viewY = Std.int(_cachedPoint.y);

getWorldPosition(FlxG.camera, _cachedPoint);
x = Std.int(_cachedPoint.x);
y = Std.int(_cachedPoint.y);
}

public function toString():String
{
return FlxStringUtil.getDebugString([LabelValuePair.weak("x", x), LabelValuePair.weak("y", y)]);
}

inline function get__globalScreenX():Int
{
return gameX;
}

inline function get__globalScreenY():Int
{
return gameY;
}

inline function set__globalScreenX(value:Int):Int
{
_rawX = value * FlxG.scaleMode.scale.x;
return value;
}

inline function set__globalScreenY(value:Int):Int
{
_rawY = value * FlxG.scaleMode.scale.y;
return value;
}
}
Loading
Loading