How to scale a button from center with a correct hitBox?

582 views
Skip to first unread message

Ats

unread,
Oct 31, 2014, 1:17:45 AM10/31/14
to haxef...@googlegroups.com
Hi, I've spent several days trying to get scale and hitBox resizing working together without luck...
I'm trying to scale a button from his center and to update his hitBox so I can click correctly on the scalled button. The problem is that when I use the function updateHitbox(), the scale is operated from the top left of the button, or maybe is offset is moved, I'm not sure...
What should I do to scale from center and having a good hitBox?

Here's a snippet showing my problem:

package;

import flixel.FlxG;
import flixel.FlxState;
import flixel.ui.FlxButton;
import flixel.util.FlxColor;

class PlayState extends FlxState
{
 
override public function create():Void
 
{
 
super.create();
 
FlxG.debugger.drawDebug = true;
 
 
// Just scale -> scale from center :) , wrong hitBox :(
 
var button1:FlxButton = new FlxButton(200, 200, "1");
 button1
.makeGraphic(16, 16, FlxColor.BEIGE);
 button1
.scale.x = button1.scale.y = 10;
 button1
.onOver.callback = onOver.bind(button1);
 button1
.onOut.callback = onOut.bind(button1);
 add
(button1);

 
// Scale with updateHitbox -> scale from top left :( , good hitBox :)
 
var button2:FlxButton = new FlxButton(400, 200, "2");
 button2
.makeGraphic(16, 16, FlxColor.BEIGE);
 button2
.scale.x = button2.scale.y = 10;
 button2
.updateHitbox();
 button2
.onOver.callback = onOver.bind(button2);
 button2
.onOut.callback = onOut.bind(button2);
 add
(button2);
 
}
 
 
private function onOver(btn:FlxButton):Void { btn.color = FlxColor.LIME; }
 
private function onOut(btn:FlxButton):Void { btn.color = FlxColor.WHITE; }
}

Thanks for your help!

Ats

unread,
Oct 31, 2014, 7:13:31 AM10/31/14
to
So after a good night of sleep and a bit more research in HaxeFlixel source code, I found a way to do almost what I want.
By setting everything hand work:

 button.scale.x = button.scale.y = scale;
 button
.width = button.scale.x * button.frameWidth;
 button
.height = button.scale.y * button.frameHeight;
 button
.centerOffsets(true);

But since my buttons are in fact covers inside a coverflow, their scale and position are always in motion. So I had to hack that a little more by compensating their position with the difference between their scale in each frame, so the button won't run away from the screen while growing in size:

 button3.width = button3.scale.x * button3.frameWidth;
 button3
.height = button3.scale.y * button3.frameHeight;
 button3
.centerOffsets();
 button3
.x -= (button3.width - btn3LastWidth) / 2;
 button3
.y -= (button3.height - btn3LastHeight) / 2;
 btn3LastWidth
= button3.width;
 btn3LastHeight
= button3.height;

Here's the complete code for playing around with those annoying buttons:

package;

import flixel.FlxG;
import flixel.FlxState;
import flixel.ui.FlxButton;
import flixel.util.FlxColor;
import flixel.tweens.FlxTween;

class PlayState extends FlxState
{
 
private var button1:FlxButton;
 
private var button2:FlxButton;
 
private var button3:FlxButton;
 
 
private var scale:Int = 4;

 
 
override public function create():Void
 
{
 
super.create();
 
FlxG.debugger.drawDebug = true;

 
 
for (x in 1...4) {
   
for (y in 1...3) {
   
var button:FlxButton = new FlxButton(x * 160, y * 140, Std.string(10 * y + x));
    button
.makeGraphic(16, 16, FlxColor.BEIGE);
    button
.onOver.callback = onOver.bind(button);
    button
.onOut.callback = onOut.bind(button);
    add
(button);
 
   
switch (10 * y + x) {
     
case 11:
      button
.scale.x = button.scale.y = scale;
     
case 12:
      button
.scale.x = button.scale.y = scale;
      button
.updateHitbox();
     
case 13:
      button
.scale.x = button.scale.y = scale;
      button
.width = button.scale.x * button.frameWidth;
      button
.height = button.scale.y * button.frameHeight;
      button
.centerOffsets(true);
     
case 21:
      button1
= button;
     
FlxTween.tween(button1.scale, { "x":scale, "y":scale }, 2);
     
case 22:
      button2
= button;
     
FlxTween.tween(button2.scale, { "x":scale, "y":scale }, 2);
     
case 23:
      button3
= button;
     
FlxTween.tween(button3.scale, { "x":scale, "y":scale }, 2);
   
}
   
}
 
}
 
}
 
 
override public function update():Void
 
{
 
super.update();

  button2
.updateHitbox();
 
  var btn3LastWidth = button3.width;
  var btn3LastHeight = button3.height;
  button3
.width = button3.scale.x * button3.frameWidth;
  button3
.height = button3.scale.y * button3.frameHeight;
  button3
.centerOffsets();
  button3
.x -= (button3.width - btn3LastWidth) / 2;
  button3
.y -= (button3.height - btn3LastHeight) / 2;
  btn3LastWidth
= button3.width;
  btn3LastHeight
= button3.height;

 
}
 
 
private function onOver(btn:FlxButton):Void { btn.color = FlxColor.LIME; }
 
private function onOut(btn:FlxButton):Void { btn.color = FlxColor.WHITE; }
}

So that works. But since I have tons of buttons in my coverflow, that's not really optimized...
I'm surely missing something obvious in order to simply obtain what I want... Nobody's ever wanted to scale a button (or sprite) from it's center and to update their hitBox at the same time?

Edit:
That's the last bit of code I've come up with. But as I'm moving the button coordinates, it's getting messy on my coverflow...

override public function update():Void
{
 
super.update();
 
var lastWidth:Float = button.width;
 
var lastHeight:Float = button.height;
  button
.updateHitbox();
  button
.x -= (button.width - lastWidth) / 2;
  button
.y -= (button.height - lastHeight) / 2;
}

Reply all
Reply to author
Forward
0 new messages