// dirty as it only checks whether one contains a point of the other internal static bool CollideBoundingBoxPolygon(ICollidible boxCollidible, ICollidible polyCollidible, CollisionTypePolygon cTypePoly) { // first check the bounding box of the polygon (for performance) CCRect box = ((CCNode)boxCollidible).BoundingBoxTransformedToWorld; if (box.IntersectsRect(((CCNode)polyCollidible).BoundingBoxTransformedToWorld)) { CCPoint[] boxPoints = Constants.CCRectPoints(box); // transform the polygon to match the positioning, rotation and scale of the node Polygon transformedPolygon = ((Polygon)cTypePoly.collisionPolygon.Clone()); transformedPolygon.TransformAccordingToGameObject(polyCollidible); foreach (var point in boxPoints) { if (transformedPolygon.ContainsPoint(point)) { return(true); } } foreach (var point in transformedPolygon.Points) { if (box.ContainsPoint(point)) { return(true); } } } return(false); }
//this method runs the game logic, such as ball physics, collision methods, etc void RunGameLogic(float frameTimeInSeconds) { if (lives == 0) { isGameOver = true; GameOver(isGameOver); return; } else if (p1Score == 72) //this is the maximum score possible for this level, thus is the victory condition { LevelComplete(bounds); return; } ball.PositionY += ball.VelocityY * frameTimeInSeconds; //moving the ball ballBoundingBox = ball.BoundingBoxTransformedToParent; // bb for ball p1BoundingBox = p1Paddle.BoundingBoxTransformedToParent; //bb for p1Paddle bool doesBallOverlapPaddle = ballBoundingBox.IntersectsRect(p1BoundingBox); //display score and lives //call handling brick collisions here HandleBrickCollisions(bricksBoundingBoxRow1, bricksRow1); HandleBrickCollisions(bricksBoundingBoxRow2, bricksRow2); HandleBrickCollisions(bricksBoundingBoxRow3, bricksRow3); HandleSilverBrickCollisions(bricksBoundingBoxRow4, bricksRow4); HandleBrickCollisions(bricksBoundingBoxRow5, bricksRow5); HandleSilverBrickCollisions(bricksBoundingBoxRow6, bricksRow6); //ball hitting paddle logic HandlePaddleCollisions(p1BoundingBox, ballBoundingBox, ball); //ball hitting wall logic HandleWallCollisions(ballBoundingBox, ball); debugLabel.Text = string.Format("Lives: {0} Score: {1}", lives, p1Score); }
//--------------------------------------------------------------------------------------------------------- // GetRandomPosition - Old method - don't use //--------------------------------------------------------------------------------------------------------- // Parameters: CCsprite - size of the sprite to position // // Returns: CCPoint - random point within the display field //--------------------------------------------------------------------------------------------------------- // CCPoint GetRandomPosition (CCSize spriteSize) // { // double rndX = CCRandom.NextDouble (); // double rndY = CCRandom.NextDouble (); // double randomX = (rndX > 0) // ? rndX * VisibleBoundsWorldspace.Size.Width - spriteSize.Width / 2 // : spriteSize.Width / 2; // if (randomX < (spriteSize.Width / 2)) // randomX += spriteSize.Width; // // double randomY = (rndY > 0) // ? rndY * VisibleBoundsWorldspace.Size.Height - spriteSize.Height / 2 // : spriteSize.Height / 2; // if (randomY < (spriteSize.Height / 2)) // randomY += spriteSize.Height; // return new CCPoint ((float)randomX, (float)randomY); // } //--------------------------------------------------------------------------------------------------------- // GetSeparatingVector - Not being used //--------------------------------------------------------------------------------------------------------- // Parameters: first - CCRect of the first object being compared // second - CCRect of the second object being compared // // Returns: CCVector2 - vector to direction to move second object so it won't collide with first //--------------------------------------------------------------------------------------------------------- // Used to compare overlaping rectangles of two objects to determine if they collide or not. If they do // return a vector to move the object so it won't overlap //--------------------------------------------------------------------------------------------------------- static CCVector2 GetSeparatingVector(CCRect first, CCRect second) { CCVector2 separation = CCVector2.Zero; if (first.IntersectsRect(second)) { var intersecionRect = first.Intersection(second); bool separateHorizontally = intersecionRect.Size.Width < intersecionRect.Size.Height; if (separateHorizontally) { separation.X = intersecionRect.Size.Width; if (first.Center.X < second.Center.X) { separation.X *= -1; } separation.Y = 0; } else { separation.X = 0; separation.Y = intersecionRect.Size.Height; if (first.Center.Y < second.Center.Y) { separation.Y *= -1; } } } return(separation); }
/** * Determines if a given node's bounding box is in visible bounds * * @return YES if it is in visible bounds */ public bool IsNodeVisible(CCNode node) { CCPoint offset = ContentOffset; CCSize size = ViewSize; float scale = ZoomScale; var viewRect = new CCRect(-offset.X / scale, -offset.Y / scale, size.Width / scale, size.Height / scale); return(viewRect.IntersectsRect(node.BoundingBox)); }
//this method runs the game logic, such as ball physics, collision methods, etc void RunGameLogic(float frameTimeInSeconds) { if (lives == 0) { isGameOver = true; GameOver(isGameOver, bounds); return; } else if (p1Score == 69) //this is the maximum score possible for this level, thus is the victory condition { LevelComplete(bounds); return; } ball.PositionY += ball.VelocityY * frameTimeInSeconds; ballBoundingBox = ball.BoundingBoxTransformedToParent; // bb for ball p1BoundingBox = p1Paddle.BoundingBoxTransformedToParent; //bb for p1Paddle bool doesBallOverlapPaddle = ballBoundingBox.IntersectsRect(p1BoundingBox); //display score and lives //call handling brick collisions here //since there are many rows, requires many calls to the HandleBrickCollisions method HandleBrickCollisions(bricksBoundingBoxRow1, bricksRow1); HandleBrickCollisions(bricksBoundingBoxRow2, bricksRow2); HandleBrickCollisions(bricksBoundingBoxRow3, bricksRow3); HandleBrickCollisions(bricksBoundingBoxRow4, bricksRow4); HandleBrickCollisions(bricksBoundingBoxRow5, bricksRow5); HandleBrickCollisions(bricksBoundingBoxRow6, bricksRow6); HandleBrickCollisions(bricksBoundingBoxRow7, bricksRow7); HandleBrickCollisions(bricksBoundingBoxRow8, bricksRow8); HandleBrickCollisions(bricksBoundingBoxRow9, bricksRow9); HandleBrickCollisions(bricksBoundingBoxRow10, bricksRow10); HandleBrickCollisions(bricksBoundingBoxRow11, bricksRow11); HandleBrickCollisions(bricksBoundingBoxRow12, bricksRow12); HandleBrickCollisions(bricksBoundingBoxRow13, bricksRow13); HandleBrickCollisions(bricksBoundingBoxRow14, bricksRow14); HandleBrickCollisions(bricksBoundingBoxRow15, bricksRow15); HandleBrickCollisions(bricksBoundingBoxRow16, bricksRow16); HandleBrickCollisions(bricksBoundingBoxRow17, bricksRow17); HandleBrickCollisions(bricksBoundingBoxRow18, bricksRow18); HandleBrickCollisions(bricksBoundingBoxRow19, bricksRow19); HandleBrickCollisions(bricksBoundingBoxRow20, bricksRow20); HandleBrickCollisions(bricksBoundingBoxRow21, bricksRow21); HandleBrickCollisions(bricksBoundingBoxRow22, bricksRow22); //ball hitting paddle logic HandlePaddleCollisions(p1BoundingBox, ballBoundingBox, ball); //ball hitting wall logic HandleWallCollisions(ballBoundingBox, ball); //update score and lives in real time debugLabel.Text = string.Format("Lives: {0} Score: {1}", lives, p1Score); }
//end reference HandleTouchesMoved //method to handle what occurs when the ball collides with a brick //the brick will be destroyed on collision and the ball's y velocity gets inverted void HandleBrickCollisions(List <CCRect> rects, List <RedBrick> bricks) { for (int i = 0; i < rects.Count; i++) { bool doesBallOverlapBrick = ballBoundingBox.IntersectsRect(rects[i]); if (doesBallOverlapBrick) { hitCount++; ball.VelocityY *= -1; p1Score += 1; if (bricks[i].IsHit()) { RemoveChild(bricks[i]); rects[i] = new CCRect(); //this essentially destroys the CCRect } if (hitCount >= 2) { ball.VelocityY *= -1; hitCount = 0; } } } }
//handle what occurs when the ball hits the paddle (invert ball yVelocity) void HandlePaddleCollisions(CCRect paddleBox, CCRect ballBox, Ball ballRep) { bool doesBallOverlapPaddle = ballBox.IntersectsRect(paddleBox); bool isMovingDown = ballRep.VelocityY < 0; if (doesBallOverlapPaddle && isMovingDown) { //invert velocity ballRep.VelocityY *= -1; //assign a value to the x velocity. Keeping constant speed const float minXVelocity = -300; const float maxXVelocity = 300; ballRep.VelocityX = CCRandom.GetRandomFloat(minXVelocity, maxXVelocity); // randomizes the xVelocity //reset hit counter whenever the ball hits anything that isn't a brick hitCount = 0; } }
/** * Determines if a given node's bounding box is in visible bounds * * @return YES if it is in visible bounds */ public bool IsNodeVisible(CCNode node) { CCPoint offset = ContentOffset; CCSize size = ViewSize; float scale = ZoomScale; var viewRect = new CCRect(-offset.X / scale, -offset.Y / scale, size.Width / scale, size.Height / scale); return viewRect.IntersectsRect(node.BoundingBox); }
bool Intersects(CCRect first, RectWithDirection second) { return(first.IntersectsRect(second.ToRect())); }
internal void Salvage() { State = WreckageState.SALVAGING; var mAircraft = MiddleAircraft; var totalScale = mAircraft.GetTotalScale(); mAircraft.Visible = false; List <Part> totalparts = mAircraft.TotalParts; // unmount and disassemble mAircraft.Body = null; foreach (var part in totalparts) { part.Disassemble(); foreach (var singlePart in totalparts) { if (singlePart.Flipped) { singlePart.Flip(); } } // repair the part fully part.Reinitialize(); } // choose the parts that will be salvaged SalvagedParts = new List <Part>(); // how many? var rng = new Random(); int salvageCount = (int)(GetWreckPercentile(mAircraft) * totalparts.Count()); if (salvageCount != totalparts.Count() && rng.NextDouble() <= (GetWreckPercentile(mAircraft) * totalparts.Count()) % 1) { salvageCount++; } // choose random parts for (int i = 0; i < salvageCount; i++) { var index = rng.Next(totalparts.Count()); SalvagedParts.Add(totalparts.ElementAt(index)); totalparts.RemoveAt(index); } float delay = SalvagedParts.Count * SalvagedParts.Count * 150 + 100; float delaySec = delay / 1000; // vibrate if (Constants.oS != Constants.OS.WINDOWS) { Vibration.Vibrate(delay * 0.015f); } // visualize var boundsCenter = VisibleBoundsWorldspace.Center; CCPoint pointIn = boundsCenter + new CCPoint(0, VisibleBoundsWorldspace.Size.Height * 0.6f); var width = VisibleBoundsWorldspace.Size.Width / 3; float inMoveTime = 1f; Dictionary <Part, CCPoint> destinations = new Dictionary <Part, CCPoint>(); foreach (var part in SalvagedParts) { part.Visible = true; AddChild(part, -10); part.AnchorPoint = CCPoint.AnchorMiddle; var rotation = new CCRepeatForever(new CCRotateBy(1, rng.Next(20, 30) * 0.5f)); rotation.Tag = RotationTag; part.AddAction(rotation); // find a free spot part.Scale = totalScale; const float BORDER = 32f; bool notFound = true; // first try to find a free space where the part can rotate without touching anything for (int tries = 0; tries < 40 && notFound; tries++) { destinations[part] = Constants.RandomPointBoxnear(boundsCenter, width, rng); // check whether the space is free part.Position = destinations[part]; CCRect bbox = part.BoundingBoxTransformedToWorld; // construct a bounding square float size = bbox.Size.Height > bbox.Size.Width ? bbox.Size.Height : bbox.Size.Width; bbox = new CCRect(bbox.Center.X - size / 2, bbox.Center.Y - size / 2, size, size); // add a bit of padding CCRect box = new CCRect(bbox.MinX - BORDER, bbox.MinY - BORDER, bbox.Size.Width + 2 * BORDER, bbox.Size.Height + 2 * BORDER); notFound = false; foreach (var otherPart in SalvagedParts) { if (otherPart == part) { continue; } if (box.IntersectsRect(otherPart.BoundingBoxTransformedToWorld)) { notFound = true; break; } } } // if this failed try to find a free space where the parts at least do not touch in starting configuration for (int tries = 0; tries < 40 && notFound; tries++) { destinations[part] = Constants.RandomPointBoxnear(boundsCenter, width, rng); // check whether the space is free part.Position = destinations[part]; CCRect bbox = part.BoundingBoxTransformedToWorld; // add a bit of padding CCRect box = new CCRect(bbox.MinX - BORDER, bbox.MinY - BORDER, bbox.Size.Width + 2 * BORDER, bbox.Size.Height + 2 * BORDER); notFound = false; foreach (var otherPart in SalvagedParts) { if (otherPart == part) { continue; } if (box.IntersectsRect(otherPart.BoundingBoxTransformedToWorld)) { notFound = true; break; } } } } foreach (var part in SalvagedParts) { part.Position = pointIn; part.AddAction(new CCSequence(new CCDelayTime(delaySec), new CCEaseOut(new CCMoveTo(inMoveTime, destinations[part]), 2f))); } // count down the percentage float startP = GetWreckPercentile(mAircraft); CCLabel percentLabel = GetPercentLabel(mAircraft); AddAction(new CCSequence(new CCEaseIn(new CCCallFiniteTimeFunc(delaySec, (progress, duration) => { SetWreckPercentile(mAircraft, startP * (1 - progress)); }), 4f), new CCCallFunc(() => { percentLabel.Visible = false; }))); // if no parts could be salvaged end the salvaged state immediately if (!SalvagedParts.Any()) { AddAction(new CCSequence(new CCDelayTime(delaySec + inMoveTime), new CCCallFunc(() => { State = WreckageState.SALVAGED; EndSalvage(); }))); } else { AddAction(new CCSequence(new CCDelayTime(delaySec + inMoveTime), new CCCallFunc(() => { State = WreckageState.SALVAGED; }))); } }