challenge-editor/scene/_2d_fight/2d_fight.gd
2024-12-09 19:59:45 +08:00

307 lines
8.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node2D
#网格寻路系统
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
func next():
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
var choice_arr=now_block.get_all_choice()
for i in range(choice_arr.size()):
var new_btn=Button.new()
new_btn.pressed.connect(select_choice.bind(i))
new_btn.text=choice_arr[i]
%choice_add_pos.add_child(new_btn)
pass
func select_choice(index:int):
print(index)
now_use_action=index
pass
func _ready() -> void:
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.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]
#上一帧的缓存
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
if Input.is_action_just_pressed("esc"):
now_use_action=-1
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.