massively overhaul and fix:
```python
import pygame
import sys
import random

# Initialize Pygame
pygame.init()

# Set up display
WIDTH, HEIGHT = 800, 600
GRID_SIZE = 20  # Size of the grid cells
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pixel Gravity Playground")

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREY = (192, 192, 192)  # Define grey color
COLORS = [(random.randint(50, 255), random.randint(50, 255), random.randint(50, 255)) for _ in range(8)] + [(244,244,244)]
WALL_COLOR = (150, 75, 0)  # Color for wall blocks (brown)
BLUE = (0, 0, 255)  # Change to blue for build mode status

# GravityObject class
class GravityObject:
    def __init__(self, x, y, size, color):
        self.rect = pygame.Rect(x, y, size, size)
        self.color = color  # Color passed during object creation

    def update(self, objects, walls, building_mode):
        if not building_mode:  # Apply gravity only if not in building mode
            self.move_down(objects, walls)

    def move_down(self, objects, walls):
        # Check if the object can move down by one grid size
        self.rect.y += GRID_SIZE  # Move down by one grid size
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                # If collision with a wall occurs, reset the position to avoid overlap
                self.rect.y -= GRID_SIZE  # Move back up if collision detected
                break  # Stop checking further collisions
        for other in objects:
            if other != self and self.rect.colliderect(other.rect):
                # If collision occurs with another object, reset the position to avoid overlap
                self.rect.y -= GRID_SIZE  # Move back up if collision detected
                break  # Stop checking further collisions

        # Ensure the object does not go off-screen
        self.check_boundaries()

    def check_boundaries(self):
        if self.rect.y + self.rect.height > HEIGHT:  # Prevent going off-screen
            self.rect.y = HEIGHT - self.rect.height  # Reset to the bottom

    def draw(self, surface):
        pygame.draw.rect(surface, self.color, self.rect)  # Draw the object

# WallBlock class
class WallBlock:
    def __init__(self, x, y, size):
        self.rect = pygame.Rect(x, y, size, size)

    def draw(self, surface):
        pygame.draw.rect(surface, WALL_COLOR, self.rect)  # Draw the wall block

def main():
    clock = pygame.time.Clock()
    objects = []
    walls = []
    dragging = None  # Object being dragged
    building_mode = False  # Toggle for building mode
    selected_color = COLORS[0]  # Default selected color

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            # Toggle building mode with the "G" key
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_g:
                    building_mode = not building_mode  # Toggle building mode
                
                # Select color with NUM1 to NUM9
                if pygame.K_1 <= event.key <= pygame.K_9:
                    selected_color = COLORS[event.key - pygame.K_1]  # Select color based on key pressed

                # Remove pixel or wall block with the "R" key
                if event.key == pygame.K_r:
                    if dragging in objects:
                        objects.remove(dragging)  # Remove the dragged object
                    elif dragging in walls:
                        walls.remove(dragging)  # Remove the dragged wall block
                    dragging = None  # Stop dragging

            # Add new gravity objects when clicking with the left mouse button
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # Left mouse button
                    x, y = event.pos
                    if building_mode:
                        # Snap to grid when building
                        x = (x // GRID_SIZE) * GRID_SIZE
                        y = (y // GRID_SIZE) * GRID_SIZE
                        size = GRID_SIZE  # Size of the pixel objects
                        # Check if the grid space is empty before adding a new object
                        new_object = GravityObject(x, y, size, selected_color)
                        if not any(new_object.rect.colliderect(obj.rect) for obj in objects) and \
                           not any(new_object.rect.colliderect(wall.rect) for wall in walls):
                            objects.append(new_object)  # Add new object at snapped position
                    else:
                        # Add object without snapping in normal mode
                        size = GRID_SIZE  # Size of the pixel objects to maintain uniformity
                        x = (x // GRID_SIZE) * GRID_SIZE
                        y = (y // GRID_SIZE) * GRID_SIZE
                        objects.append(GravityObject(x, y, size, selected_color))

                elif event.button == 3:  # Right mouse button (for dragging)
                    for obj in objects:
                        if obj.rect.collidepoint(event.pos):
                            dragging = obj  # Set the object to drag
                            break  # Stop searching if found

                    for wall in walls:
                        if wall.rect.collidepoint(event.pos):
                            dragging = wall  # Set the wall block to drag

                elif event.button == 2:  # Middle mouse button (MMB) for removing
                    for obj in objects:
                        if obj.rect.collidepoint(event.pos):
                            objects.remove(obj)  # Remove the object on MMB click
                            break
                    for wall in walls:
                        if wall.rect.collidepoint(event.pos):
                            walls.remove(wall)  # Remove the wall on MMB click
                            break

            # Stop dragging when the right mouse button is released
            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 3:  # Right mouse button
                    # Snap the object to the grid on release
                    if dragging:
                        dragging.rect.x = (dragging.rect.x // GRID_SIZE) * GRID_SIZE
                        dragging.rect.y = (dragging.rect.y // GRID_SIZE) * GRID_SIZE
                        # Check for placement of new object
                        if not building_mode:
                            # Check if we need to add a new pixel at the released position
                            x, y = dragging.rect.topleft
                            new_object = GravityObject(x, y, GRID_SIZE, selected_color)
                            if not any(new_object.rect.colliderect(obj.rect) for obj in objects) and \
                               not any(new_object.rect.colliderect(wall.rect) for wall in walls):
                                objects.append(new_object)  # Place new object at snapped position
                    dragging = None  # Stop dragging

        # Drag the object if dragging is not None
        if dragging:
            dragging.rect.center = pygame.mouse.get_pos()  # Set object position to mouse position

        # Update and draw all gravity objects and wall blocks
        screen.fill(WHITE)  # Clear the screen
        for wall in walls:
            wall.draw(screen)  # Draw wall blocks
        for obj in objects:
            obj.update(objects, walls, building_mode)
            obj.draw(screen)

        # Display the color and build mode status
        font = pygame.font.Font(None, 36)

        # Display color index with its color
        color_index = COLORS.index(selected_color) + 1  # Get the index (1-9)
        color_text = f"color: {color_index}"  # Text to display
        index_surface = font.render(str(color_index), True, GREY if color_index == 9 else selected_color)  # Render index with grey if it's color index 9

        # Create a surface for the rest of the text
        text_surface = font.render("color: ", True, BLACK)

        # Draw the text surfaces
        screen.blit(text_surface, (10, 10))  # Draw static text
        screen.blit(index_surface, (10 + text_surface.get_width(), 10))  # Draw colored index text

        # Display build mode status
        mode_text = "Build Mode" if building_mode else None
        mode_surface = font.render(mode_text, True, BLUE)
        
        screen.blit(mode_surface, (10, 50))  # Draw build mode status

        pygame.display.flip()  # Update the display
        clock.tick(33)  # Cap the frame rate

if __name__ == "__main__":
    main()
```