#objective-c #sprite-kit #scenekit
#objective-c #sprite-kit #scenekit
Вопрос:
У меня проблема в том, что touchesEnded (на iOS) или mouseUp (на macOS) по-прежнему вызываются для выпущенных объектов, когда касание / щелчок был запущен до выпуска. Такое поведение вызывает сбои в моем проекте. Я создал урезанную программу с SceneKit и наложением SpriteKit, но я не уверен, что я делаю неправильно.
Я начал с игрового шаблона SceneKit (iOS или macOS) и добавил два класса:
В GameViewController.m в конце -(void)awakeFromNib я добавил это:
OverlayScene *overlay=[OverlayScene sceneWithSize:self.gameView.frame.size];// init the overlay
[overlay setupButtons];// create a small GUI menu
[self.gameView setOverlaySKScene:overlay];// add the overlay to the SceneKit view
Затем два класса
OverlayScene.m:
#import <SpriteKit/SpriteKit.h>
#import "Button.h"
@interface OverlayScene : SKScene
-(void)setupButtons;
@end
OverlayScene.m:
#import "OverlayScene.h"
@implementation OverlayScene
-(void)setupButtons{//showing a menu mockup
NSLog(@"setupButtons");
srand((unsigned)time(NULL));// seed the RNG
[self removeAllChildren];//remove all GUI element (only one button or nothing (in the first call)
Button *b=[[Button alloc] initWithSelector:@selector(setupButtons) onObject:self];// a new button
b.position=CGPointMake(rand()%300, rand()%300);// just a random position so we can see the change
[self addChild:b];// finally attach the button to the scene
}
@end
Button.h:
#import <SpriteKit/SpriteKit.h>
@interface Button : SKSpriteNode{
SEL selector;//the method which is supposed to be called by the button
__weak id selectorObj;//the object on which the selector is called
}
-(id)initWithSelector:(SEL)s onObject:(__weak id)o;
@end
Button.m:
#import "Button.h"
@implementation Button
-(id)initWithSelector:(SEL)s onObject:(__weak id)o{
//self=[super initWithColor:[UIColor purpleColor] size:CGSizeMake(200, 60)];//this is the code for iOS
self=[super initWithColor:[NSColor purpleColor] size:CGSizeMake(200, 60)];// this is for macOS
selector=s;//keep the selector with the button
selectorObj=o;
[self setUserInteractionEnabled:YES];//enable touch handling
return self;
}
//-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//called on iOS
-(void)mouseDown:(NSEvent *)event{//called on macOS
[selectorObj performSelector:selector];//we are calling the method which was given during the button initialization
}
@end
Когда вы нажимаете на кнопку, она удаляется (и освобождается по дуге), как и ожидалось, и создается новая. Все в порядке, пока вы продолжаете удерживать нажатой кнопку мыши. Когда вы отпускаете его, приложение вылетает, потому что это событие наведения мыши отправляется на удаленную кнопку:
Комментарии:
1. похоже, ваши имена переменных очень трудно читать, но почему вы вызываете кнопки настройки внутри вашего селектора? Вы удаляете свои кнопки с помощью remove all, тем самым получая свои ошибки
2. Если вы могли бы предоставить проект, я посмотрю на него сегодня вечером
3. Хорошо, вот что происходит, mouseUp ищет кнопку, но кнопка не существует, похоже, в коде mouseUp есть дефект, который не проверяет, существует ли кнопка, прежде чем запускать событие для нее. Вам придется как-то сохранить его и удалить в конечном обновлении
4. Предполагается, что mouseDragged не будет запущен, как и mouseUp, если объект равен нулю, но есть ошибка с набором сцен с наложением набора спрайтов. По-видимому, я видел еще одну проблему с этим, но код был неясен, и я предположил, что это только набор спрайтов, поэтому я найду его завтраи также сообщите об этом пользователю.
5. ну, технически, это и то, и другое, вы не должны удалять вещи из своей сцены с набором спрайтов до конца обновления по причинам, которые вы наблюдаете. Конечно, это в основном мое мнение, но с точки зрения дизайна имеет смысл убивать только в конце обновления, потому что мне нравится рассматривать каждое обновление как замороженный момент времени, оценивать этот момент, а затем, когда вы будете готовы разморозить время, вносить изменения.