Created
May 15, 2025 08:52
-
-
Save EncodeTheCode/2630ec7c15be855fc1892ec7b6ed7203 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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