Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Completing the Sleep Feature in Stardew Valley-Style Pygame

Notes 1

Purpose

When the player approaches the bed and presses Enter, the screen fades to black (then brightens). After sleeping, apples on trees regenerate (future updates: crop growth, time progression).

Code Implementation

1. Bed Interaction Detection

The TMX map’s player layer includes a bed region. Create a collision sprite (via Interaction class, inheriting Generic) to detect proximity. The sprite’s image is a placeholder (not rendered, so any size).

2. Sprite Setup (level.py)

In level.py, instantiate the bed sprite and add it to interaction_sprites (for interactive areas like beds/traders):

class Level:
    def setup(self):
        tmx_data = load_pygame('../data/map.tmx')
        # ... other layer setup (house, fence, water) ...
        # Bed sprite (from TMX 'Player' layer)
        for obj in tmx_data.get_layer_by_name('Player'):
            if obj.name == 'Bed':
                Interaction(
                    pos=(obj.x, obj.y),
                    size=(obj.width, obj.height),
                    groups=self.interaction_sprites,
                    name='Bed'
                )

3. Player Collision (player.py)

Pass interaction_sprites to the Player class. Add a is_sleeping flag too track sleep state. In input(), check for Enter key + collision:

class Player(pygame.sprite.Sprite):
    def __init__(self, pos, groups, obstacle_sprites, tree_sprites, interaction_sprites):
        super().__init__(groups)
        # ... other init ...
        self.interaction_sprites = interaction_sprites
        self.is_sleeping = False  # Sleep state

    def input(self):
        keys = pygame.key.get_pressed()
        if not self.timers['tool_use'].active and not self.is_sleeping:
            # ... movement keys (up/down/left/right) ...
            if keys[pygame.K_RETURN]:  # Enter to sleep
                collided = pygame.sprite.spritecollide(self, self.interaction_sprites, False)
                if collided:
                    sprite = collided[0]
                    if sprite.name == 'Trader':
                        pass  # Future trading
                    else:
                        self.status = 'left_idle'  # Face bed
                        self.is_sleeping = True

4. Fade Animation (transition.py)

A new Transition class (in transition.py) handles the fade. It fades to black (RGB 0) then white (255). During the fade, call regenerate_apple (reset) when black, then set is_sleeping to False when bright:

import pygame
from settings import SCREEN_WIDTH, SCREEN_HEIGHT

class Transition:
    def __init__(self, reset_callback, player):
        self.screen = pygame.display.get_surface()
        self.reset = reset_callback
        self.player = player
        self.color_value = 255  # Start with white (RGB 255,255,255)
        self.fade_speed = -2    # Fade to black first
        self.fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))

    def play(self):
        self.color_value += self.fade_speed
        # Fade to black → reverse to fade to white
        if self.color_value <= 0:
            self.fade_speed *= -1
            self.color_value = 0
            self.reset()  # Regenerate apples/tasks
        # Fade to white → reset sleep state
        if self.color_value > 255:
            self.color_value = 255
            self.player.is_sleeping = False
            self.fade_speed = -2  # Reset speed
        # Render fade effect
        self.fade_surface.fill((self.color_value, self.color_value, self.color_value))
        self.screen.blit(self.fade_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)

5. Reset Logic (level.py)

After the screen fades to black, call regenerate_apple() to re-grow apples on trees:

class Level:
    def regenerate_apple(self):
        for tree in self.tree_sprites.sprites():
            for apple in tree.apple_sprites.sprites():
                apple.kill()
            tree.regenerate_fruit()  # Tree method to create apples

    def run(self, dt):
        # ... draw/update game ...
        if self.player.is_sleeping:
            self.transition.play()

Complete Code Overview

  • player.py: Handles input, collision with the bed, and is_sleeping flag.
  • transition.py: Manages fade animation, resets apples, and updates is_sleeping.
  • level.py: Sets up sprites, runs the game loop, and triggers the transition.
  • sprites.py: Defines Interaction (bed sprite), Tree (apple regeneration), etc.

Example Code Snippets

player.py (Input Handling)

def input(self):
    keys = pygame.key.get_pressed()
    if not self.timers['tool_use'].active and not self.is_sleeping:
        # Movement logic (up/down/left/right)
        if keys[pygame.K_RETURN]:
            collided = pygame.sprite.spritecollide(self, self.interaction_sprites, False)
            if collided:
                sprite = collided[0]
                if sprite.name == 'Trader':
                    pass  # Future trading
                else:
                    self.status = 'left_idle'
                    self.is_sleeping = True

transition.py (Fade Logic)

def play(self):
    self.color_value += self.fade_speed
    if self.color_value <= 0:
        self.fade_speed *= -1
        self.color_value = 0
        self.reset()  # Regenerate apples
    if self.color_value > 255:
        self.color_value = 255
        self.player.is_sleeping = False
        self.fade_speed = -2
    self.fade_surface.fill((self.color_value, self.color_value, self.color_value))
    self.screen.blit(self.fade_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)

Final Result

When the player presses Enter near the bed, the screen fades to black (apples reset) then brightens. The is_sleeping flag is cleared, and the player "wakes up" to a new day.

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.