// Instance Constructor public Raincloud() { // NEW CLOUD rng = new Random(); cloud = new Raindrop[BeatmapConstants.MAX_RAINDROPS]; NoNoRegion = new CollisionMap(); regionList = new List <CollisionNode>(); shiftList = new List <ShiftNode>(); initializeLightning(); clearMap(); for (int x = 0; x < cloud.Length; x++) { cloud[x] = new Raindrop(BeatmapConstants.MIN_HEIGHT + rng.NextDouble() * BeatmapConstants.MAX_HEIGHT, rng.NextDouble() * BeatmapConstants.MAX_FADE); } }
// Instance Constructor public Raincloud() { // NEW CLOUD rng = new Random(); cloud = new Raindrop[BeatmapConstants.MAX_RAINDROPS]; NoNoRegion = new CollisionMap(); regionList = new List<CollisionNode>(); shiftList = new List<ShiftNode>(); initializeLightning(); clearMap(); for(int x = 0; x < cloud.Length; x++) { cloud[x] = new Raindrop(BeatmapConstants.MIN_HEIGHT + rng.NextDouble() * BeatmapConstants.MAX_HEIGHT, rng.NextDouble() * BeatmapConstants.MAX_FADE); } }
// RAINDROP METHOD public void drop(int t0, int inpX, int inpY, CollisionMap NoNoRegion, bool underCollisionFlag) { // Drop function. // Currently has the droplet from top to bottom. // Initializations x = inpX; y = inpY; int t1; // Height offset is used to compensate for the height ratio scale. var heightOffset = (int)(Math.Round((BeatmapConstants.RAINDROP_HEIGHT * heightRatio / 2))); // Calculate the actual pixel velocity (rate) using constant RAINDROP_VELOCITY (time) and SCREEN_HEIGHT + heightOffset - y (distance) // This is used to help find the endtime of a droplet's movement in the event that it hits a NoNo region and prematurely stops. var endDistance = BeatmapConstants.SCREEN_HEIGHT + heightOffset; double pixelVelocity = ((double)endDistance - (double)y) / ((double)BeatmapConstants.RAINDROP_VELOCITY); // TOTALLY NEW IMPLEMENTATION ALGORITHM // Use proper indexing of X and Y // At this point, Y should be screen top. var indexX = x + (BeatmapConstants.SCREEN_LEFT * -1); var indexY = y; // To prevent Out of Range exceptions if (indexY > NoNoRegion.map.GetLength(1)) { indexY = NoNoRegion.map.GetLength(1); } else if(indexY < 0) { indexY = 0; } //var indexY = y + ((BeatmapConstants.SCREEN_TOP + BeatmapConstants.SCREEN_TOP_OFFSET) * -1); // Initialize a ySlave, which is where y will drop to (Y -> YSLAVE) int ySlave; // NEWER IMPLEMENTATION while (indexY < NoNoRegion.map.GetLength(1)) { // Initialize. // Update spot. ySlave = y; // Check for the closest NoNo region hit by iterating through the collision map until we hit a space or we hit the end of the map // Traverse the NoNo Region until we hit a NoNo space or the end of the map. while ((indexY < NoNoRegion.map.GetLength(1) && !NoNoRegion.map[indexX, indexY])) { indexY++; } // Then send a droplet to whatever that space is. // First, use indexY to make the secondary y location ySlave += indexY; // Find time t1 given rate (pixelVelocity) and distance (ySlave - y) t1 = (int)((ySlave - y) / (pixelVelocity)); // Send a droplet to that location. droplet.move(0, t0, t0 + t1, x, y, x + angleOffset, ySlave); if (underCollisionFlag) { // Check if we have to create another droplet: // The only condition to create another droplet // would be if the NoNo Region gives way to an open spot // So let's run a while loop to check for the next available spot. while ((indexY < NoNoRegion.map.GetLength(1) && NoNoRegion.map[indexX, indexY])) { indexY++; } // So now that we're here, if the droplet is at the end, then we can finish our loop. // But now we have our new location updated as this is the next available spot // from the last NoNo Region hit. This spot CAN be the bottom of the screen, to which // then this is our last iteration. y += indexY; } else { break; } } }
// RAINDROP METHOD public void drop(int t0, int inpX, int inpY, CollisionMap NoNoRegion, bool underCollisionFlag) { // Drop function. // Currently has the droplet from top to bottom. // Initializations x = inpX; y = inpY; int t1; // Height offset is used to compensate for the height ratio scale. var heightOffset = (int)(Math.Round((BeatmapConstants.RAINDROP_HEIGHT * heightRatio / 2))); // Calculate the actual pixel velocity (rate) using constant RAINDROP_VELOCITY (time) and SCREEN_HEIGHT + heightOffset - y (distance) // This is used to help find the endtime of a droplet's movement in the event that it hits a NoNo region and prematurely stops. var endDistance = BeatmapConstants.SCREEN_HEIGHT + heightOffset; double pixelVelocity = ((double)endDistance - (double)y) / ((double)BeatmapConstants.RAINDROP_VELOCITY); // TOTALLY NEW IMPLEMENTATION ALGORITHM // Use proper indexing of X and Y // At this point, Y should be screen top. var indexX = x + (BeatmapConstants.SCREEN_LEFT * -1); var indexY = y; // To prevent Out of Range exceptions if (indexY > NoNoRegion.map.GetLength(1)) { indexY = NoNoRegion.map.GetLength(1); } else if (indexY < 0) { indexY = 0; } //var indexY = y + ((BeatmapConstants.SCREEN_TOP + BeatmapConstants.SCREEN_TOP_OFFSET) * -1); // Initialize a ySlave, which is where y will drop to (Y -> YSLAVE) int ySlave; // NEWER IMPLEMENTATION while (indexY < NoNoRegion.map.GetLength(1)) { // Initialize. // Update spot. ySlave = y; // Check for the closest NoNo region hit by iterating through the collision map until we hit a space or we hit the end of the map // Traverse the NoNo Region until we hit a NoNo space or the end of the map. while ((indexY < NoNoRegion.map.GetLength(1) && !NoNoRegion.map[indexX, indexY])) { indexY++; } // Then send a droplet to whatever that space is. // First, use indexY to make the secondary y location ySlave += indexY; // Find time t1 given rate (pixelVelocity) and distance (ySlave - y) t1 = (int)((ySlave - y) / (pixelVelocity)); // Send a droplet to that location. droplet.move(0, t0, t0 + t1, x, y, x + angleOffset, ySlave); if (underCollisionFlag) { // Check if we have to create another droplet: // The only condition to create another droplet // would be if the NoNo Region gives way to an open spot // So let's run a while loop to check for the next available spot. while ((indexY < NoNoRegion.map.GetLength(1) && NoNoRegion.map[indexX, indexY])) { indexY++; } // So now that we're here, if the droplet is at the end, then we can finish our loop. // But now we have our new location updated as this is the next available spot // from the last NoNo Region hit. This spot CAN be the bottom of the screen, to which // then this is our last iteration. y += indexY; } else { break; } } }