I am trying to code 3D objects in game but I do not know how to code that, I have tried making a 3D sword, how minecraft, but I does not look like that. I also tried making a player model for the P2P but it seems to not work, windows did ask me if I wanted to allow the .py file to use the internet so it is trying to communicate but it does not work. I need help with that. I removed the # Generate Shapes because my code exceeded the character limit. import pygame import math import random import socket import threading import json import platform class Player: def __init__(self, x, y, angle): self.x = x self.y = y self.z = 0 self.angle = angle self.speed = 0.1 self.rotation_speed = 3 self.is_jumping = False self.jump_height = 12 self.jump_velocity = 1.0 self.jump_z = 0 self.layer = 0 self.inventory = [None] * 5 self.selected_slot = None self.swinging_sword = False self.model_vertices = [ (-5, -5), (5, -5), (0, 10) ] def move_forward(self, maze_map): angle_rad = math.radians(self.angle) dx = math.cos(angle_rad) dy = math.sin(angle_rad) new_x = self.x + self.speed * dx new_y = self.y + self.speed * dy if self.check_collision(new_x, new_y, maze_map): if not self.check_collision(new_x, self.y, maze_map): self.x = new_x elif not self.check_collision(self.x, new_y, maze_map): self.y = new_y else: self.x = new_x self.y = new_y def move_backward(self, maze_map): angle_rad = math.radians(self.angle) dx = math.cos(angle_rad) dy = math.sin(angle_rad) new_x = self.x - self.speed * dx new_y = self.y - self.speed * dy if self.check_collision(new_x, new_y, maze_map): if not self.check_collision(new_x, self.y, maze_map): self.x = new_x elif not self.check_collision(self.x, new_y, maze_map): self.y = new_y else: self.x = new_x self.y = new_y def rotate_left(self): self.angle -= self.rotation_speed def rotate_right(self): self.angle += self.rotation_speed def jump(self): if not self.is_jumping: self.is_jumping = True self.jump_z = self.z def check_collision(self, x, y, maze_map): map_x = int(x) map_y = int(y) if 0 <= map_y < len(maze_map[self.layer]) and 0 <= map_x < len(maze_map[self.layer][0]): if maze_map[self.layer][map_y][map_x] == 1: return True else: return False else: return True # Constants WIDTH, HEIGHT = 1080,750 FOV = math.pi / 2 NUM_RAYS = 360 MAP_WIDTH = 90 MAP_HEIGHT = 90 ROOM_MIN_SIZE = 5 ROOM_MAX_SIZE = 15 NUM_ROOMS = 50 render_distance = 100 INVENTORY_SLOT_SIZE = 50 INVENTORY_X = WIDTH // 2 - (INVENTORY_SLOT_SIZE * 5) // 2 INVENTORY_Y = HEIGHT - INVENTORY_SLOT_SIZE - 10 BROADCAST_PORT = 5556 GAME_PORT = 5555 # Colors BLACK = (0, 0, 0) GRAY = (100, 100, 100) DARK_GRAY = (50, 50, 50) WHITE = (255, 255, 255) RED = (255, 0, 0, 100) GREEN = (0, 255, 0) BLUE = (0, 0, 255) SWORD_COLOR = (150, 150, 150) # Peer-to-Peer Networking class P2PClient: def __init__(self): self.peers = {} self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.host_ip = self.get_local_ip() self.hosting = False # Initially not hosting self.device_name = platform.node() self.listener_thread = threading.Thread(target=self.listen_for_peers, daemon=True) self.listener_thread.start() self.is_host = False # Add this line def get_local_ip(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip = s.getsockname()[0] s.close() return ip def broadcast_presence(self): message = json.dumps({"host": self.host_ip, "device": self.device_name}) self.socket.sendto(message.encode(), ('<broadcast>', BROADCAST_PORT)) def listen_for_peers(self): listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) listener.bind(('', BROADCAST_PORT)) while True: data, addr = listener.recvfrom(1024) if addr[0] != self.host_ip: peer_info = json.loads(data.decode()) self.peers[addr[0]] = peer_info["host"] if not self.hosting: self.connect_to_peer(peer_info["host"]) def connect_to_peer(self, peer_ip): self.host_ip = peer_ip self.is_host = False # Not the host if connected to someone else print(f"Connected to host: {peer_ip}") # Generate Shapes ##TOO LONG## # Check for room overlaps def check_overlap(new_room, existing_rooms): x1, y1, size1, _ = new_room for x2, y2, size2, _ in existing_rooms: if (x1 < x2 + size2 and x1 + size1 > x2 and y1 < y2 + size2 and y1 + size1 > y2): return True # Overlap detected return False # No overlap # Generate Rooms def generate_rooms(map_width, map_height, room_min_size, room_max_size, num_rooms): rooms =[] for _ in range(num_rooms): attempts = 0 while attempts < 100: room_type = random.choice(["rectangle", "triangle", "octagon", "pentagon", "circle", "rectangle_hollow", "circle_hollow", "ellipse", "cross","star", "trapezoid", "diamond", "plus", "hexagon", "t_shape"]) size = random.randint(room_min_size, room_max_size) x = random.randint(1, map_width - size - 1) y = random.randint(1, map_height - size - 1) new_room = (x, y, size, room_type) if not check_overlap(new_room, rooms): rooms.append(new_room) break attempts += 1 else: print("Failed to place room after 100 attempts.") return rooms # Generate Corridors def generate_corridors(rooms, world_map): corridor_segments = [] connected_rooms = {0} while len(connected_rooms) < len(rooms): unconnected_room_index = -1 connected_room_index = random.choice(list(connected_rooms)) for i in range(len(rooms)): if i not in connected_rooms: unconnected_room_index = i break if unconnected_room_index == -1: break x1, y1, _, _ = rooms[connected_room_index] x2, y2, _, _ = rooms[unconnected_room_index] while x1 != x2: world_map[y1][x1] = 0 corridor_segments.append((x1, y1)) if x1 < x2: x1 += 1 else: x1 -= 1 while y1 != y2: world_map[y1][x1] = 0 corridor_segments.append((x1, y1)) if y1 < y2: y1 += 1 else: y1 -= 1 connected_rooms.add(unconnected_room_index) return corridor_segments # Generate World Map def generate_world_map(map_width, map_height, rooms): world_map = [[[1 for _ in range(map_width)] for _ in range(map_height)] for _ in range(3)] for layer in range(3): for x, y, size, room_type in rooms: if room_type == "rectangle": for i in range(size): for j in range(size): if 0 <= x + j < MAP_WIDTH and 0 <= y + i < MAP_HEIGHT: world_map[layer][y + i][x + j] = 0 elif room_type == "triangle": generate_triangle(world_map[layer], x, y, size) elif room_type == "octagon": generate_octagon(world_map[layer], x, y, size) elif room_type == "pentagon": generate_pentagon(world_map[layer], x, y, size) elif room_type == "circle": generate_circle(world_map[layer], x, y, size // 2) elif room_type == "rectangle_hollow": generate_rectangle_hollow(world_map[layer], x, y, size, size) elif room_type == "circle_hollow": generate_circle_hollow(world_map[layer], x, y, size // 2) elif room_type == "ellipse": generate_ellipse(world_map[layer], x, y, size, size // 2) elif room_type == "cross": generate_cross(world_map[layer], x, y, size // 2, size // 4) elif room_type == "star": generate_star(world_map[layer], x, y, size, size // 3) elif room_type == "trapezoid": generate_trapezoid(world_map[layer], x, y, size, size // 2, size // 3) elif room_type == "diamond": generate_diamond(world_map[layer], x, y, size) elif room_type == "plus": generate_plus(world_map[layer], x, y, size // 2, size // 4) elif room_type == "hexagon": generate_hexagon(world_map[layer], x, y, size // 2) elif room_type == "t_shape": generate_t_shape(world_map[layer], x, y, size // 2, size // 4, size) corridor_segments = generate_corridors(rooms, world_map[layer]) for x, y in corridor_segments: if random.random() < 0.1: world_map[layer][y][x] = 2 # Ensure player spawn is not in a wall player_spawn_room = rooms[0] player_x = player_spawn_room[0] + player_spawn_room[2] // 2 player_y = player_spawn_room[1] + player_spawn_room[2] // 2 # Adjust player spawn if it's in a wall if world_map[0][int(player_y)][int(player_x)] != 0: for y_offset in range(player_spawn_room[2]): for x_offset in range(player_spawn_room[2]): test_x = player_spawn_room[0] + x_offset test_y = player_spawn_room[1] + y_offset if 0 <= test_x < MAP_WIDTH and 0 <= test_y < MAP_HEIGHT and world_map[0][int(test_y)][int(test_x)] == 0: player_x = test_x player_y = test_y break else: continue break return world_map, player_x, player_y # Export Map to TXT def export_map_to_txt(world_map, filename="world_map.txt"): with open(filename, "w") as file: for layer in world_map: for row in layer: file.write("".join(map(str, row)) + "\n") file.write("\n") # Generate Map Image def generate_map_image(world_map, filename="world_map.png"): image_width = MAP_WIDTH * 10 image_height = MAP_HEIGHT * 10 # Create a new surface map_surface = pygame.Surface((image_width, image_height)) # Define colors for map elements wall_color = pygame.Color("gray") floor_color = pygame.Color("black") corridor_color = pygame.Color("blue") # Iterate through the map and draw pixels for layer in range(len(world_map)): for y in range(len(world_map[layer])): for x in range(len(world_map[layer][y])): color = floor_color if world_map[layer][y][x] == 1: color = wall_color elif world_map[layer][y][x] == 2: color = corridor_color # Draw a rectangle for each map cell pygame.draw.rect(map_surface, color, (x * 10, y * 10, 10, 10)) # New function to draw the map in-game def draw_map(map_surface, player_x, player_y, player_angle, screen): map_x = 50 map_y = 50 map_width = MAP_WIDTH * 4 map_height = MAP_HEIGHT * 4 # Clear the area where the map will be drawn pygame.draw.rect(screen, BLACK, (map_x - 5, map_y - 5, map_width + 10, map_height + 10)) # Draw the map surface screen.blit(map_surface, (map_x, map_y)) # Draw player position on the map player_draw_x = int(player_x * 4) player_draw_y = int(player_y * 4) pygame.draw.circle(screen, RED, (map_x + player_draw_x, map_y + player_draw_y), 3) # Draw player direction indicator direction_x = player_draw_x + 8 * math.cos(math.radians(player_angle)) direction_y = player_draw_y + 8 * math.sin(math.radians(player_angle)) pygame.draw.line(screen, GREEN, (map_x + player_draw_x, map_y + player_draw_y), (map_x + int(direction_x), map_y + int(direction_y)), 2) # Function to handle map display toggle and drawing def show_map(map_surface, player, screen, show_map_flag): keys = pygame.key.get_pressed() if keys[pygame.K_m]: show_map_flag = not show_map_flag pygame.time.delay(300) if show_map_flag: draw_map(map_surface, player.x, player.y, player.angle, screen) return show_map_flag # Main Game Initialization pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Ray Casting Horror") clock = pygame.time.Clock() rooms = generate_rooms(MAP_WIDTH, MAP_HEIGHT, ROOM_MIN_SIZE, ROOM_MAX_SIZE, NUM_ROOMS) world_map, player_x, player_y = generate_world_map(MAP_WIDTH, MAP_HEIGHT, rooms) map_surface = pygame.Surface((MAP_WIDTH * 4, MAP_HEIGHT * 4)) wall_color = pygame.Color("gray") floor_color = pygame.Color("black") corridor_color = pygame.Color("blue") for layer in range(len(world_map)): for y in range(len(world_map[layer])): for x in range(len(world_map[layer][y])): color = floor_color if world_map[layer][y][x] == 1: color = wall_color elif world_map[layer][y][x] == 2: color = corridor_color pygame.draw.rect(map_surface, color, (x * 4, y * 4, 4, 4)) player = Player(player_x, player_y, 0) # Main Game Initialization pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Ray Casting Horror") clock = pygame.time.Clock() rooms = generate_rooms(MAP_WIDTH, MAP_HEIGHT, ROOM_MIN_SIZE, ROOM_MAX_SIZE, NUM_ROOMS) world_map, player_x, player_y = generate_world_map(MAP_WIDTH, MAP_HEIGHT, rooms) generate_map_image(world_map) export_map_to_txt(world_map) player = Player(player_x, player_y, 0) # Sword sword_x = random.randint(1, MAP_WIDTH - 1) sword_y = random.randint(1, MAP_HEIGHT - 1) sword_z = 2 sword_layer = 0 sword_picked_up = False sword_rotation = 0 # 3D Sword Data sword_vertices = [ (-0.5, -5, -0.5), (0.5, -5, -0.5), (0.5, 5, -0.5), (-0.5, 5, -0.5), (-0.5, -5, 0.5), (0.5, -5, 0.5), (0.5, 5, 0.5), (-0.5, 5, 0.5), (-0.5, 5, 0.5), (0.5, 5, 0.5), (0.5, 6, 0), ] sword_faces = [ (0, 1, 2), (2, 3, 0), (4, 5, 6), (6, 7, 4), (0, 4, 7), (7, 3, 0), (1, 5, 6), (6, 2, 1), (0, 1, 5), (5, 4, 0), (3, 2, 6), (6, 7, 3), (8, 9, 10), ] def calculate_normal(p1, p2, p3): """Calculates the normal vector of a triangle.""" v1 = (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]) v2 = (p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]) # Cross product normal = [ v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0] ] # Normalize the normal length = math.sqrt(normal[0]**2 + normal[1]**2 + normal[2]**2) if length != 0: normal = [n / length for n in normal] return normal # Inventory Editing inventory_editing = False # Initialize pygame pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Ray Casting Horror") clock = pygame.time.Clock() # Raycasting Engine (Integrated) def cast_rays(player_x, player_y, player_angle, maze_map, screen_width, fov): rays = [] for x in range(screen_width): ray_angle_rad = math.radians(player_angle) + fov * (x / screen_width - 0.5) intersection = perform_ray_cast(player_x, player_y, ray_angle_rad, maze_map) rays.append(intersection) return rays def perform_ray_cast(x, y, angle, maze_map): map_x = int(x) map_y = int(y) delta_dist_x = abs(1 / math.cos(angle)) if math.cos(angle) != 0 else float('inf') delta_dist_y = abs(1 / math.sin(angle)) if math.sin(angle) != 0 else float('inf') step_x = -1 if math.cos(angle) < 0 else 1 step_y = -1 if math.sin(angle) < 0 else 1 side_dist_x = (map_x + 1 - x) * delta_dist_x if step_x > 0 else (x - map_x) * delta_dist_x side_dist_y = (map_y + 1 - y) * delta_dist_y if step_y > 0 else (y - map_y) * delta_dist_y side = 0 for i in range(render_distance): if side_dist_x < side_dist_y: side_dist_x += delta_dist_x map_x += step_x side = 0 else: side_dist_y += delta_dist_y map_y += step_y side = 1 if 0 <= map_y < len(maze_map) and 0 <= map_x < len(maze_map[0]): if maze_map[map_y][map_x] == 1: distance = (side_dist_x - delta_dist_x) if side == 0 else (side_dist_y - delta_dist_y) return distance, side else: return float('inf'), 0 return float('inf'), 0 #Render function def render(): global sword_rotation screen.fill(BLACK) rays = cast_rays(player.x, player.y, player.angle, world_map[player.layer], WIDTH, FOV) for x, ray in enumerate(rays): distance, side = ray if distance == float('inf'): continue map_x = int(player.x + distance * math.cos(math.radians(player.angle) + FOV * (x / WIDTH - 0.5))) map_y = int(player.y + distance * math.sin(math.radians(player.angle) + FOV * (x / WIDTH - 0.5))) if 0 <= map_y < len(world_map[player.layer]) and 0 <= map_x < len(world_map[player.layer][0]): wall_type = world_map[player.layer][map_y][map_x] else: wall_type = 1 wall_height = int(HEIGHT / (distance + 0.0001)) color_intensity = 255 - min(distance * 80, 255) if side == 0: color = (color_intensity // 2, 0, 0) else: color = (0, color_intensity // 2, 0) wall_y_offset = (player.z * 20) if wall_type == 2: pygame.draw.line(screen, color, (x, HEIGHT / 2 + wall_y_offset), (x, HEIGHT / 2 + wall_height // 2 + wall_y_offset), 1) else: pygame.draw.line(screen, color, (x, HEIGHT / 2 - wall_height // 2 + wall_y_offset), (x, HEIGHT / 2 + wall_height // 2 + wall_y_offset), 1) floor_color = (30, 30, 30) pygame.draw.rect(screen, floor_color, (x, HEIGHT / 2 + wall_height / 2 + wall_y_offset, 1, HEIGHT // 2 - wall_y_offset),) # 3D Sword Rendering if player.selected_slot is not None and player.inventory[player.selected_slot] == "sword": sword_scale = 100 sword_x_offset = WIDTH * 0.25 sword_y_offset = HEIGHT // 2 sword_z_offset = 50 swing_frame = pygame.time.get_ticks() // 100 swing_angle = 0 if player.swinging_sword: if swing_frame % 4 == 0: swing_angle = 20 elif swing_frame % 4 == 1: swing_angle = -60 elif swing_frame % 4 == 2: swing_angle = -20 else: swing_angle = 0 rotated_vertices =[] for vertex in sword_vertices: x, y, z = vertex # Rotation rotation_x = math.radians(swing_angle) rotation_y = math.radians(sword_rotation) # Rotate around X-axis rotated_y = y * math.cos(rotation_x) - z * math.sin(rotation_x) rotated_z = y * math.sin(rotation_x) + z * math.cos(rotation_x) y, z = rotated_y, rotated_z # Rotate around Y-axis rotated_x = x * math.cos(rotation_y) + z * math.sin(rotation_y) rotated_z = -x * math.sin(rotation_y) + z * math.cos(rotation_y) x, z = rotated_x, rotated_z rotated_vertices.append((x * sword_scale + sword_x_offset, y * sword_scale + sword_y_offset + sword_z_offset, z * sword_scale)) # Project and draw faces for face in sword_faces: p1 = rotated_vertices[face[0]] p2 = rotated_vertices[face[1]] p3 = rotated_vertices[face[2]] # Calculate normal for shading normal = calculate_normal(p1, p2, p3) # Simple shading (dot product with light direction) light_direction = (0, 1, 1) dot_product = normal[0] * light_direction[0] + normal[1] * light_direction[1] + normal[2] * light_direction[2] # Calculate color intensity intensity = max(0.1, dot_product) color_intensity = int(150 * intensity) face_color = (color_intensity, color_intensity, color_intensity) # Project to 2D x1, y1 = int(p1[0]), int(p1[1]) x2, y2 = int(p2[0]), int(p2[1]) x3, y3 = int(p3[0]), int(p3[1]) pygame.draw.polygon(screen, face_color, [(x1, y1), (x2, y2), (x3, y3)]) # Render Inventory for i in range(5): rect = pygame.Rect(INVENTORY_X + i * INVENTORY_SLOT_SIZE, INVENTORY_Y, INVENTORY_SLOT_SIZE, INVENTORY_SLOT_SIZE) pygame.draw.rect(screen, GRAY, rect, 2) if player.selected_slot == i: s = pygame.Surface((INVENTORY_SLOT_SIZE - 10, INVENTORY_SLOT_SIZE - 10), pygame.SRCALPHA) s.fill(RED) screen.blit(s, (rect.x + 5, rect.y + 5)) # Inventory Editing if inventory_editing: for i in range(5): rect = pygame.Rect(INVENTORY_X + i * INVENTORY_SLOT_SIZE, INVENTORY_Y, INVENTORY_SLOT_SIZE, INVENTORY_SLOT_SIZE) pygame.draw.rect(screen, BLUE, rect, 2) if player.inventory is not None: font = pygame.font.Font(None, 20) text = font.render(player.inventory, True, WHITE) text_rect = text.get_rect(center=rect.center) screen.blit(text, text_rect) # Update the map image #update_map_image(world_map, player.x, player.y, player.angle) pygame.display.flip() # Rendering connection status def draw_connection_status(screen, p2p): font = pygame.font.Font(None, 24) if p2p.hosting or p2p.is_host: text = font.render("Host", True, WHITE) else: text = font.render(f"Joined {p2p.device_name}", True, WHITE) screen.blit(text, (WIDTH - 150, HEIGHT - 30)) # Game loop running = True show_map_flag = False p2p_client = P2PClient() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_6: player.selected_slot = 0 if event.key == pygame.K_7: player.selected_slot = 1 if event.key == pygame.K_8: player.selected_slot = 2 if event.key == pygame.K_9: player.selected_slot = 3 if event.key == pygame.K_0: player.selected_slot = 4 if event.key == pygame.K_e: inventory_editing = not inventory_editing if event.key == pygame.K_p: if sword_picked_up: continue angle_rad = math.radians(player.angle) spawn_distance = 5 new_sword_x = player.x + spawn_distance * math.cos(angle_rad) new_sword_y = player.y + spawn_distance * math.sin(angle_rad) # Check for wall collisions if 0 <= int(new_sword_y) < len(world_map[player.layer]) and 0 <= int(new_sword_x) < len(world_map[player.layer][0]): if world_map[player.layer][int(new_sword_y)][int(new_sword_x)] == 0: sword_x = new_sword_x sword_y = new_sword_y sword_layer = player.layer else: print("Cannot spawn sword inside a wall.") else: print("Cannot spawn sword outside the map.") if event.type == pygame.MOUSEBUTTONDOWN: if player.selected_slot is not None and player.inventory[player.selected_slot] == "sword": player.swinging_sword = True if event.type == pygame.MOUSEBUTTONUP: player.swinging_sword = False keys = pygame.key.get_pressed() if keys[pygame.K_w]: player.move_forward(world_map) if keys[pygame.K_s]: player.move_backward(world_map) if keys[pygame.K_a]: player.rotate_left() if keys[pygame.K_d]: player.rotate_right() if keys[pygame.K_SPACE]: player.jump() if player.is_jumping: player.z += player.jump_velocity player.jump_velocity -= 0.08 if player.z <= player.jump_z - player.jump_height or player.z <= 0: player.is_jumping = False player.jump_velocity = 1.0 player.z = max(0, int(player.z)) if player.z > 0: player.layer = min(player.layer + 1, 2) if player.z == 0 and player.is_jumping == False: if player.layer > 0: if world_map[player.layer - 1][int(player.y)][int(player.x)] == 2: player.layer -= 1 player.angle %= 360 # Sword Pickup if not sword_picked_up and player.layer == sword_layer: sword_dist_x = sword_x - player.x sword_dist_y = sword_y - player.y sword_dist = math.sqrt(sword_dist_x**2 + sword_dist_y**2) if sword_dist < 5: for i in range(5): if player.inventory is None: player.inventory = "sword" sword_picked_up = True break render() # Draw connection status draw_connection_status(screen, p2p_client) clock.tick(60) pygame.quit() Continue reading...