1

我在屏幕上以编程方式绘制了几个圆圈。然后我计算出手指点击的 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 方法中

4

2 回答 2

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

于 2012-04-23T03:00:31.947 回答
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)];

虽然,我不确定单击将如何与多个按钮相交,除非您的按钮部分重叠。

于 2012-04-23T03:00:58.870 回答