Ball implemented, started work on game AI
This commit is contained in:
92
proto2/ai/ball_game_ai3d.gd
Normal file
92
proto2/ai/ball_game_ai3d.gd
Normal file
@@ -0,0 +1,92 @@
|
||||
extends Node
|
||||
class_name BallGameAI3D
|
||||
|
||||
var _cheers = {}
|
||||
var _game_area: AABB
|
||||
var _teams = {}
|
||||
var _main
|
||||
var _state = STATE_INIT
|
||||
var _ball_instance
|
||||
var _cheer_locations = {}
|
||||
var _team_start = {}
|
||||
var _ball_carrier = null
|
||||
var _ball_team = -1
|
||||
var ch2team: Dictionary = {}
|
||||
var gate2team = {}
|
||||
var _gates = {}
|
||||
var _scores = {}
|
||||
|
||||
enum {STATE_INIT, STATE_START, STATE_RUNNING, STATE_FINISH}
|
||||
func _ready():
|
||||
_game_area = AABB()
|
||||
|
||||
func set_ball(ball: Node):
|
||||
_ball_instance = ball
|
||||
|
||||
func add_player(team: int, pl: Dictionary):
|
||||
if !_teams.has(team):
|
||||
_teams[team] = [pl]
|
||||
else:
|
||||
_teams[team].push_back(pl)
|
||||
assert pl != null
|
||||
ch2team[pl.scene] = team
|
||||
func add_cheer(team: int, ch: Dictionary):
|
||||
if !_cheers.has(team):
|
||||
_cheers[team] = [ch]
|
||||
else:
|
||||
_cheers[team].push_back(ch)
|
||||
assert ch != null
|
||||
ch2team[ch.scene] = team
|
||||
func add_cheer_game_location(team: int, loc: Vector3):
|
||||
if !_cheer_locations.has(team):
|
||||
_cheer_locations[team] = [loc]
|
||||
else:
|
||||
_cheer_locations[team].push_back(loc)
|
||||
_game_area = _game_area.expand(loc)
|
||||
func set_team_start(team: int, v: Vector3):
|
||||
_team_start[team] = v
|
||||
_game_area = _game_area.expand(v)
|
||||
func set_team_gate(team: int, gate: Area):
|
||||
_gates[team] = gate
|
||||
gate2team[gate] = team
|
||||
gate.connect("body_entered", self, "check_goal", [gate])
|
||||
var o : = gate.global_transform.origin
|
||||
_game_area = _game_area.expand(o)
|
||||
func set_main(n):
|
||||
_main = n
|
||||
func start_game():
|
||||
var ball = _ball_instance
|
||||
ball.add_to_group("ball")
|
||||
_state = STATE_START
|
||||
for t in _teams.keys():
|
||||
for ch in _teams[t]:
|
||||
assert ch != null
|
||||
print(ch)
|
||||
assert ch.scene != null
|
||||
print("start: ", _team_start[t])
|
||||
ch.scene.walkto(_team_start[t])
|
||||
var loc = 0
|
||||
for t in _cheers.keys():
|
||||
for ch in _cheers[t]:
|
||||
assert ch != null
|
||||
print(ch)
|
||||
assert ch.scene != null
|
||||
ch.scene.walkto(_cheer_locations[t][loc % _cheer_locations[t].size()])
|
||||
loc += 1
|
||||
for t in _teams.keys():
|
||||
_scores[t] = 0
|
||||
func stop_game():
|
||||
# for k in get_tree().get_nodes_in_group("ball"):
|
||||
# k.queue_free()
|
||||
_state = STATE_INIT
|
||||
var max_score = -1
|
||||
var winner_team = -1
|
||||
for k in _scores.keys():
|
||||
if _scores[k] > max_score:
|
||||
max_score = _scores[k]
|
||||
winner_team = k
|
||||
if winner_team >= 0:
|
||||
for e in _teams[winner_team]:
|
||||
world.increase_xp(e, min(e.xp * 2, min(100 * e.level, 1000)))
|
||||
for e in _cheers[winner_team]:
|
||||
world.increase_xp(e, min(e.xp * 2, min(200 * e.level, 2000)))
|
||||
Binary file not shown.
@@ -12,3 +12,6 @@ func _ready():
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
#func _physics_process(delta):
|
||||
# for obj in get_tree().get_nodes_in_group("characters"):
|
||||
# pass
|
||||
|
||||
@@ -27,7 +27,9 @@ func _process(delta):
|
||||
var tf_turn = Transform(Quat(Vector3(0, 1, 0), PI * 0.6 * delta))
|
||||
frame_tf *= tf_turn
|
||||
if Input.is_action_just_pressed("action1"):
|
||||
if monitored_objects.size() > 0:
|
||||
if master_node.item_right_hand:
|
||||
master_node.item_right_hand.activate()
|
||||
elif monitored_objects.size() > 0:
|
||||
var closest = monitored_objects[0]
|
||||
var dst = master_node.global_transform.origin.distance_to(closest.global_transform.origin)
|
||||
for k in monitored_objects:
|
||||
|
||||
@@ -3,6 +3,7 @@ signal room_event
|
||||
signal next_day
|
||||
signal next_period
|
||||
signal level_up
|
||||
signal start_training
|
||||
|
||||
var money: int = 2000
|
||||
var master_node
|
||||
|
||||
@@ -5,6 +5,8 @@ var skel: Skeleton
|
||||
var anim_tree: AnimationTree
|
||||
var aplay: AnimationPlayer
|
||||
const GRAVITY = Vector3(0, -9.8, 0)
|
||||
var ball_carry: Node
|
||||
var item_right_hand: Node
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
@@ -33,6 +35,7 @@ func _ready():
|
||||
anim.loop = true
|
||||
add_to_group("characters")
|
||||
add_to_group("activatable")
|
||||
ball_carry = get_children()[0].get_children()[0].get_node("item_carry/ball_carry")
|
||||
|
||||
func get_act():
|
||||
return "Talk"
|
||||
@@ -61,7 +64,12 @@ func walkto(target: Vector3, spd: float = 1.4):
|
||||
set_walk_speed(spd)
|
||||
walk()
|
||||
|
||||
func _process(delta):
|
||||
func take_object(obj):
|
||||
if obj.is_in_group("items"):
|
||||
obj.taken(self)
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
orientation = global_transform
|
||||
orientation.origin = Vector3()
|
||||
var sm: AnimationNodeStateMachinePlayback = anim_tree["parameters/base/playback"]
|
||||
@@ -84,7 +92,7 @@ func _process(delta):
|
||||
var direction: Vector3 = (next - global_transform.origin).normalized()
|
||||
var actual_direction: Vector3 = -global_transform.basis[2]
|
||||
var angle: float = Vector2(actual_direction.x, actual_direction.z).angle_to(Vector2(direction.x, direction.z))
|
||||
var tf_turn = Transform(Quat(Vector3(0, 1, 0), -angle * delta))
|
||||
var tf_turn = Transform(Quat(Vector3(0, 1, 0), -angle * min(delta * 2.0, 1.0)))
|
||||
orientation *= tf_turn
|
||||
if !_path || _path.size() == 0:
|
||||
idle()
|
||||
|
||||
@@ -78,6 +78,16 @@ script = ExtResource( 1 )
|
||||
|
||||
[node name="female_2018" parent="." instance=ExtResource( 2 )]
|
||||
|
||||
[node name="female_2018" parent="female_2018" index="0"]
|
||||
bones/132/bound_children = [ NodePath("item_carry") ]
|
||||
|
||||
[node name="item_carry" type="BoneAttachment" parent="female_2018/female_2018" index="13"]
|
||||
transform = Transform( 0.816538, -0.555132, -0.158408, 0.505615, 0.555284, 0.660309, -0.278598, -0.619263, 0.734095, 0.174373, 0.783361, -0.0350451 )
|
||||
bone_name = "wrist_R"
|
||||
|
||||
[node name="ball_carry" type="Spatial" parent="female_2018/female_2018/item_carry"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.12, 0, 0 )
|
||||
|
||||
[node name="AnimationTree" type="AnimationTree" parent="female_2018"]
|
||||
tree_root = SubResource( 14 )
|
||||
anim_player = NodePath("../female_2018/AnimationPlayer")
|
||||
|
||||
@@ -74,6 +74,15 @@ script = ExtResource( 2 )
|
||||
|
||||
[node name="male_2018" parent="." instance=ExtResource( 1 )]
|
||||
|
||||
[node name="male_g_2018" parent="male_2018" index="0"]
|
||||
bones/110/bound_children = [ NodePath("item_carry") ]
|
||||
|
||||
[node name="item_carry" type="BoneAttachment" parent="male_2018/male_g_2018" index="9"]
|
||||
transform = Transform( 0.579234, -0.742538, -0.336341, 0.736249, 0.299448, 0.606851, -0.349893, -0.59914, 0.720144, 0.334017, 1.00794, -0.175007 )
|
||||
bone_name = "wrist_R"
|
||||
|
||||
[node name="ball_carry" type="Spatial" parent="male_2018/male_g_2018/item_carry"]
|
||||
|
||||
[node name="AnimationTree" type="AnimationTree" parent="male_2018"]
|
||||
tree_root = SubResource( 13 )
|
||||
anim_player = NodePath("../male_g_2018/AnimationPlayer")
|
||||
|
||||
@@ -9,9 +9,14 @@ func _ready():
|
||||
add_to_group("activatable")
|
||||
|
||||
func get_act():
|
||||
return "Start training"
|
||||
return "Get a ball"
|
||||
func activate():
|
||||
print("Starting training...")
|
||||
print("Getting a ball...")
|
||||
var ball_st = load("res://items/ball/ball.tscn").instance()
|
||||
get_node("/root/main").add_child(ball_st)
|
||||
ball_st.global_transform = world.master_node.global_transform
|
||||
ball_st.global_transform.origin += ball_st.global_transform.xform(Vector3(0, 0.5, -0.25))
|
||||
ball_st.taken(world.master_node)
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
importer="scene"
|
||||
type="PackedScene"
|
||||
path="res://.import/ball.escn-c244a295d2ddfac47ce2708f1bcb6791.scn"
|
||||
path="res://.import/ball.escn-8722f09c6da73e6847feb641eaa35784.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://ball/ball.escn"
|
||||
dest_files=[ "res://.import/ball.escn-c244a295d2ddfac47ce2708f1bcb6791.scn" ]
|
||||
source_file="res://items/ball/ball.escn"
|
||||
dest_files=[ "res://.import/ball.escn-8722f09c6da73e6847feb641eaa35784.scn" ]
|
||||
|
||||
[params]
|
||||
|
||||
43
proto2/items/ball/ball.gd
Normal file
43
proto2/items/ball/ball.gd
Normal file
@@ -0,0 +1,43 @@
|
||||
extends Item
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
func _taken_act(pobj):
|
||||
mode = RigidBody.MODE_KINEMATIC
|
||||
collision_layer = 16
|
||||
collision_mask = 16 | 2
|
||||
get_parent().remove_child(self)
|
||||
if pobj.is_in_group("characters"):
|
||||
pobj.ball_carry.add_child(self)
|
||||
transform = Transform()
|
||||
pobj.item_right_hand = self
|
||||
remove_from_group("activatable")
|
||||
else:
|
||||
pobj.add_child(self)
|
||||
transform = Transform()
|
||||
set_as_toplevel(false)
|
||||
is_at_hands = true
|
||||
func _dropped_act(pobj):
|
||||
._dropped_act(get_parent())
|
||||
pobj.item_right_hand = null
|
||||
add_to_group("activatable")
|
||||
|
||||
func get_take_act():
|
||||
return "Take ball"
|
||||
|
||||
func get_drop_act():
|
||||
return "Drop ball"
|
||||
|
||||
func activate():
|
||||
if is_at_hands:
|
||||
dropped(world.master_node)
|
||||
world.emit_signal("start_training", self)
|
||||
15
proto2/items/ball/ball.tscn
Normal file
15
proto2/items/ball/ball.tscn
Normal file
@@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://items/ball/ball.gd" type="Script" id=1]
|
||||
[ext_resource path="res://items/ball/ball.escn" type="PackedScene" id=2]
|
||||
|
||||
[sub_resource type="SphereShape" id=1]
|
||||
radius = 0.25
|
||||
|
||||
[node name="ball" type="RigidBody"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="ball" parent="." instance=ExtResource( 2 )]
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||
shape = SubResource( 1 )
|
||||
68
proto2/items/item.gd
Normal file
68
proto2/items/item.gd
Normal file
@@ -0,0 +1,68 @@
|
||||
extends RigidBody
|
||||
class_name Item
|
||||
|
||||
var _taken: bool = false
|
||||
var _taken_by: Object
|
||||
var _dropped: bool = false
|
||||
var _dropped_by: Object
|
||||
var is_at_hands: bool = false
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
add_to_group("activatable")
|
||||
|
||||
func get_take_act():
|
||||
return "Take item"
|
||||
|
||||
func get_drop_act():
|
||||
return "Drop item"
|
||||
|
||||
func get_act():
|
||||
if is_at_hands:
|
||||
return get_drop_act()
|
||||
else:
|
||||
return get_take_act()
|
||||
func activate():
|
||||
if is_at_hands:
|
||||
dropped(world.master_node)
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
func _taken_act(pobj):
|
||||
mode = RigidBody.MODE_KINEMATIC
|
||||
collision_layer = 16
|
||||
collision_mask = 16 | 2
|
||||
get_parent().remove_child(self)
|
||||
pobj.add_child(self)
|
||||
transform = Transform()
|
||||
set_as_toplevel(false)
|
||||
is_at_hands = true
|
||||
func _dropped_act(pobj):
|
||||
mode = RigidBody.MODE_RIGID
|
||||
collision_layer = 1
|
||||
collision_mask = 1 | 2
|
||||
get_parent().remove_child(self)
|
||||
world.master_node.get_node("/root/main").add_child(self)
|
||||
global_transform = pobj.global_transform
|
||||
set_as_toplevel(true)
|
||||
is_at_hands = false
|
||||
func _physics_process(delta):
|
||||
if _taken:
|
||||
_taken_act(_taken_by)
|
||||
_taken = false
|
||||
_taken_by = null
|
||||
if _dropped:
|
||||
_dropped_act(_dropped_by)
|
||||
_dropped = false
|
||||
_dropped_by = null
|
||||
func taken(pobj):
|
||||
_taken = true
|
||||
_taken_by = pobj
|
||||
func dropped(pobj):
|
||||
_dropped = true
|
||||
_dropped_by = pobj
|
||||
@@ -6,8 +6,11 @@ extends Spatial
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
var frame_tf: Transform = Transform()
|
||||
var ball_game : BallGameAI3D
|
||||
|
||||
func master_control(pos):
|
||||
var n = lerp(world.master_node.get_walk_speed(), 3.8, 0.1)
|
||||
world.master_node.set_walk_speed(n)
|
||||
$master.walkto(pos)
|
||||
|
||||
func update_quests():
|
||||
@@ -28,6 +31,35 @@ func start_interaction(obj):
|
||||
else:
|
||||
obj.activate()
|
||||
|
||||
func start_training(ball):
|
||||
print("start training")
|
||||
ball_game = BallGameAI3D.new()
|
||||
var t0 = $team0
|
||||
var t1 = $team1
|
||||
for k in t0.get_children():
|
||||
if k.name.begins_with("cheer"):
|
||||
ball_game.add_cheer_game_location(0, k.global_transform.origin)
|
||||
elif k.name == "start":
|
||||
ball_game.set_team_start(0, k.global_transform.origin)
|
||||
elif k.name == "gate":
|
||||
ball_game.set_team_gate(0, k)
|
||||
for k in t1.get_children():
|
||||
if k.name.begins_with("cheer"):
|
||||
ball_game.add_cheer_game_location(1, k.global_transform.origin)
|
||||
elif k.name == "start":
|
||||
ball_game.set_team_start(1, k.global_transform.origin)
|
||||
elif k.name == "gate":
|
||||
ball_game.set_team_gate(1, k)
|
||||
for ch in world.cheer_team.keys():
|
||||
assert world.cheer_team[ch] != null
|
||||
ball_game.add_cheer(randi() % 2, world.cheer_team[ch])
|
||||
for ch in world.team.keys():
|
||||
assert world.team[ch] != null
|
||||
ball_game.add_player(randi() % 2, world.team[ch])
|
||||
ball_game.set_ball(ball)
|
||||
ball_game.set_main(self)
|
||||
ball_game.start_game()
|
||||
|
||||
func _ready():
|
||||
$master.add_to_group("master")
|
||||
controls.master_node = $master
|
||||
@@ -79,6 +111,7 @@ func _ready():
|
||||
quest_timer.connect("timeout", self, "update_quests")
|
||||
quest_timer.start()
|
||||
controls.connect("action1", self, "start_interaction")
|
||||
world.connect("start_training", self, "start_training")
|
||||
|
||||
func _process(delta):
|
||||
var pos = $master.global_transform.origin
|
||||
|
||||
104
proto2/main.tscn
104
proto2/main.tscn
File diff suppressed because one or more lines are too long
@@ -14,6 +14,16 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"path": "res://ai/ball_game_ai.gd"
|
||||
}, {
|
||||
"base": "Node",
|
||||
"class": "BallGameAI3D",
|
||||
"language": "GDScript",
|
||||
"path": "res://ai/ball_game_ai3d.gd"
|
||||
}, {
|
||||
"base": "RigidBody",
|
||||
"class": "Item",
|
||||
"language": "GDScript",
|
||||
"path": "res://items/item.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"class": "Quest",
|
||||
"language": "GDScript",
|
||||
@@ -36,6 +46,8 @@ _global_script_classes=[ {
|
||||
} ]
|
||||
_global_script_class_icons={
|
||||
"BallGameAI": "",
|
||||
"BallGameAI3D": "",
|
||||
"Item": "",
|
||||
"Quest": "",
|
||||
"QuestObjective": "",
|
||||
"StatsQuest": "",
|
||||
|
||||
Reference in New Issue
Block a user