Thank you for the help but now the ocean isn't spawning in correctly. I tried making the ocean it's own layer but it over laps the islands (destroys them) I appreciated y'alls help with the color biome problem I had. It is also very laggy and I don't know how to optimise the code.
import pygame
import random
import noise
# Initialize Pygame
pygame.init()
# Screen settings
screen_width = 900
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Infinite Scrollable World")
# Color palette
colors = {
"land": (134, 168, 83), # Light green
"water": (30, 144, 255), # Deep blue
"desert": (244, 164, 96), # Sandy color
"mountains": (139, 137, 137), # Gray
"snow": (255, 250, 250), # Snow white
"forest": (34, 139, 34), # Forest green
"swamp": (105, 139, 34), # Swampy green
"beach": (238, 214, 175), # Light beige
"tundra": (192, 192, 192) # Light gray
}
# Biome definitions
biomes = {
"water": {"elevation": (0, 70), "temperature": (0.0, 1.0), "moisture": (0.0, 1.0), "color": colors["water"]},
"beach": {"elevation": (71, 100), "temperature": (0.2, 0.8), "moisture": (0.2, 0.8), "color": colors["beach"]},
"desert": {"temperature": (0.4, 1.0), "moisture": (0.0, 0.3), "elevation": (101, 200), "color": colors["desert"]},
"grassland": {"temperature": (0.2, 0.8), "moisture": (0.2, 0.6), "elevation": (101, 200), "color": colors["land"]},
"forest": {"temperature": (0.0, 0.7), "moisture": (0.5, 1.0), "elevation": (101, 200), "color": colors["forest"]},
"mountains": {"elevation": (201, 255), "temperature": (0.0, 0.5), "moisture": (0.2, 0.8), "color": colors["mountains"]},
"snow": {"temperature": (-1.0, 0.0), "moisture": (0.5, 1.0), "elevation": (256, 300), "color": colors["snow"]},
"swamp": {"temperature": (0.0, 0.7), "moisture": (0.8, 1.0), "elevation": (101, 200), "color": colors["swamp"]},
"tundra": {"temperature": (-1.0, 0.5), "moisture": (0.3, 0.6), "elevation": (201, 255), "color": colors["tundra"]}
}
# Infinite world generator (using modulo for continuous access)
def generate_world(x, y, size):
world = []
for y_ in range(y, y + size):
row = []
for x_ in range(x, x + size):
# Combine multiple Perlin noise layers
noise_ocean = noise.snoise2(x_ * 0.005, y_ * 0.005, octaves=4) # Ocean noise
noise_elevation = noise.snoise2(x_ * 0.005, y_ * 0.005, octaves=4) # Adjusted scale
noise_temperature = noise.snoise2(x_ * 0.01, y_ * 0.01, octaves=4)
noise_moisture = noise.snoise2(x_ * 0.015, y_ * 0.015, octaves=4) # Adjusted scale
ocean = int((noise_ocean + 1) * 128) # Map ocean to 0-255
elevation = int((noise_elevation + 1) * 128) # Map elevation to 0-255
temperature = min(max(noise_temperature, -1.0), 1.0) # Limit temperature to range (-1.0, 1.0)
moisture = min(max(noise_moisture, -1.0), 1.0) # Limit moisture to range (-1.0, 1.0)
# Assign biome based on elevation, temperature, and moisture
color = (0, 0, 0) # Default color
if ocean < 90: # If below water threshold, assign ocean color
color = colors["water"]
else: # Otherwise, assign biome color
for biome_name, info in biomes.items():
if elevation >= info.get("elevation", (0, 0))[0] and elevation <= info.get("elevation", (0, 0))[1] \
and temperature >= info.get("temperature", (0, 0))[0] and temperature <= info.get("temperature", (0, 0))[1] \
and moisture >= info.get("moisture", (0, 0))[0] and moisture <= info.get("moisture", (0, 0))[1]:
color = info["color"] # Assign color within the matching biome condition
break
row.append((elevation, color)) # Referencing 'color' after assignment
world.append(row)
return world
# Function to generate a new random seed for world generation
def generate_new_seed():
return random.randint(0, 1000000)
# Player movement variables
player_x = screen_width // 2
player_y = screen_height // 2
scroll_speed = 5
# World generation parameters
chunk_size = 100 # Adjustable chunk size preference
world_offset = {
"x": player_x // chunk_size, # Initial world offset adjusted based on player position
"y": player_y // chunk_size
}
# Perlin noise parameters for island generation
scale = 0.005
octaves = 4
# Set initial random seed for world generation
random_seed = generate_new_seed()
random.seed(random_seed)
# Game loop
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_n: # Press "N" key to generate a new world
random_seed = generate_new_seed()
random.seed(random_seed)
print(f"Generating new world with seed: {random_seed}")
# Player movement and world offset update
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= scroll_speed
world_offset["x"] += scroll_speed // chunk_size # Update world offset for scrolling
if keys[pygame.K_RIGHT]:
player_x += scroll_speed
world_offset["x"] -= scroll_speed // chunk_size
if keys[pygame.K_UP]:
player_y -= scroll_speed
world_offset["y"] += scroll_speed // chunk_size
if keys[pygame.K_DOWN]:
player_y += scroll_speed
world_offset["y"] -= scroll_speed // chunk_size
# Generate world chunk around player
chunk_x = (player_x - screen_width // 2 // chunk_size)
chunk_y = (player_y - screen_height // 2 // chunk_size)
world_chunk = generate_world(chunk_x, chunk_y, chunk_size)
# Clear screen and draw world chunk
screen.fill((0, 0, 0)) # Clear black background
for y in range(len(world_chunk)):
for x in range(len(world_chunk[0])):
elevation, color = world_chunk[y][x] # Unpack elevation and color tuple
rect = pygame.Rect(x * 10, y * 10, 10, 10)
pygame.draw.rect(screen, color, rect) # Use color from tuple
# Update display
pygame.display.flip()
pygame.display.update()
clock.tick(60)
pygame.quit()
Different biomes with different colors and elevations.
A quick read of your code shows a few weird things in generate_world
:
noise4
is unused (I assume it goes into the elevation
formula) - that might have a small impact on which elevations actually show up on the map;biome_name
is unused (that one's not really important, maybe you just want it around so you can use print
to debug - otherwise you can use for info in biomes.values():
);elevation
is the only variable, so there shouldn't be more than 5 biomes on screen (whichever ones come first for each of your five elevation ranges).Other than that it seems okay. I ran your code (just had to replace the noise
module with perlin_noise
because noise
wouldn't install) and got this:
If that's not what you're expecting, maybe you can update the question?