ylliX - Online Advertising Network
Vertex AI - Antrophic and Mistral models: Why does it require Imegen access?

What is the best way to keep spacing consistent between images following each other


In the following basic code, I have centipede segments form a longer centipede class. As the first segment follows the “head” and then the second segment follows the first segment, etc. they are to be spaced exactly one segment size distance behind each other. For the most part it works but depending what speed I have them at, the spacing sometimes does not stay consistent with segments overlapping or spacing further apart when the move down and reverse direction.

What would be the best way code the spacing to keep it consistent no matter what speed it may be going?

import pygame
import random

# Initialize Pygame
pygame.init()


# Screen dimensions
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 800
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()

# Colors
BLACK = (0, 0, 0)
CYAN = (0, 255, 255)


# Centipede settings
SEGMENT_SIZE = 20

class CentipedeSegment(pygame.sprite.Sprite):
    def __init__(self, x, y, speed):
        super().__init__()
        self.image = pygame.Surface((SEGMENT_SIZE, SEGMENT_SIZE), pygame.SRCALPHA)
        pygame.draw.circle(self.image, CYAN, (SEGMENT_SIZE // 2, SEGMENT_SIZE // 2), SEGMENT_SIZE // 2)
        self.rect = self.image.get_rect(topleft=(x, y))
        # self.image = centipedes_sprites[0] 
        self.rect = self.image.get_rect(topleft=(x, y))
        self.speed = speed
        self.x_direction = 1  # 1 for right, -1 for left
        self.y_direction = SEGMENT_SIZE  # 20 for down, -20 for up
        self.move_down_next_frame = False  # Flag to control down movement after edge collision
        self.move_up_next_frame = False  # Flag to control up movement after edge collision
        self.current_frame = 0 # Set frame counter for images in list

    def update(self, mushrooms, delta_time):
        # self.image = centipedes_sprites[self.current_frame]
        # self.current_frame = (self.current_frame + 1) % len(centipedes_sprites)              
        # if self.x_direction == -1:
            # screen.blit(pygame.transform.flip(self.image, True, False),(self.rect.x,self.rect.y))
        # else:
            # screen.blit(self.image,(self.rect.x,self.rect.y))
        screen.blit(self.image,(self.rect.x,self.rect.y))   
    
        if self.move_down_next_frame:
            self.rect.y += self.y_direction
            self.move_down_next_frame = False
        if self.move_up_next_frame:
            self.move_up_next_frame = False

        # Calculate movement with delta time
        self.rect.x += int(self.speed * self.x_direction * delta_time)

        # Check for collisions with mushrooms
        for mushroom in mushrooms:
            if self.x_direction == 1 and self.rect.right >= mushroom.rect.left and self.rect.left < mushroom.rect.left and self.rect.colliderect(mushroom.rect):
                self.x_direction = -1
                self.move_down_next_frame = True
                if self.rect.y >= SCREEN_HEIGHT - 40:
                    self.y_direction *= -1  # Reverse vertical direction
                break
            elif self.x_direction == -1 and self.rect.left <= mushroom.rect.right and self.rect.right > mushroom.rect.right and self.rect.colliderect(mushroom.rect):
                self.x_direction = 1
                self.move_down_next_frame = True
                if self.rect.y >= SCREEN_HEIGHT - 40:
                    self.y_direction *= -1  # Reverse vertical direction
                break

        # Check for screen edges and toggle direction if reached
        if self.rect.left <= 0 and self.x_direction == -1:
            self.x_direction = 1
            self.move_down_next_frame = True
            if self.rect.y >= SCREEN_HEIGHT - 40:
                self.y_direction *= -1  # Reverse vertical direction
        elif self.rect.right >= SCREEN_WIDTH and self.x_direction == 1:
            self.x_direction = -1
            self.move_down_next_frame = True
            if self.rect.y >= SCREEN_HEIGHT - 40:
                self.y_direction *= -1  # Reverse vertical direction
    
        # Reverse y_direction logic
        if self.y_direction < 0:  # Moving up
            if self.rect.y <= SCREEN_HEIGHT - 120:
                for mushroom in mushrooms:
                    if self.rect.colliderect(mushroom.rect):
                        self.y_direction *= -1  # Reverse to move down when hitting a mushroom
                        self.move_up_next_frame = True
                        break
                if self.rect.left <= 0 or self.rect.right >= SCREEN_WIDTH:
                    self.y_direction *= -1  # Reverse to move down when hitting screen edges
                    self.move_up_next_frame = True


class Centipede(pygame.sprite.Sprite):
    def __init__(self, x, y, num_segments, base_speed):
        super().__init__()
        self.segments = []
        self.base_speed = base_speed
    
        # Create each segment of the centipede
        for i in range(num_segments):
            segment_x = x - i * SEGMENT_SIZE
            segment = CentipedeSegment(segment_x, y, base_speed)
            self.segments.append(segment)

    def update_speed(self):
        """Adjust speed based on the current number of segments."""
        if len(self.segments) == 1:
            speed = self.base_speed + 125 # * 1.5
        elif 2 <= len(self.segments) < 6:
            speed = self.base_speed + 75 # * 1.25
        else:
            speed = self.base_speed

        # Update each segment's speed
        for segment in self.segments:
            segment.speed = speed

    def update(self, mushrooms, delta_time):
        # Adjust speed based on segment count
        self.update_speed()

        # Update each segment in order, starting from the head
        for i, segment in enumerate(self.segments):
            segment.update(mushrooms, delta_time)
            if i > 0:
                # Align current segment based on the previous segment
                prev_segment = self.segments[i - 1]
                if segment.x_direction == prev_segment.x_direction:
                    # Ensure the current segment does not overlap or leave space from the previous segment
                    if segment.x_direction == 1:  # Moving right
                        segment.rect.x = max(segment.rect.x, prev_segment.rect.x - SEGMENT_SIZE)
                    else:  # Moving left
                        segment.rect.x = min(segment.rect.x, prev_segment.rect.x + SEGMENT_SIZE)


class Mushroom(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__() 
        self.full_height = SEGMENT_SIZE
        self.image = pygame.Surface((SEGMENT_SIZE, self.full_height))
        self.health = 3  # Mushrooms take 3 hits to destroy
        self.update_mushroom()
        self.rect = self.image.get_rect(topleft=(x, y))

    def update_mushroom(self):
        # Update the mushroom's color based on health, starting dark red and getting lighter
        red_value = min(255, 80 + (self.health * 60))  # Increase red with each hit, keeping visibility
        self.image.fill((red_value, 0, 0))

        # Adjust the visible portion of the mushroom
        height_visible = self.full_height * (self.health / 3)
        self.image = pygame.Surface((SEGMENT_SIZE, int(height_visible)))
        self.image.fill((red_value, 0, 0))

    def take_hit(self):
        # Increase health when hit and update mushroom sprite
        self.health += 1
        if self.health < 4:
            self.update_mushroom()
        else:
            self.kill()  # Remove mushroom when health reaches 4

    def update(self):
        pass  # No need for continuous updates unless needed in the future


def is_position_valid(x, y, mushrooms):
    """Check if the position (x, y) is valid (not overlapping/touching existing mushrooms)."""
    for mushroom in mushrooms:
        if mushroom.rect.colliderect(pygame.Rect(x, y, SEGMENT_SIZE, SEGMENT_SIZE)):
            return False
    return True

# Main game loop setup
# Create sprites groups
centipedes = [Centipede(200, -20, 10, 300), Centipede(240, -100, 12, 225), Centipede(200, -60, 8, 275)]
mushrooms = pygame.sprite.Group()

# Adding a few initial mushrooms ensuring no overlaps
while len(mushrooms) < 40:
    x = random.randint(20, SCREEN_WIDTH - SEGMENT_SIZE)
    if x % 20 != 0:
        x = 20 * round(x/20)
    y = random.randint(40, SCREEN_HEIGHT - (SEGMENT_SIZE * 8))
    if y % 20 != 0:
        y = 20 * round(y/20)
    if is_position_valid(x, y, mushrooms):
        mushrooms.add(Mushroom(x, y))

running = True
while running:
    delta_time = clock.tick(60) / 1000.0  # Convert milliseconds to seconds

    screen.fill(BLACK)

    # Event handling
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # Update centipedes and mushrooms
    mushrooms.update()
    for centipede in centipedes:
        centipede.update(mushrooms, delta_time)

    # Draw everything
    # for centipede in centipedes:
        # for segment in centipede.segments:
            # screen.blit(segment.image, segment.rect)
    mushrooms.draw(screen)

    pygame.display.flip()

pygame.quit()



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *