extends Node2D class_name DatawhaleOffice ## Datawhale 办公室场景 ## 游戏的主要场景 # 场景配置 const SCENE_WIDTH = 2000 const SCENE_HEIGHT = 1500 # Datawhale 品牌色 const COLOR_PRIMARY = Color(0.118, 0.565, 1.0) # 蓝色 #1E90FF const COLOR_SECONDARY = Color(0.0, 0.4, 0.8) # 深蓝 #0066CC const COLOR_ACCENT = Color(0.0, 0.749, 1.0) # 亮蓝 #00BFFF const COLOR_FLOOR = Color(0.9, 0.9, 0.9) # 浅灰色地板 const COLOR_WALL = Color(0.4, 0.4, 0.4) # 深灰色墙壁 const COLOR_FURNITURE = Color(0.545, 0.271, 0.075) # 棕色家具 # 节点引用 @onready var tile_map = $TileMap @onready var characters_container = $Characters @onready var camera = $Camera2D func _ready(): """初始化场景""" print("DatawhaleOffice scene loaded") print("Scene size: ", SCENE_WIDTH, "x", SCENE_HEIGHT) # 程序化生成场景元素 _create_scene_elements() # 设置相机限制 _setup_camera_limits() ## 创建场景元素 func _create_scene_elements(): """程序化创建场景的所有视觉元素和碰撞""" # 创建地板 _create_floor() # 创建墙壁(带碰撞) _create_walls() # 创建家具(带碰撞) _create_furniture() # 创建 Datawhale 品牌元素 _create_branding() print("Scene elements created") ## 设置相机限制 func _setup_camera_limits(): """设置相机边界,防止看到场景外""" # 计算视口尺寸(假设默认分辨率 1280x720) var viewport_width = 1280 var viewport_height = 720 # 为缩放留出更大的缓冲区,避免缩放时触碰边界造成颠簸 var buffer_x = viewport_width * 0.8 # 增加水平缓冲区 var buffer_y = viewport_height * 0.8 # 增加垂直缓冲区 # 设置更宽松的相机限制 camera.limit_left = -buffer_x camera.limit_top = -buffer_y camera.limit_right = SCENE_WIDTH + buffer_x camera.limit_bottom = SCENE_HEIGHT + buffer_y # 启用平滑跟随 camera.position_smoothing_enabled = true camera.position_smoothing_speed = 5.0 print("Camera limits set with buffer - Left: ", camera.limit_left, " Top: ", camera.limit_top, " Right: ", camera.limit_right, " Bottom: ", camera.limit_bottom) # 注意:相机的调试控制脚本已在场景文件中直接添加 # 使用 WASD/方向键移动,Q/E 缩放,R 重置 ## 获取角色容器 func get_characters_container() -> Node2D: """ 获取角色容器节点 @return: 角色容器 """ return characters_container ## 设置相机跟随目标 func set_camera_target(target: Node2D): """ 设置相机跟随的目标 @param target: 要跟随的节点(通常是玩家角色) """ if target: # 使用 RemoteTransform2D 实现平滑跟随 var remote_transform = RemoteTransform2D.new() remote_transform.remote_path = camera.get_path() remote_transform.update_position = true remote_transform.update_rotation = false remote_transform.update_scale = false target.add_child(remote_transform) print("Camera following: ", target.name) ## 获取场景尺寸 func get_scene_size() -> Vector2: """ 获取场景尺寸 @return: 场景尺寸 """ return Vector2(SCENE_WIDTH, SCENE_HEIGHT) ## 创建地板 func _create_floor(): """创建地板(纯视觉,无碰撞)""" var floor_rect = ColorRect.new() floor_rect.name = "Floor" floor_rect.size = Vector2(SCENE_WIDTH, SCENE_HEIGHT) floor_rect.color = COLOR_FLOOR floor_rect.z_index = -10 # 放在最底层 add_child(floor_rect) ## 创建墙壁 func _create_walls(): """创建墙壁(带碰撞)""" var walls_container = Node2D.new() walls_container.name = "Walls" add_child(walls_container) # 墙壁厚度 var wall_thickness = 20 # 上墙 _create_wall(walls_container, Vector2(0, 0), Vector2(SCENE_WIDTH, wall_thickness)) # 下墙 _create_wall(walls_container, Vector2(0, SCENE_HEIGHT - wall_thickness), Vector2(SCENE_WIDTH, wall_thickness)) # 左墙 _create_wall(walls_container, Vector2(0, 0), Vector2(wall_thickness, SCENE_HEIGHT)) # 右墙 _create_wall(walls_container, Vector2(SCENE_WIDTH - wall_thickness, 0), Vector2(wall_thickness, SCENE_HEIGHT)) # 内部分隔墙(创建房间) # 垂直分隔墙 _create_wall(walls_container, Vector2(800, 200), Vector2(wall_thickness, 600)) # 水平分隔墙 _create_wall(walls_container, Vector2(200, 800), Vector2(1600, wall_thickness)) ## 创建单个墙壁 func _create_wall(parent: Node2D, pos: Vector2, size: Vector2): """创建单个墙壁块""" var wall = StaticBody2D.new() wall.collision_layer = 1 # Layer 1: Walls wall.collision_mask = 0 # 视觉表现 var visual = ColorRect.new() visual.size = size visual.color = COLOR_WALL wall.add_child(visual) # 碰撞形状 var collision = CollisionShape2D.new() var shape = RectangleShape2D.new() shape.size = size collision.shape = shape collision.position = size / 2 # 中心点 wall.add_child(collision) wall.position = pos parent.add_child(wall) ## 创建家具 func _create_furniture(): """创建家具(办公桌、椅子等)""" var furniture_container = Node2D.new() furniture_container.name = "Furniture" add_child(furniture_container) # 入口区域 - 欢迎台 _create_furniture_piece(furniture_container, Vector2(100, 100), Vector2(200, 80), "Reception") # 工作区 - 办公桌(6个) for i in range(3): for j in range(2): var desk_pos = Vector2(100 + i * 250, 300 + j * 200) _create_furniture_piece(furniture_container, desk_pos, Vector2(120, 60), "Desk") # 会议区 - 会议桌 _create_furniture_piece(furniture_container, Vector2(900, 300), Vector2(400, 200), "Meeting Table") # 休息区 - 沙发 _create_furniture_piece(furniture_container, Vector2(100, 900), Vector2(300, 100), "Sofa") _create_furniture_piece(furniture_container, Vector2(100, 1050), Vector2(100, 100), "Coffee Table") ## 创建单个家具 func _create_furniture_piece(parent: Node2D, pos: Vector2, size: Vector2, label: String): """创建单个家具块""" var furniture = StaticBody2D.new() furniture.name = label furniture.collision_layer = 2 # Layer 2: Furniture furniture.collision_mask = 0 # 视觉表现 var visual = ColorRect.new() visual.size = size visual.color = COLOR_FURNITURE furniture.add_child(visual) # 碰撞形状 var collision = CollisionShape2D.new() var shape = RectangleShape2D.new() shape.size = size collision.shape = shape collision.position = size / 2 furniture.add_child(collision) furniture.position = pos parent.add_child(furniture) ## 创建品牌元素 func _create_branding(): """创建 Datawhale 品牌元素""" var branding_container = Node2D.new() branding_container.name = "Branding" branding_container.z_index = 5 # 确保品牌元素在上层 add_child(branding_container) # 1. 主 Logo 展示区(展示区中心) _create_main_logo(branding_container, Vector2(1400, 400)) # 2. 欢迎标识(入口区域) _create_welcome_sign(branding_container, Vector2(100, 50)) # 3. 成就墙(展示区) _create_achievement_wall(branding_container, Vector2(1200, 900)) # 4. 装饰性品牌元素 _create_decorative_elements(branding_container) # 5. 地板品牌标识 _create_floor_branding(branding_container) ## 创建主 Logo func _create_main_logo(parent: Node2D, pos: Vector2): """创建主 Datawhale Logo(使用真实图片)""" var logo_container = Node2D.new() logo_container.name = "MainLogo" logo_container.position = pos parent.add_child(logo_container) # Logo 路径 var logo_path = "res://assets/ui/datawhale_logo.png" # 检查 Logo 文件是否存在 if ResourceLoader.exists(logo_path): # 创建白色背景板(让蓝色 logo 更突出) var bg_panel = ColorRect.new() bg_panel.size = Vector2(450, 120) bg_panel.color = Color.WHITE bg_panel.position = Vector2(-225, -60) logo_container.add_child(bg_panel) # 添加边框效果 var border = ColorRect.new() border.size = Vector2(460, 130) border.color = COLOR_PRIMARY border.position = Vector2(-230, -65) border.z_index = -1 logo_container.add_child(border) # 使用真实的 Logo 图片 var logo_sprite = Sprite2D.new() logo_sprite.texture = load(logo_path) # 362x53 像素的 logo,缩放到合适大小 # 目标宽度约 400 像素,所以 scale = 400/362 ≈ 1.1 logo_sprite.scale = Vector2(1.1, 1.1) logo_sprite.position = Vector2(0, 0) logo_container.add_child(logo_sprite) print("✓ Datawhale logo loaded (362x53 px, scaled to fit)") else: # 如果 logo 文件不存在,使用占位符 print("⚠ Logo file not found at: ", logo_path) print(" Please place logo at: assets/ui/datawhale_logo.png") # 占位符 var placeholder = ColorRect.new() placeholder.size = Vector2(400, 60) placeholder.color = COLOR_PRIMARY placeholder.position = Vector2(-200, -30) logo_container.add_child(placeholder) var placeholder_text = Label.new() placeholder_text.text = "DATAWHALE LOGO HERE (362x53)" placeholder_text.position = Vector2(-150, -10) placeholder_text.add_theme_font_size_override("font_size", 20) placeholder_text.add_theme_color_override("font_color", Color.WHITE) logo_container.add_child(placeholder_text) # 副标题(在 logo 下方) var subtitle = Label.new() subtitle.text = "AI Learning Community" subtitle.position = Vector2(-80, 80) subtitle.add_theme_font_size_override("font_size", 18) subtitle.add_theme_color_override("font_color", COLOR_SECONDARY) logo_container.add_child(subtitle) ## 创建欢迎标识 func _create_welcome_sign(parent: Node2D, pos: Vector2): """创建入口欢迎标识(带 logo)""" var sign_container = Node2D.new() sign_container.name = "WelcomeSign" sign_container.position = pos parent.add_child(sign_container) # 标识背景(白色,让蓝色 logo 更突出) var bg = ColorRect.new() bg.size = Vector2(600, 100) bg.color = Color.WHITE sign_container.add_child(bg) # 蓝色边框 var border = ColorRect.new() border.size = Vector2(610, 110) border.color = COLOR_PRIMARY border.position = Vector2(-5, -5) border.z_index = -1 sign_container.add_child(border) # Logo(如果存在) var logo_path = "res://assets/ui/datawhale_logo.png" if ResourceLoader.exists(logo_path): var logo_sprite = Sprite2D.new() logo_sprite.texture = load(logo_path) # 小尺寸显示在欢迎标识中 logo_sprite.scale = Vector2(0.5, 0.5) # 约 181x26.5 像素 logo_sprite.position = Vector2(120, 50) sign_container.add_child(logo_sprite) # 欢迎文字 var welcome_text = Label.new() welcome_text.text = "Welcome to" welcome_text.position = Vector2(20, 15) welcome_text.add_theme_font_size_override("font_size", 20) welcome_text.add_theme_color_override("font_color", COLOR_SECONDARY) sign_container.add_child(welcome_text) # Office 文字 var office_text = Label.new() office_text.text = "Office" office_text.position = Vector2(250, 50) office_text.add_theme_font_size_override("font_size", 24) office_text.add_theme_color_override("font_color", COLOR_SECONDARY) sign_container.add_child(office_text) ## 创建成就墙 func _create_achievement_wall(parent: Node2D, pos: Vector2): """创建成就展示墙""" var wall_container = Node2D.new() wall_container.name = "AchievementWall" wall_container.position = pos parent.add_child(wall_container) # 墙面背景 var wall_bg = ColorRect.new() wall_bg.size = Vector2(600, 450) wall_bg.color = Color(0.95, 0.95, 0.95) wall_container.add_child(wall_bg) # 顶部 Logo var logo_path = "res://assets/ui/datawhale_logo.png" if ResourceLoader.exists(logo_path): var logo_sprite = Sprite2D.new() logo_sprite.texture = load(logo_path) logo_sprite.scale = Vector2(0.6, 0.6) # 约 217x32 像素 logo_sprite.position = Vector2(300, 30) wall_container.add_child(logo_sprite) # 标题 var title = Label.new() title.text = "Our Achievements" title.position = Vector2(200, 60) title.add_theme_font_size_override("font_size", 24) title.add_theme_color_override("font_color", COLOR_PRIMARY) wall_container.add_child(title) # 成就卡片 var achievements = [ {"title": "10K+ Members", "icon_color": COLOR_PRIMARY}, {"title": "500+ Projects", "icon_color": COLOR_SECONDARY}, {"title": "100+ Courses", "icon_color": COLOR_ACCENT}, {"title": "AI Excellence", "icon_color": COLOR_PRIMARY} ] for i in range(achievements.size()): @warning_ignore("integer_division") var row = i / 2 # 整数除法 var col = i % 2 var card_pos = Vector2(50 + col * 280, 110 + row * 140) _create_achievement_card(wall_container, card_pos, achievements[i]) ## 创建成就卡片 func _create_achievement_card(parent: Node2D, pos: Vector2, data: Dictionary): """创建单个成就卡片""" var card = ColorRect.new() card.size = Vector2(240, 100) card.color = Color.WHITE card.position = pos parent.add_child(card) # 图标 var icon = ColorRect.new() icon.size = Vector2(60, 60) icon.color = data["icon_color"] icon.position = Vector2(20, 20) card.add_child(icon) # 文字 var text = Label.new() text.text = data["title"] text.position = Vector2(90, 35) text.add_theme_font_size_override("font_size", 18) text.add_theme_color_override("font_color", COLOR_SECONDARY) card.add_child(text) ## 创建装饰性元素 func _create_decorative_elements(parent: Node2D): """创建装饰性品牌元素""" # 蓝色装饰条纹(右侧墙面) for i in range(8): var stripe = ColorRect.new() stripe.size = Vector2(40, 200) stripe.color = COLOR_ACCENT stripe.color.a = 0.2 + (i % 3) * 0.1 # 渐变透明度 stripe.position = Vector2(1700 + i * 50, 100 + (i % 2) * 100) parent.add_child(stripe) # 品牌色圆点装饰(散布在场景中) var dot_positions = [ Vector2(500, 200), Vector2(700, 250), Vector2(900, 150), Vector2(300, 600), Vector2(600, 650), Vector2(1100, 600) ] for pos in dot_positions: var dot = ColorRect.new() dot.size = Vector2(30, 30) dot.color = COLOR_PRIMARY dot.color.a = 0.3 dot.position = pos parent.add_child(dot) ## 创建地板品牌标识 func _create_floor_branding(parent: Node2D): """在地板上创建品牌标识""" var logo_path = "res://assets/ui/datawhale_logo.png" if ResourceLoader.exists(logo_path): # 使用真实 logo 作为地板水印 var floor_logo = Sprite2D.new() floor_logo.texture = load(logo_path) floor_logo.position = Vector2(1000, 700) floor_logo.rotation = -0.1 floor_logo.scale = Vector2(3.0, 3.0) # 大尺寸水印 floor_logo.modulate.a = 0.08 # 非常淡的水印效果 floor_logo.z_index = -5 parent.add_child(floor_logo) else: # 文字水印作为后备 var floor_logo = Label.new() floor_logo.text = "DATAWHALE" floor_logo.position = Vector2(800, 600) floor_logo.rotation = -0.1 floor_logo.add_theme_font_size_override("font_size", 120) floor_logo.add_theme_color_override("font_color", COLOR_PRIMARY) floor_logo.modulate.a = 0.05 floor_logo.z_index = -5 parent.add_child(floor_logo)