Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Moisture Mechanics for Farmland in Pygame

Tech 1

When the character uses the watering tool on cultivated soil, a wet texture overlay should appear on the targeted tile. This visual indicator must be cleared upon starting a new day after sleeping.

Three distinct moisture textures are available. Upon watering a tile, one texture is selected randomly to render the damp effect. This requires importing the random choice utility alongside the custom graphics loading function.

The hydration logic mirrors the cultivation mechanism. Iterate through the group of plowed soil patches. If a patch's bounding box intersects with the watering tool's interaction coordinate, instantiate a moisture overlay sprite at that specific lcoation.

from random import choice
from support import load_graphics_folder
from settings import TILE_DIMENSIONS, RENDER_LAYERS

Farm Ground Manager Construction

Define a manager class to track the farmable grid, handle plowed patches, and manage moisture overlays.

class PlowedPatch(pygame.sprite.Sprite):
    def __init__(self, position, texture, sprite_groups):
        super().__init__(sprite_groups)
        self.image = texture
        self.rect = self.image.get_rect(topleft=position)
        self.z = RENDER_LAYERS['soil']

class MoistPatch(pygame.sprite.Sprite):
    def __init__(self, position, texture, sprite_groups):
        super().__init__(sprite_groups)
        self.image = texture
        self.rect = self.image.get_rect(topleft=position)
        self.z = RENDER_LAYERS['soil_water']

class FarmGroundManager:
    def __init__(self, global_sprites):
        self.global_sprites = global_sprites
        self.plowed_patches = pygame.sprite.Group()
        self.moist_patches = pygame.sprite.Group()
        
        self.tilled_texture = pygame.image.load('../graphics/soil/o.png')
        self.moisture_variants = load_graphics_folder('../graphics/soil_water')
        
        self.setup_plot_matrix()
        self.setup_action_zones()

Inside the manager, the hydrate_soil method processes the watering action. It must update both the visual sprites and the logical grid state by appending a 'W' flag to the corresponding matrix cell.

    def hydrate_soil(self, tool_target):
        for patch in self.plowed_patches.sprites():
            if patch.rect.collidepoint(tool_target):
                grid_col = patch.rect.x // TILE_DIMENSIONS
                grid_row = patch.rect.y // TILE_DIMENSIONS
                
                self.plot_matrix[grid_row][grid_col].append('W')
                
                spawn_pos = patch.rect.topleft
                selected_texture = choice(self.moisture_variants)
                MoistPatch(spawn_pos, selected_texture, [self.global_sprites, self.moist_patches])

When a new day begins, invoke dry_out_ground to eliminate the moisture sprites and remove the 'W' flags from the matrix, resetting the farmland for the next cycle.

    def dry_out_ground(self):
        for patch in self.moist_patches.sprites():
            patch.kill()
            
        for row in self.plot_matrix:
            for cell in row:
                if 'W' in cell:
                    cell.remove('W')

Character Tool Execution

The character class must trigger the hydration process when the watering tool is active. Calculate the interaction point and pass it to the farm manager.

class Character(pygame.sprite.Sprite):
    # ... initialization ...
    
    def execute_tool_action(self):
        current_tool = self.equipped_tools[self.tool_idx]
        
        if current_tool == 'hoe':
            self.farm_manager.plow_ground(self.tool_target)
        elif current_tool == 'axe':
            self.chop_tree(self.tool_target)
        elif current_tool == 'watering_can':
            self.farm_manager.hydrate_soil(self.tool_target)
            
    def calculate_tool_target(self):
        facing_direction = self.state.split('_')[0]
        self.tool_target = self.rect.center + TOOL_OFFSET[facing_direction]

Day Reset Sequence

Within the game scene, the day reset method handles state transitions after sleeping. This includes regrowing tree fruits and removing the moisture overlays from the previous day.

class GameScene:
    # ... setup and run methods ...
    
    def start_new_day(self):
        for tree in self.tree_sprites.sprites():
            for fruit in tree.fruit_sprites.sprites():
                fruit.kill()
            tree.spawn_fruit()
            
        self.farm_manager.dry_out_ground()

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

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