private static void splitBall(Ball ball, int targetBallCount, FieldSimulation field) { int ballCopiesCount = targetBallCount - 1; //add more balls var resultBalls = new ArrayList {ball}; if (ballCopiesCount > 0) { for (int i = 0; i < ballCopiesCount; i++) { Ball ballCopy = getBallCopy(ball, field); resultBalls.Add(ballCopy); } } double currentAngle = ball.getCurrentAngle(); double newBallAngle = currentAngle%90; double leftover = newBallAngle - MINIMUM_ANGLE; double fraction = (leftover*2)/(targetBallCount + 1); for (int i = 0; i < resultBalls.Count; i++) { newBallAngle = currentAngle + leftover - (i + 1)*fraction; Console.WriteLine("newBallAngle: " + newBallAngle); (resultBalls[i] as Ball).setVector(newBallAngle); if (resultBalls[i] != ball) //add new balls to field { field.ballsManager.balls.Add(resultBalls[i]); } } }
public Ball(FieldSimulation fieldLink) { _fieldLink = fieldLink; isNPC = fieldLink is NPCFieldSimulation; setVector(BALL_START_ANGLE); _wiggler = new BallWiggler(this); }
/** * Checks for cells which are around and "hit tests" them by comparing coordinates. * @param ball * @param field */ public static void hitTest(Ball ball, FieldSimulation field, bool shieldProtection) { double currentCellI = Math.Floor(ball.x / GameConfig.BRICK_WIDTH); double currentCellJ = Math.Floor(ball.y / GameConfig.BRICK_HEIGHT); AroundCellData nearByCellsData = new AroundCellData(field.fieldCells.cells, (int)currentCellI, (int)currentCellJ, field); hitTestFieldSides(nearByCellsData, ball, field, shieldProtection); if (ball.stealthMode == false) //if stealth (during switching presets) -> don't hittest cells hitTestCells(nearByCellsData._cells, ball); }
public AroundCellData(Cell[,] cells, int currentCellI, int currentCellJ, FieldSimulation field) { if (currentCellI < 0 || currentCellJ < 0 || currentCellI >= field.fieldCells.columnsCount || currentCellJ >= field.fieldCells.rowsCount) //out of the "box" { leftBorderNearby = rightBorderNearby = topBorderNearby = bottomBorderNearby = true; return; } topBorderNearby = (currentCellJ - 1) < 0; bottomBorderNearby = (currentCellJ + 1) >= field.fieldCells.rowsCount; rightBorderNearby = (currentCellI + 1) >= field.fieldCells.columnsCount; leftBorderNearby = (currentCellI - 1) < 0; //Testing 1 cell down if (!bottomBorderNearby && cells[currentCellJ + 1, currentCellI].notEmpty) _cells.Add(cells[currentCellJ + 1, currentCellI]); // //Testing 1 cell right, 1 cell down if (!bottomBorderNearby && !rightBorderNearby && cells[currentCellJ + 1, currentCellI + 1].notEmpty) _cells.Add(cells[currentCellJ + 1, currentCellI + 1]); //Testing 1 cell right if (!rightBorderNearby && cells[currentCellJ, currentCellI + 1].notEmpty) _cells.Add(cells[currentCellJ, currentCellI + 1]); // //Testing 1 cell up, 1 cell down if (!rightBorderNearby && !topBorderNearby && cells[currentCellJ - 1, currentCellI + 1].notEmpty) _cells.Add(cells[currentCellJ - 1, currentCellI + 1]); //Testing 1 cell up if (!topBorderNearby && cells[currentCellJ - 1, currentCellI].notEmpty) _cells.Add(cells[currentCellJ - 1, currentCellI]); // //Testing 1 cell left, 1 cell up if (!leftBorderNearby && !topBorderNearby && cells[currentCellJ - 1, currentCellI - 1].notEmpty) _cells.Add(cells[currentCellJ - 1, currentCellI - 1]); //Testing 1 cell left if (!leftBorderNearby && cells[currentCellJ, currentCellI - 1].notEmpty) _cells.Add(cells[currentCellJ, currentCellI - 1]); // //Testing 1 cell down, 1 cell left if (!topBorderNearby && !leftBorderNearby && field.fieldCells.rowsCount > currentCellJ + 1 && cells[currentCellJ + 1, currentCellI - 1].notEmpty) _cells.Add(cells[currentCellJ + 1, currentCellI - 1]); if (cells[currentCellJ, currentCellI].notEmpty) //cell in which ball is (it could be skipped before) _cells.Add(cells[currentCellJ, currentCellI]); }
public static void splitBalls(FieldSimulation field, int targetBallCount) { var tempArr = new ArrayList(); //thus we wont be operating on target array foreach (Ball ball in field.ballsManager.balls) //copy balls { tempArr.Add(ball); } foreach (Ball ball in tempArr) //split em (new balls will be added to BaseField) { splitBall(ball, targetBallCount, field); } }
private static Ball getBallCopy(Ball targetBall, FieldSimulation fs) { var copy = new Ball(fs); copy.x = targetBall.x; copy.y = targetBall.y; copy.stealthMode = targetBall.stealthMode; copy.dead = targetBall.dead; copy.setVector(targetBall.getCurrentAngle()); if (targetBall.wiggler.wiggling) //copy wiggling params { copy.goWiggle(); copy.wiggler.currentShiftX = targetBall.wiggler.currentShiftX; copy.wiggler.currentShiftY = targetBall.wiggler.currentShiftY; copy.wiggler.currentPerpendicularAngle = targetBall.wiggler.currentPerpendicularAngle; copy.wiggler.currentStepNumber = targetBall.wiggler.currentStepNumber; } return copy; }
private static void hitTestFieldSides(AroundCellData nearByCellsData, Ball ball, FieldSimulation field, bool shieldProtection) { if (ballAtCriticalZone(ball, field) && ball.goingDown) //currentCellJ > 25 so no unnecessary hittesting { field.saveCriticalHitForNPC(); if (ball.x > field.bouncer.x && ball.x < (field.bouncer.x + field.bouncer.currentWidth)) //hit panel { Console.WriteLine("[Hit panel]: " + field.bouncer.x + " : " + ball.x + " " + ball.y + " tick: " + field.ballsManager.currentTick + (field is NPCFieldSimulation ? " [NPC] " : " [Player] ")); ball.bounceOff(false, (ball.x - field.bouncer.x) / field.bouncer.currentWidth); if (ball.stealthMode) ball.goOutOfStealth(); } else if (shieldProtection) { Console.WriteLine("YYYY: shield protection on. tick: " + field.ballsManager.currentTick); if (ball.y + GameConfig.BALL_RADIUS >= field.bouncer.y + GameConfig.BOUNCER_WATER_DEPTH) { Console.WriteLine("YYYY: shield protection on and bounce off at: " + ball.y + " tick: " + field.ballsManager.currentTick); ball.bounceOff(false); if (ball.stealthMode) ball.goOutOfStealth(); } } else { Console.WriteLine("[Missed panel]: " + field.bouncer.x + " : " + ball.x + " " + ball.y + " tick: " + field.ballsManager.currentTick + (field is NPCFieldSimulation ? " [NPC] " : " [Player] ")); ball.die(); } if (!shieldProtection) ball.y = field.bouncer.y - GameConfig.BALL_RADIUS; //making sure ball will bounce off always from the same point } else if ((nearByCellsData.leftBorderNearby && ball.x - GameConfig.BALL_RADIUS <= 0 && ball.goingLeft) || (nearByCellsData.rightBorderNearby && (ball.x + GameConfig.BALL_RADIUS) >= GameConfig.FIELD_WIDTH_PX && ball.goingRight)) ball.bounceOff(true); else if (nearByCellsData.topBorderNearby && ball.y - GameConfig.BALL_RADIUS <= 0 && ball.goingUp) ball.bounceOff(false); }
private static bool ballAtCriticalZone(Ball ball, FieldSimulation field) { return ball.y + GameConfig.BALL_RADIUS >= field.bouncer.y; }
public LaserShotsManager(FieldCells cellsLink, Bouncer bouncerLink, FieldSimulation sim) { _cellsLink = cellsLink; _bouncerLink = bouncerLink; _fieldLink = sim; }
public BallsManager(FieldSimulation fieldLink) { _fieldLink = fieldLink; _bouncyShield = new BouncyShield(); }
protected virtual void initFieldSimulation(string mapsProgram) { sim = new FieldSimulation(mapsProgram, this); }