Add proper overlap and input check for circle buttons scheme
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
This commit is contained in:
co-authored by
Mihai Alexandru
parent
381bc6521c
commit
9657b7eb72
@@ -12,6 +12,7 @@ import flixel.math.FlxPoint;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxSignal;
|
||||
import funkin.mobile.util.SwipeUtil;
|
||||
import haxe.ds.Map;
|
||||
|
||||
/**
|
||||
* Enum representing the status of the button.
|
||||
@@ -28,8 +29,15 @@ enum abstract FunkinButtonStatus(Int) from Int to Int
|
||||
#if !display
|
||||
@:generic
|
||||
#end
|
||||
@:allow(funkin.mobile.ui.FunkinHitbox)
|
||||
@:allow(funkin.mobile.ui.FunkinButton)
|
||||
class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
{
|
||||
/**
|
||||
* A map that's storing every active touch's ID that's pressing a button.
|
||||
*/
|
||||
public static var buttonsTouchID:Map<Int, FunkinButton> = new Map();
|
||||
|
||||
/**
|
||||
* The current state of the button, either `FunkinButtonStatus.NORMAL` or `FunkinButtonStatus.PRESSED`.
|
||||
*/
|
||||
@@ -70,11 +78,21 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
*/
|
||||
public var justPressed(get, never):Bool;
|
||||
|
||||
/**
|
||||
* The touch instance that pressed this button.
|
||||
*/
|
||||
public var currentTouch(get, never):Null<FlxTouch>;
|
||||
|
||||
/**
|
||||
* An array of objects that blocks your input.
|
||||
*/
|
||||
public var deadZones:Array<FunkinSprite> = [];
|
||||
|
||||
/**
|
||||
* Wether the button should be released if you swiped over somwhere else.
|
||||
*/
|
||||
public var limitToBounds:Bool = true;
|
||||
|
||||
/**
|
||||
* The input associated with the button, using `Int` as the type.
|
||||
*/
|
||||
@@ -86,6 +104,11 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
*/
|
||||
var currentInput:IFlxInput;
|
||||
|
||||
/**
|
||||
* The ID of the touch object that pressed this button.
|
||||
*/
|
||||
var touchID:Int = -1;
|
||||
|
||||
/**
|
||||
* Creates a new `FunkinButton` object.
|
||||
*
|
||||
@@ -103,6 +126,7 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
ignoreDrawDebug = true;
|
||||
#end
|
||||
scrollFactor.set();
|
||||
|
||||
input = new FlxInput(0);
|
||||
}
|
||||
|
||||
@@ -115,6 +139,10 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
currentInput = null;
|
||||
input = null;
|
||||
|
||||
buttonsTouchID.remove(touchID);
|
||||
|
||||
touchID = -1;
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@@ -131,14 +159,14 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
{
|
||||
final overlapFound:Bool = checkTouchOverlap();
|
||||
|
||||
if (currentInput != null && currentInput.justReleased)
|
||||
if (currentInput != null && currentInput.justReleased && overlapFound)
|
||||
{
|
||||
onUpHandler();
|
||||
}
|
||||
|
||||
if (status != FunkinButtonStatus.NORMAL && !SwipeUtil.swipeAny && (currentInput != null && !currentInput.pressed))
|
||||
if (!isPressed(overlapFound))
|
||||
{
|
||||
onOutHandler();
|
||||
if (limitToBounds || (!limitToBounds && (currentTouch != null && currentTouch.justReleased))) onOutHandler();
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -146,24 +174,30 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
input.update();
|
||||
}
|
||||
|
||||
private function checkTouchOverlap():Bool
|
||||
private function checkTouchOverlap(?touch:FlxTouch):Bool
|
||||
{
|
||||
var touches = touch == null ? FlxG.touches.list : [touch];
|
||||
for (camera in cameras)
|
||||
{
|
||||
for (touch in FlxG.touches.list)
|
||||
for (touch in touches)
|
||||
{
|
||||
final worldPos:FlxPoint = touch.getWorldPosition(camera, _point);
|
||||
|
||||
for (zone in deadZones)
|
||||
{
|
||||
if (zone != null)
|
||||
{
|
||||
if (zone.overlapsPoint(worldPos, true, camera)) return false;
|
||||
}
|
||||
if (zone != null && zone.overlapsPoint(worldPos, true, camera)) return false;
|
||||
}
|
||||
|
||||
if (overlapsPoint(worldPos, true, camera))
|
||||
{
|
||||
touchID = touch.touchPointID;
|
||||
var prevButton = buttonsTouchID.get(touchID);
|
||||
if (prevButton != null && prevButton != this && !prevButton.limitToBounds)
|
||||
{
|
||||
prevButton.onOutHandler();
|
||||
}
|
||||
buttonsTouchID.set(touchID, this);
|
||||
|
||||
updateStatus(touch);
|
||||
|
||||
return true;
|
||||
@@ -174,6 +208,11 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isPressed(check:Bool):Bool
|
||||
{
|
||||
return !(status != FunkinButtonStatus.NORMAL && (!check || (currentInput != null && currentInput.justReleased)));
|
||||
}
|
||||
|
||||
private function updateStatus(input:IFlxInput):Void
|
||||
{
|
||||
if (input.justPressed)
|
||||
@@ -197,6 +236,10 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
|
||||
input.release();
|
||||
|
||||
buttonsTouchID.remove(touchID);
|
||||
|
||||
touchID = -1;
|
||||
|
||||
currentInput = null;
|
||||
|
||||
onUp.dispatch();
|
||||
@@ -217,6 +260,10 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
|
||||
input.release();
|
||||
|
||||
buttonsTouchID.remove(touchID);
|
||||
|
||||
touchID = -1;
|
||||
|
||||
onOut.dispatch();
|
||||
}
|
||||
|
||||
@@ -239,4 +286,9 @@ class FunkinButton extends FunkinSprite implements IFlxInput
|
||||
{
|
||||
return input.justPressed;
|
||||
}
|
||||
|
||||
private inline function get_currentTouch():Null<FlxTouch>
|
||||
{
|
||||
return FlxG.touches.getByID(touchID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +368,9 @@ class FunkinHitbox extends FlxTypedSpriteGroup<FunkinHint>
|
||||
final x:Float = ((i == 1) ? FlxG.width - (hintSize * 4) : hintSize * 2) + Math.cos(hintsAngles[j]) * hintsZoneRadius;
|
||||
final y:Float = (FlxG.height - (hintSize * 3.75)) + Math.sin(hintsAngles[j]) * hintsZoneRadius;
|
||||
|
||||
add(createHintCircle(x, y, hintsNoteDirections[j % hintsNoteDirections.length], hintSize, hintsColors[j % hintsColors.length]));
|
||||
final hint:FunkinHint = createHintCircle(x, y, hintsNoteDirections[j % hintsNoteDirections.length], hintSize, hintsColors[j % hintsColors.length]);
|
||||
hint.limitToBounds = false;
|
||||
add(hint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package funkin.mobile.ui;
|
||||
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxG;
|
||||
import flixel.input.touch.FlxTouch;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.ui.FlxButton;
|
||||
import flixel.util.FlxDirectionFlags;
|
||||
import flixel.input.touch.FlxTouch;
|
||||
import openfl.display.Graphics;
|
||||
|
||||
/**
|
||||
@@ -74,13 +74,14 @@ class FunkinPolygonButton extends FunkinButton
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
private override function checkTouchOverlap():Bool
|
||||
private override function checkTouchOverlap(?touch:FlxTouch):Bool
|
||||
{
|
||||
if (polygon != null && polygon.length >= 6 && polygon.length % 2 == 0)
|
||||
var touches = touch == null ? FlxG.touches.list : [touch];
|
||||
for (touch in touches)
|
||||
{
|
||||
for (camera in cameras)
|
||||
if (polygon != null && polygon.length >= 6 && polygon.length % 2 == 0)
|
||||
{
|
||||
for (touch in FlxG.touches.list)
|
||||
for (camera in cameras)
|
||||
{
|
||||
final worldPos:FlxPoint = touch.getWorldPosition(camera, _point);
|
||||
|
||||
@@ -96,11 +97,10 @@ class FunkinPolygonButton extends FunkinButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.checkTouchOverlap();
|
||||
return super.checkTouchOverlap(touch);
|
||||
}
|
||||
|
||||
#if FLX_DEBUG
|
||||
|
||||
Reference in New Issue
Block a user