Skip to content

Instantly share code, notes, and snippets.

@EncodeTheCode
Created May 15, 2025 08:52
Show Gist options
  • Save EncodeTheCode/2630ec7c15be855fc1892ec7b6ed7203 to your computer and use it in GitHub Desktop.
Save EncodeTheCode/2630ec7c15be855fc1892ec7b6ed7203 to your computer and use it in GitHub Desktop.
import pygame
import sys
# === CONFIGURABLE SETTINGS ===
WINDOW_WIDTH = 512
WINDOW_HEIGHT = 240
UPSCALED_WIDTH = 1920
UPSCALED_HEIGHT = 1080
FONT_SIZE = 10
TEXT_SCALE = 4
TEXT_LAYER_SCALE = 0.50
BOX_SCALE = 1.0
TEXT_OFFSET_X = 0
TEXT_OFFSET_Y = 30
BG_COLOR = (2, 6, 17) # Weapon select screen background color
BG_PADDING_X = 8
BG_PADDING_Y = 4
BG_OPACITY = 0.8
DISPLAY_DURATION = 4000
FADE_IN_DURATION = 1000
FADE_OUT_DURATION = 1000
VISIBLE_DURATION = 2000
BLUR_AMOUNT = 1
BLUR_EDGE_SIZE_OUTER = 1 # outward smudge effect
# --- Weapon Select Settings ---
weapon_select_open = False
weapon_list = [
{"name": "Knife", "image": "item\\item_bg.png"},
{"name": "Taser", "image": "item\\item_bg.png"},
{"name": "M16", "image": "item\\wpn\\m16.png"},
{"name": "Shotgun", "image": "item\\item_bg.png"},
{"name": "Sniper Rifle", "image": "item\\item_bg.png"},
{"name": "AK47", "image": "item\\item_bg.png"},
{"name": "Desert Eagle", "image": "item\\item_bg.png"},
{"name": "Beretta", "image": "item\\item_bg.png"},
{"name": "Smoke Grenade", "image": "item\\item_bg.png"},
{"name": "Gas Grenade", "image": "item\\item_bg.png"},
{"name": "Grenade", "image": "item\\item_bg.png"},
{"name": "Dragunov", "image": "item\\wpn\\dragunov.png"},
{"name": "Sniper Rifle", "image": "item\\item_bg.png"},
{"name": "Defuse Kit", "image": "item\\defuse_kit_resized_blurry.png"},
{"name": "Transponder", "image": "item\\item_bg.png"},
{"name": "Cool Item", "image": "item\\item_bg.png"}
]
current_weapon_index = 0
transition_speed = 0.1 # Controls the speed of the transition
item_height = 100 # The height of each weapon item
item_width = 150 # Fixed width for each weapon item
empty_space_size = 50 # Empty space around the weapon select
weapon_select_height = 120 # Fixed height for the weapon select screen
weapon_select_width = 500 # Fixed width for the weapon select screen
# Weapon switch delay handling
weapon_switch_delay = 320 # milliseconds
last_switch_time = 0
# === Configurable Image Size ===
wpn_img_w = (item_width) # Weapon image width
wpn_img_h = (item_height) # Weapon image height
pygame.init()
font = pygame.font.Font("visitor1.ttf", FONT_SIZE)
screen = pygame.display.set_mode((UPSCALED_WIDTH, UPSCALED_HEIGHT), pygame.RESIZABLE)
pygame.display.set_caption("Weapon Select Screen")
clock = pygame.time.Clock()
message_start_time = None
ITM_TRANSPONDER = "TRANSPONDER ACQUIRED"
ITM_DEF_KIT = "DEFUSE KIT ACQUIRED"
WPN_KNIFE = "KNIFE PICKED UP"
WPN_TASER = "TASER PICKED UP"
WPN_HGREN = "HIGH EXPLOSIVE GRENADES PICKED UP"
WPN_GGREN = "GAS GRENADES PICKED UP"
WPN_SGREN = "SMOKE GRENADES PICKED UP"
WPN_AMMO_9MM = "9MM AMMO PICKED UP"
WPN_AMMO_BERETTA = "BERETTA AMMO PICKED UP"
WPN_AMMO_DEAGLE = "DESERT EAGLE AMMO PICKED UP"
WPN_AMMO_M16 = "M16 AMMO PICKED UP"
WPN_AMMO_AK47 = "AK47 AMMO PICKED UP"
WPN_AMMO_SHOTGUN = "SHOTGUN AMMO PICKED UP"
WPN_AMMO_SNIPER = "SNIPER RIFLE AMMO PICKED UP"
WPN_AMMO_DRAGUNOV = "DRAGUNOV AMMO PICKED UP"
MSG_GT = "SYPHON FILTER: RAPID INSURGENCY"
MESSAGE = MSG_GT
# Draw background image over the screen
def load_and_cache_background(path):
img = pygame.image.load(path).convert_alpha() # Load once
return pygame.transform.scale(img, screen.get_size()) # Scale once
bg = load_and_cache_background("background.png") # Cached in memory
def draw_bg(): screen.blit(bg, (0, 0))
# Gradient generator
def generate_gradient(start, end, steps):
return [
(
start[0] + (end[0] - start[0]) * i // (steps - 1),
start[1] + (end[1] - start[1]) * i // (steps - 1),
start[2] + (end[2] - start[2]) * i // (steps - 1)
)
for i in range(steps)
]
# Create the gradient once
gradient_colors = generate_gradient((53, 82, 179), (255, 255, 255), 50)
# Load images for weapons (ensure these images are in the same directory or provide the full path)
weapon_images = {weapon['name']: pygame.image.load(weapon['image']) for weapon in weapon_list}
def scale_surface(surface, scale):
width = int(surface.get_width() * scale)
height = int(surface.get_height() * scale)
return pygame.transform.scale(surface, (width, height))
def blur_surface(surface, passes=1):
for _ in range(passes):
surface = pygame.transform.smoothscale(surface, (surface.get_width() // 2, surface.get_height() // 2))
surface = pygame.transform.smoothscale(surface, (surface.get_width() * 2, surface.get_height() * 2))
return surface
def create_outer_blur_box(rect, blur_amount, outer_spread, color):
blur_size = (rect.width + outer_spread * 2, rect.height + outer_spread * 2)
blur_surface_base = pygame.Surface(blur_size, pygame.SRCALPHA)
inner_rect = pygame.Rect(outer_spread, outer_spread, rect.width, rect.height)
pygame.draw.rect(blur_surface_base, color, inner_rect, border_radius=4)
blurred = blur_surface(blur_surface_base, blur_amount)
return blurred, blur_surface_base.get_rect(center=rect.center)
def draw_pickup_message(message, start_time_ms):
now = pygame.time.get_ticks()
elapsed = now - start_time_ms
if elapsed > DISPLAY_DURATION:
return False
if elapsed < FADE_IN_DURATION:
alpha = int((elapsed / FADE_IN_DURATION) * 255)
elif elapsed < FADE_IN_DURATION + VISIBLE_DURATION:
alpha = 255
else:
fade_out_elapsed = elapsed - (FADE_IN_DURATION + VISIBLE_DURATION)
alpha = int((1 - (fade_out_elapsed / FADE_OUT_DURATION)) * 255)
text_surf = font.render(message, True, (255, 255, 255))
shadow_surf = font.render(message, True, (0, 0, 0))
base_scale = TEXT_SCALE
full_text_scale = base_scale * TEXT_LAYER_SCALE
text_scaled = scale_surface(text_surf, full_text_scale)
shadow_scaled = scale_surface(shadow_surf, full_text_scale)
text_scaled.set_alpha(alpha)
shadow_scaled.set_alpha(alpha)
center_x = WINDOW_WIDTH // 2 + TEXT_OFFSET_X
center_y = WINDOW_HEIGHT - TEXT_OFFSET_Y
text_rect = text_scaled.get_rect(center=(center_x, center_y))
bg_rect = pygame.Rect(
text_rect.left - BG_PADDING_X,
text_rect.top - BG_PADDING_Y,
text_rect.width + BG_PADDING_X * 2,
text_rect.height + BG_PADDING_Y * 2
)
blur_box, blur_box_pos = create_outer_blur_box(bg_rect, BLUR_AMOUNT, BLUR_EDGE_SIZE_OUTER, BG_COLOR)
blur_box.set_alpha(int(alpha * BG_OPACITY))
if BOX_SCALE != 1.0:
new_size = (int(blur_box.get_width() * BOX_SCALE), int(blur_box.get_height() * BOX_SCALE))
blur_box = pygame.transform.scale(blur_box, new_size)
blur_box_pos = blur_box.get_rect(center=text_rect.center)
internal_surface = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
internal_surface.blit(blur_box, blur_box_pos)
internal_surface.blit(shadow_scaled, (text_rect.x + 2, text_rect.y + 2))
internal_surface.blit(text_scaled, text_rect.topleft)
final_surface = pygame.transform.scale(internal_surface, (UPSCALED_WIDTH, UPSCALED_HEIGHT))
screen.blit(final_surface, (0, 0))
return True
def draw_weapon_select_screen():
global current_weapon_index, item_width
# Create internal surface
internal_surface = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
# Scrollable weapons
num_weapons_on_screen = weapon_select_width // item_width # Number of items that can fit horizontally
scroll_offset = (current_weapon_index - num_weapons_on_screen // 2) * item_width
weapon_select_top = (WINDOW_HEIGHT - weapon_select_height) // 2
weapon_select_left = (WINDOW_WIDTH - weapon_select_width) // 2
weapon_select_bg_rect = pygame.Rect(
weapon_select_left,
weapon_select_top,
weapon_select_width,
weapon_select_height
)
pygame.draw.rect(internal_surface, BG_COLOR, weapon_select_bg_rect)
pygame.draw.rect(internal_surface, (255, 255, 255), weapon_select_bg_rect, 2)
# Draw weapons with seamless scrolling
for i in range(len(weapon_list)): # Ensure that every item is drawn
weapon_index = i
item_rect = pygame.Rect(
weapon_select_left + empty_space_size + i * item_width - scroll_offset,
weapon_select_top + 10,
item_width,
item_height
)
# Draw the weapon image with configurable width and height
weapon_name = weapon_list[weapon_index]["name"]
weapon_image = weapon_images.get(weapon_name)
if weapon_image:
weapon_image = pygame.transform.scale(weapon_image, (wpn_img_w, wpn_img_h)) # Scale image to custom size
internal_surface.blit(weapon_image, item_rect.topleft)
weapon_text = font.render(weapon_list[weapon_index]["name"], True, (255, 255, 255))
weapon_text_rect = weapon_text.get_rect(center=(item_rect.centerx, item_rect.bottom - 10))
internal_surface.blit(weapon_text, weapon_text_rect)
# Draw a border around the currently selected item
if weapon_index == current_weapon_index:
# Determine current color index based on time
tick = pygame.time.get_ticks()
color_index = (tick // 50) % len(gradient_colors) # change every 50ms
current_color = gradient_colors[color_index]
pygame.draw.rect(internal_surface, (255,255,255), item_rect, 1)
if (pygame.time.get_ticks() // 500) % 2 == 0: # toggle every 500ms
pygame.draw.rect(internal_surface, current_color, item_rect, 1)
if (pygame.time.get_ticks() // 1500) % 2 == 0: # toggle every 1500ms
pygame.draw.rect(internal_surface, (255,255,255), item_rect, 1)
final_surface = pygame.transform.scale(internal_surface, (UPSCALED_WIDTH, UPSCALED_HEIGHT))
screen.blit(final_surface, (0, 0))
def handle_weapon_scroll(keys, now):
global current_weapon_index, last_switch_time
if now - last_switch_time > weapon_switch_delay:
if keys[pygame.K_a]:
current_weapon_index = (current_weapon_index - 1) % len(weapon_list)
last_switch_time = now
elif keys[pygame.K_d]:
current_weapon_index = (current_weapon_index + 1) % len(weapon_list)
last_switch_time = now
def main():
global weapon_select_open, current_weapon_index, message_start_time
running = True
while running:
screen.fill((0, 0, 0))
draw_bg()
now = pygame.time.get_ticks()
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_i: # Toggle the weapon select screen
weapon_select_open = not weapon_select_open
elif event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
running = False
screen.fill((0,0,0))
pygame.quit()
sys.exit()
if message_start_time is None:
message_start_time = now
if not draw_pickup_message(MESSAGE, message_start_time):
pass
if (pygame.time.get_ticks() // 10000) % 2 == 0:
message_start_time = now
if not draw_pickup_message(MESSAGE, message_start_time):
pass
# Draw weapon select screen only if it's open
if weapon_select_open:
draw_weapon_select_screen()
# Handle weapon selection and scroll
handle_weapon_scroll(keys, now)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment