检测被点击的几个按钮的最佳方法是什么

时间:2012-04-23 02:46:22

标签: iphone c++ openframeworks

我在屏幕上以编程方式绘制了几个圆圈。然后我计算出手指点击的x和y坐标与圆圈的x和y坐标之间的距离。

哪个距离小于任何圆的半径是点击的圆。真的很简单。然而我发现我有很多重复的代码,我觉得我可以清理代码,但我不知道目前最好的方法是什么。

任何帮助表示赞赏。

float diffx = touch.x - bass.pos.x;
float diffy = touch.y - bass.pos.y;
float dist = sqrt(diffx*diffx + diffy*diffy);
if(dist < bass.radius){

    if(recordingInfo.isRecording){
        //do some stuff related to this button unique

    }
    //play some sound
}

diffx = touch.x - treble.pos.x;
diffy = touch.y - treble.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < treble.radius){
    if(recordingInfo.isRecording){
        //do something related to this button
    }
    //play some sound
}

diffx = touch.x - hihat.pos.x;
diffy = touch.y - hihat.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < hihat.radius){
    if(recordingInfo.isRecording){

        //do shayt related to this button

    }
    //play this sound
}

diffx = touch.x - bassTwo.pos.x;
diffy = touch.y - bassTwo.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < bassTwo.radius){
    if(recordingInfo.isRecording){
        //do some crap regarding this indivudal button

    }
    //play another sound
}

diffx = touch.x - kick.pos.x;
diffy = touch.y - kick.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < kick.radius){
    if(recordingInfo.isRecording){
      //do some funky stuff related to this button
    }
    //play some sound
}

diffx = touch.x - snare.pos.x;
diffy = touch.y - snare.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < snare.radius){
    if(recordingInfo.isRecording){
        //
    }
    //play some sound
}

diffx = touch.x - recordButton.pos.x;
diffy = touch.y - recordButton.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

if(dist < recordButton.radius){
    //and do some funky stuff audio visual styff gere
}    

diffx = touch.x - play.pos.x;
diffy = touch.y - play.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);
     //code execution if this circle button is hit
}    

或者这样好吗?我将所有这些代码放在touchDown方法

2 个答案:

答案 0 :(得分:1)

重复的代码是:

diffx = touch.x - recordButton.pos.x;
diffy = touch.y - recordButton.pos.y;
dist = sqrt(diffx*diffx + diffy*diffy);

任何时候代码都会出现多次,你应该考虑把它放在一个函数中:

float distance(vec touch, vec button_center) {
    float diffx = touch.x - bass.pos.x;
    float diffy = touch.y - bass.pos.y;
    float dist = sqrt(diffx*diffx + diffy*diffy);
    return dist;
}

if(distance(touch,bass.pos) < bass.radius){
   ...
}
if(distance(touch, treble.pos) < treble.radius){
   ...
}
if(distance(touch,hihat.pos) < hihat.radius){
   ...
}

当然,您也在重复检查按钮是否已被点击:

bool is_hit(Button b,vec touch) {
    return distance(b.pos,touch) < b.radius;
}

if(is_hit(bass,touch)) {}
if(is_hit(treble,touch)) {}
...

这是处理事件的一种非常简单的方法,在不改变程序架构的情况下很难进一步减少重复。如果您想要更灵活的东西,可能需要了解GUI框架如何处理事件。关于事件的Cocoa文档可能是一个很好的例子:Cocoa Event-Handling Guide

答案 1 :(得分:1)

首先,添加一些简单的实用方法:

- (float) distanceBetweenTouch:(UITouch*)touch andPoint:(CGPoint)point {
    float diffx = touch.x - point.x;
    float diffy = touch.y - point.y;
    return sqrt(diffx*diffx + diffy*diffy);
}

- (NSArray*) tappedButtons:(NSArray*)buttons forTouch:(UITouch*)touch {
    NSMutableArray* result = [NSMutableArray array];

    for (SomeCustomButtonType* button in buttons) {
        if ([self distanceBetweenTouch:touch andPoint:button.pos] < button.radius) {
            [result addObject:button];
        }
    }

    return result;
}

然后修改代码以执行以下操作:

NSArray* allButtons = [NSArray* arrayWithObjects:bass, treble, hihat, ..., nil];
NSArray* tappedButtons = [self tappedButtons:allButtons forTouch:touch];

for (SomeCustomButtonType* button in tappedButtons) {
    if (button == bass) {
        //handle tap on the 'bass' button
    }
    else if (button == treble) {
        //handle tap on the 'treble' button
    }
    //... (handlers for other buttons)
}

...甚至更好,如果你稍微移动一下代码以便每个按钮知道在点击时它应该做什么,你或许可以重写那个if/else块和for循环:

[tappedButtons makeObjectsPerformSelector:@selector(handleTap)];

虽然,我不确定单个水龙头如何与多个按钮交叉,除非您的按钮部分重叠。