So I am trying to implement a basic pong AI that is decent, but can be beaten. I have tried [UIView animateWithDuration...] UISnapBehavior and UIAttachmentBehavior.
animateWithDuration does not update the collision detection properly so i get invisible walls
UISnapBehavior is still too fast, and does not respond to friction or resistance to slow down
UIAttachmentBehavior seems to be my best bet, because it works with my collision behavior like Snap but is more flexible. However, I cannot get it to work. Open to all suggestions, here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
[self startGame];
}
basic method that just gets everything going
- (void)startGame {
[self createBall];
[self createPlayerPaddle];
[self createAIPaddle];
[self createCollisions];
// Remove rotation
self.paddleDynamicProperties = [[UIDynamicItemBehavior alloc] initWithItems:@[self.paddleView, self.paddleViewAI]];
self.paddleDynamicProperties.allowsRotation = NO;
//make heavy
self.paddleDynamicProperties.density = 1000.0f;
//make slow
self.paddleDynamicProperties.friction = 1000;
[self.animator addBehavior:self.paddleDynamicProperties];
}
we'll look at collisions and the paddleViewAI
- (void)createCollisions {
self.collider = [[UICollisionBehavior alloc] initWithItems:@[self.ballView, self.paddleView, self.paddleViewAI]];
//self.collider.collisionDelegate = self.paddleView;
self.collider.collisionMode = UICollisionBehaviorModeEverything;
[self.collider addBoundaryWithIdentifier:@"left" fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.view.frame.size.height)];
[self.collider addBoundaryWithIdentifier:@"right" fromPoint:CGPointMake(self.view.frame.size.width, 0) toPoint:CGPointMake(self.view.frame.size.width, self.view.frame.size.height)];
[self.animator addBehavior:self.collider];
}
- (void)createAIPaddle {
CGRect paddleRect = CGRectMake((self.view.frame.size.width / 2), 30, 100, 10);
self.paddleViewAI = [[UIView alloc] initWithFrame:paddleRect];
self.paddleViewAI.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.paddleViewAI];
//make AI work
//track location of ball
[self addObserver:self forKeyPath:@"self.ballView.center" options:NSKeyValueObservingOptionNew context:nil];
}
and finally where i respond to the changes of the balls position as it moves along
-(void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString *,id> *)change context:(nullable void *)context {
if ([keyPath isEqualToString:@"self.ballView.center"]) {
if (!CGRectContainsRect(self.view.frame, self.ballView.frame)) {
[self createBall];
[self createCollisions];
}
CGPoint location = self.ballView.center;
//paddle respond to location of ball
if (self.dxAI == 0) {
self.dxAI = location.x - self.paddleViewAI.center.x;
}
//create offsets
CGPoint newLocation = CGPointMake(location.x - self.dxAI, self.paddleViewAI.center.y);
CGRect newRect = CGRectMake(newLocation.x - (self.paddleViewAI.frame.size.width / 2), self.paddleViewAI.frame.origin.y, self.paddleViewAI.frame.size.width, self.paddleViewAI.frame.size.height);
//keep paddle inside view
if (CGRectContainsRect(self.view.frame, newRect)) {
//apply offsets
if (self.attach != nil) {
[self.animator removeBehavior:self.attach];
}
self.attach = [[UIAttachmentBehavior alloc] initWithItem:self.paddleViewAI attachedToAnchor:self.paddleViewAI.center];
// the plan was adjust the frequency to affect speed so AI will only be able to keep up sometimes
self.attach.frequency = 20;
self.attach.damping = 1;
[self.attach setAnchorPoint:newLocation];
[self.animator addBehavior:self.attach];
}
//update animations
[self.animator updateItemUsingCurrentState:self.paddleViewAI];
}
}
I could use UISnap, UIAttach, or the UIView animateWithDuration in this last method but as I mentioned none quite works. I'm open to any suggestion, or just to get the UIAttach to at least work would be lovely.
Aucun commentaire:
Enregistrer un commentaire