extends Node2D class_name Fight2D const BLOCK_TAG_LABEL = preload("res://scene/_2d_fight/block_tag_label.tscn") const _2D_ACTION_CHOICE = preload("res://scene/_2d_fight/2d_action_choice.tscn") #网格寻路系统 var astar:AStarGrid2D=AStarGrid2D.new() ##当前使用的tilemap的范围开始 @export var tile_map_area_from:Vector2i ##当前使用的tilemap的范围结束 @export var tile_map_area_to:Vector2i ##color block的颜色指示 enum ColorBlockSetColor{ BLACK=0, BLUE=1, GREEN=2, RED=3, WHITE=4, YELLOW=5 } #镜头部分 #镜头速度 var camera_speed:float=1000 #镜头模式 enum CameraMode{ #wsad自由移动 FREE=0, #镜头放大,并且进行一个平滑位移 FOCUS=1 } ##相机模式 @export var camera_mode:CameraMode=CameraMode.FREE ##相机基础缩放乘数 @export var camera_base_zoom_scale:Vector2 ##当前聚焦的相机对象 @export var camera_focusmode_focus_target:Node2D: set(val): if camera_mode==CameraMode.FOCUS and val!=camera_focusmode_focus_target: if camera_focus_mode_focus_tween!=null: camera_focus_mode_focus_tween.kill() camera_focus_mode_focus_tween=create_tween() camera_focus_mode_focus_tween.tween_property(%main_camera,"global_position",val.global_position,camera_focus_mode_focus_time) camera_focus_mode_focus_tween.set_parallel() camera_focus_mode_focus_tween.tween_property(%main_camera,"zoom",camera_base_zoom_scale*camera_focus_mode_focus_scale,camera_focus_mode_focus_time) camera_focusmode_focus_target=val pass #聚焦模式下相机的tween补间动画 var camera_focus_mode_focus_tween #相机聚焦所用时间 var camera_focus_mode_focus_time:float=0.2 #相机聚焦倍率 var camera_focus_mode_focus_scale:float=1.5 ##地块Block部分 #全局地块数据引用 #Vector2i:Array[BaseBlock] var global_block_data:Dictionary={ } #友方单位(需要自己做出行动选择的) var friendly_side:Array[UnitBlock]=[] #敌方单位(自动进行行动选择的) var enermy_side:Array[UnitBlock]=[] var now_use_block:UnitBlock var now_use_action:int=-1: set(val): if now_use_action!=val: match val: -1: %color_block.clear() %select.clear() %panel_container.change_open(true) var block_action:BlockAction=now_use_block.could_use_action[now_use_action] block_action.del_action_with_target() _: print("尝试进行行动") var block_action:BlockAction=now_use_block.could_use_action[val] print(block_action.need_target) if block_action.need_target: var res=block_action.get_action_could_use_block(now_use_block,Rect2i(tile_map_area_from,tile_map_area_to-tile_map_area_from),global_block_data) print(res) show_color_block(res) %panel_container.change_open(false) pass now_use_action=val pass var now_index:int=0 func turn(): now_index=-1 for i in global_block_data.keys(): var arr=global_block_data[i] for j in arr: if j is BaseBlock: j.turn() next() pass var character_block_tween func next(): if %left_character_drawer.is_open: close_left_character() for i in %choice_add_pos.get_children(): i.queue_free() now_index+=1 now_use_action=-1 if now_index>=friendly_side.size(): turn() return var now_block:UnitBlock=friendly_side[now_index] now_use_block=now_block if character_block_tween!=null: character_block_tween.kill() character_block_tween=create_tween() character_block_tween.tween_property(%main_camera,"global_position",now_block.position,0.2) show_left_character({}) var choice_arr=now_block.get_all_choice() for i in range(choice_arr.size()): var new_btn=_2D_ACTION_CHOICE.instantiate() new_btn.pressed.connect(select_choice.bind(i)) new_btn.text=choice_arr[i] %choice_add_pos.add_child(new_btn) %action.modulate.a=0 %action.show() var tween=create_tween() tween.tween_property(%action,"modulate:a",1,0.2) pass func select_choice(index:int): print(index) now_use_action=index pass func _ready() -> void: Global.now_2d_fight_scene=self astar.default_compute_heuristic=AStarGrid2D.HEURISTIC_MANHATTAN astar.default_estimate_heuristic=AStarGrid2D.HEURISTIC_MANHATTAN astar.diagonal_mode=AStarGrid2D.DIAGONAL_MODE_NEVER astar.region=Rect2i(tile_map_area_from,tile_map_area_to-tile_map_area_from) astar.update() update_astar_from_walkable_map() for i in range(10): add_block(Vector2i(i,i),Database.get_block("wall"),2) for i in range(10): add_block(Vector2i(i,i+1),Database.get_block("test_character"),0) #for i in range(10): #add_block(Vector2i(i,i+2),Database.get_block("test_character"),1) turn() #从可行走tilemap图中同步到astar寻路中 func update_astar_from_walkable_map(): for i in range(tile_map_area_from.x,tile_map_area_to.x): for j in range(tile_map_area_from.y,tile_map_area_to.y): var crood=Vector2i(i,j) var tile_data=%walkable.get_cell_tile_data(crood) if tile_data !=null and tile_data.get_custom_data("walkable"): astar.set_point_solid(crood,false) else: astar.set_point_solid(crood,true) astar.update() #获取两点之间的最短可达路径,返回一个数组,0下标未是否可达,1下标为距离,2下标为途径点数组 func get_walkable_path(from:Vector2i,to:Vector2i)->Array: #如果不在要求的tilemap范围内,则返回不可达 if to.xtile_map_area_to.x or to.ytile_map_area_to.y: return [false,0,null] var arr=astar.get_id_path(from,to) if arr==null or (arr is Array and arr.size()<=0): return [false,0,null] return [true,arr.size()-1,arr] #上一帧的缓存 var before_mouse_block:Vector2i=Vector2i.ZERO func _process(delta: float) -> void: match camera_mode: CameraMode.FREE: var input=Input.get_vector("a","d","w","s").normalized() %main_camera.position+=input*delta*camera_speed CameraMode.FOCUS: pass #测试角色移动 if Input.is_action_just_pressed("mouse_left"): print("click") if now_use_action!=-1: var crood=%block_add_pos.local_to_map(get_global_mouse_position()) var now_action:BlockAction=now_use_block.could_use_action[now_use_action] var res=now_action.block_use_action(now_use_block,Rect2i(tile_map_area_from,tile_map_area_to-tile_map_area_from),global_block_data,crood) if res: now_use_action=-1 else: var crood=%block_add_pos.local_to_map(get_global_mouse_position()) if crood!=before_crood: before_index=0 if global_block_data.has(crood): var arr=global_block_data[crood] if arr.size()==0: close_block_mes() else: var block:BaseBlock=arr[before_index] pop_up_block_mes(block.block_name,block.block_attribute) else: close_block_mes() pass if Input.is_action_just_pressed("esc"): now_use_action=-1 #上一次展示的block信息 var before_crood:Vector2i=Vector2i.ZERO #上一次弹出地块信息的层级 var before_index:int=0 func _input(event: InputEvent) -> void: if event is InputEventMouseMotion: var mouse_pos=get_global_mouse_position() var crood=%mouse_block.local_to_map(mouse_pos) update_mouse_block(crood) if before_mouse_block!=crood: before_mouse_block=crood draw_action(crood) func draw_action(target:Vector2i): if now_use_action==-1: return if not now_use_block is UnitBlock: return var block_action:BlockAction=now_use_block.could_use_action[now_use_action] print(block_action.need_target) if block_action.need_target: block_action.draw_action_with_target(now_use_block,Rect2i(tile_map_area_from,tile_map_area_to-tile_map_area_from),global_block_data,target,%block_add_pos) #更新鼠标显示 func update_mouse_block(pos:Vector2i,area:Rect2i=Rect2i(0,0,0,0)): %mouse_block.clear() var area_right=area.position+area.size for i in range(area.position.x,area_right.x+1): for j in range(area.position.y,area_right.y+1): var offset=Vector2i(i,j) %mouse_block.set_cell(pos+offset,0,Vector2i(0,0)) pass func add_block(pos:Vector2i,scene:PackedScene,queue): var instance:BaseBlock=scene.instantiate() instance.block_pos=pos instance.request_block_move.connect(move_block.bind(instance)) %block_add_pos.add_child(instance) match queue: 0: friendly_side.append(instance) 1: enermy_side.append(instance) add_block_to_data(instance,pos) #移动block实例到指定位置 func move_block(from_pos:Vector2i,to_pos:Vector2i,block_instance:BaseBlock): if not global_block_data.has(from_pos): return var arr:Array=global_block_data[from_pos] if not block_instance in arr: return arr.pop_at(arr.find(block_instance)) if not global_block_data.has(to_pos): global_block_data[to_pos]=[block_instance] else: global_block_data[to_pos].append(block_instance) pass #将block的引用添加到全局字典中 func add_block_to_data(block:BaseBlock,pos:Vector2i): if not global_block_data.has(pos): global_block_data[pos]=[block] else: global_block_data[pos].append(block) pass pass func show_color_block(arr:Array): var veci_arr:Array[Vector2i]=[] %select.clear() for i in range((tile_map_area_to-tile_map_area_from).x+1): for j in range((tile_map_area_to-tile_map_area_from).y+1): var offset=Vector2i(i,j) var real_pos=tile_map_area_from+offset if arr[i][j]: %color_block.set_cell(tile_map_area_from+offset,ColorBlockSetColor.GREEN,Vector2i(0,0)) veci_arr.append(Vector2i(real_pos.x,real_pos.y)) else: %color_block.set_cell(tile_map_area_from+offset,ColorBlockSetColor.RED,Vector2i(0,0)) %select.set_cells_terrain_connect(veci_arr,0,0) pass func _on_next_pressed() -> void: next() pass # Replace with function body. func _on_pop_1_pressed() -> void: %block_drawer.change_open(true) pass # Replace with function body. func _on_pop_2_pressed() -> void: %left_character_drawer.change_open(true) pass # Replace with function body. func _on_pop_3_pressed() -> void: %right_character_drawer.change_open(true) pass # Replace with function body. func _on_pop_4_pressed() -> void: %alert_drawer.change_open(true) %alert_timer.start() pass # Replace with function body. func _on_alert_timer_timeout() -> void: %alert_drawer.change_open(false) pass # Replace with function body. #弹出地块信息,attribute字典应为String:bool func pop_up_block_mes(_name:String,attribute:Dictionary): %block_name.text=_name for i in %block_label_add_pos.get_children(): i.queue_free() for i in attribute.keys(): var new_tag=BLOCK_TAG_LABEL.instantiate() %block_label_add_pos.add_child(new_tag) new_tag.set_mes(i,attribute[i]) %block_drawer.change_open(true) #收起地块信息 func close_block_mes(): if %block_drawer.is_open: %block_drawer.change_open(false) pass func pop_up_choice(text:String,acc_callback:Callable,ref_callback:Callable): %choice.modulate.a=0 %choice_text.text=text ac_cal=acc_callback re_cal=ref_callback %choice.show() var tween=create_tween() tween.tween_property(%choice,"modulate:a",1,0.2) pass var ac_cal var re_cal func _on_action_close_pressed() -> void: %action.hide() pop_up_choice("是否结束本角色回合?",next,%action.show) pass # Replace with function body. func _on_choice_accept_pressed() -> void: if ac_cal is Callable: if ac_cal.is_valid(): ac_cal.call() %choice.hide() pass # Replace with function body. func _on_choice_refuse_pressed() -> void: if re_cal is Callable: if re_cal.is_valid(): re_cal.call() %choice.hide() pass # Replace with function body. #展示左边的角色信息 func show_left_character(data:Dictionary): %left_character_drawer.change_open(true) pass #展示右边的角色信息 func show_right_character(data:Dictionary): %right_character_drawer.change_open(true) pass #关闭左边的角色信息 func close_left_character(): if %left_character_drawer.is_open: %left_character_drawer.change_open(false) pass #关闭右边的角色信息 func close_right_character(): if %right_character_drawer.is_open: %right_character_drawer.change_open(false) pass