challenge-editor/scene/_2d_fight/2d_fight.gd

424 lines
12 KiB
GDScript3
Raw Permalink Normal View History

2024-11-26 21:10:14 +08:00
extends Node2D
2024-12-12 19:09:32 +08:00
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")
2024-11-26 21:10:14 +08:00
#网格寻路系统
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()
2024-11-29 01:02:57 +08:00
camera_focus_mode_focus_tween.tween_property(%main_camera,"global_position",val.global_position,camera_focus_mode_focus_time)
2024-11-26 21:10:14 +08:00
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
2024-11-29 01:02:57 +08:00
##地块Block部分
#全局地块数据引用
#Vector2i:Array[BaseBlock]
var global_block_data:Dictionary={
}
#友方单位(需要自己做出行动选择的)
var friendly_side:Array[UnitBlock]=[]
2024-11-26 21:10:14 +08:00
2024-11-29 01:02:57 +08:00
#敌方单位(自动进行行动选择的)
var enermy_side:Array[UnitBlock]=[]
2024-11-26 21:10:14 +08:00
2024-11-29 01:02:57 +08:00
var now_use_block:UnitBlock
2024-11-26 21:10:14 +08:00
2024-11-29 01:02:57 +08:00
var now_use_action:int=-1:
set(val):
if now_use_action!=val:
match val:
-1:
%color_block.clear()
2024-12-09 19:59:45 +08:00
%select.clear()
2024-11-29 01:02:57 +08:00
%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
2024-12-12 19:09:32 +08:00
var character_block_tween
2024-11-29 01:02:57 +08:00
func next():
2024-12-12 19:09:32 +08:00
if %left_character_drawer.is_open:
close_left_character()
2024-11-29 01:02:57 +08:00
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
2024-12-12 19:09:32 +08:00
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({})
2024-11-29 01:02:57 +08:00
var choice_arr=now_block.get_all_choice()
for i in range(choice_arr.size()):
2024-12-12 19:09:32 +08:00
var new_btn=_2D_ACTION_CHOICE.instantiate()
2024-11-29 01:02:57 +08:00
new_btn.pressed.connect(select_choice.bind(i))
new_btn.text=choice_arr[i]
%choice_add_pos.add_child(new_btn)
2024-12-12 19:09:32 +08:00
%action.modulate.a=0
%action.show()
var tween=create_tween()
tween.tween_property(%action,"modulate:a",1,0.2)
2024-11-29 01:02:57 +08:00
pass
func select_choice(index:int):
print(index)
now_use_action=index
pass
2024-11-26 21:10:14 +08:00
func _ready() -> void:
2024-12-12 19:09:32 +08:00
Global.now_2d_fight_scene=self
2024-11-26 21:10:14 +08:00
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()
2024-11-29 01:02:57 +08:00
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()
2024-11-26 21:10:14 +08:00
#从可行走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.x<tile_map_area_from.x or to.x>tile_map_area_to.x or to.y<tile_map_area_from.y or to.y>tile_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]
2024-11-29 01:02:57 +08:00
#上一帧的缓存
var before_mouse_block:Vector2i=Vector2i.ZERO
2024-11-26 21:10:14 +08:00
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
2024-11-29 01:02:57 +08:00
#测试角色移动
2024-11-26 21:10:14 +08:00
if Input.is_action_just_pressed("mouse_left"):
print("click")
2024-11-29 01:02:57 +08:00
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
2024-12-12 19:09:32 +08:00
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
2024-11-29 01:02:57 +08:00
if Input.is_action_just_pressed("esc"):
now_use_action=-1
2024-12-12 19:09:32 +08:00
#上一次展示的block信息
var before_crood:Vector2i=Vector2i.ZERO
#上一次弹出地块信息的层级
var before_index:int=0
2024-11-29 01:02:57 +08:00
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):
2024-12-09 19:59:45 +08:00
var veci_arr:Array[Vector2i]=[]
%select.clear()
2024-11-29 01:02:57 +08:00
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)
2024-12-09 19:59:45 +08:00
var real_pos=tile_map_area_from+offset
2024-11-29 01:02:57 +08:00
if arr[i][j]:
%color_block.set_cell(tile_map_area_from+offset,ColorBlockSetColor.GREEN,Vector2i(0,0))
2024-12-09 19:59:45 +08:00
veci_arr.append(Vector2i(real_pos.x,real_pos.y))
2024-11-29 01:02:57 +08:00
else:
%color_block.set_cell(tile_map_area_from+offset,ColorBlockSetColor.RED,Vector2i(0,0))
2024-12-09 19:59:45 +08:00
%select.set_cells_terrain_connect(veci_arr,0,0)
2024-11-29 01:02:57 +08:00
pass
func _on_next_pressed() -> void:
next()
pass # Replace with function body.
2024-12-09 19:59:45 +08:00
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.
2024-12-12 19:09:32 +08:00
#弹出地块信息,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