Ball implemented, started work on game AI

This commit is contained in:
Segey Lapin
2019-07-30 13:23:34 +03:00
parent 0f1655ac81
commit 20b0ce05de
17 changed files with 400 additions and 21 deletions

View 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.

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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()

View File

@@ -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")

View File

@@ -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")

View File

@@ -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):

View File

@@ -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
View 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)

View 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
View 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

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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": "",