1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
router = require("router")
ecs = require("ecs")
world = require("world")
win = require("window")
sprites = require("world.sprites")
class FishGraphicComponent extends world.GraphicsComponent
@fish_size = 0.5
@static = false
@loctbl = {
{-1,-1}
{-1,1}
{1,1}
{1,1}
{1,-1}
{-1,-1}
}
buf_size: () =>
6
populate_buf: (geom_view, normal_view, offset) =>
@buf = geom_view
h = @@fish_size / 2
--@lamp_offset = vec4(2.5,1.4,0,0)
aspect = win.width / win.height
--@lamp = world.level.add_lamp(vec4(0,0,0,0.1 * aspect) + @lamp_offset)
for i = 1,6
loctbl = @@loctbl[i]
geom_view[i] = vec3(@@loctbl[i][1] * h, @@loctbl[i][2] * h, -1.5)
uv = sprites.player_normal
normal_view[1] = vec2(uv.s1,uv.t1)
normal_view[2] = vec2(uv.s1,uv.t2)
normal_view[3] = vec2(uv.s2,uv.t2)
normal_view[4] = vec2(uv.s2,uv.t2)
normal_view[5] = vec2(uv.s2,uv.t1)
normal_view[6] = vec2(uv.s1,uv.t1)
join: (entity) =>
super(entity)
aspect = win.width / win.height
program = @.node("use_program")
@pred = entity\get("pred")
graphic = entity\get("graphic")
assert(@pred, "Fish graphic must have a predicted component")
@node\remove(program)
@node\append(am.blend("alpha")\append(program))
@ent = entity
comp = @
move: (pos) =>
h = @@fish_size / 2
--print("Calling move with", pos)
--if @ent.state ~= "swimming"
-- error("called move while not swimming")
for i = 1,6
@buf[i] = vec3(@@loctbl[i][1] * h, @@loctbl[i][2] * h, -0.13) + vec3(pos.x, pos.y, 0)
friction = 0.1
class FishPredictedComponent extends ecs.PredictedComponent
new: (id) =>
fish_speed = 0.00001
super(id, {accel: vec2(0,0), vel: vec2(0,0), pos: vec2(0,0)}, "netc", {
accel: () =>
--print("ent state:", @cc.state)
if @cc.state ~= "swimming"
return vec2(0,0)
localized = @net.properties.next_loc - @properties.pos
--direction = math.atan(localized.y / localized.x)
math.normalize(localized + @properties.vel) * fish_speed
vel: () =>
--print("Before calculating vel, properties was ", @properties)
delta = world.sync_time! - @net.properties.next_loc_time
--print("Delta time:", delta)
(@properties.accel / friction) + ((@properties.vel - (@properties.accel / friction)) * math.exp(-friction * delta))
pos: () =>
if @properties.pos.x > 20
error("Very far, stopping")
delta = world.sync_time! - @net.properties.next_loc_time
friction_loss = @properties.accel / friction
(friction_loss * delta) - ((1/friction) * (@properties.vel - friction_loss) * (math.exp(-friction * delta))) + @properties.pos
})
@node = am.group!
join: (entity) =>
@net = entity\get("net")
@gc = entity\get("graphic")
@properties.pos = @net.properties.pos
@cc = entity\get("control")
@ent = entity
print("Got graphic component:",@gc, @gc.node)
print("And my node is", @node)
@gc.node\append(@node)
s = @
@node\action(() =>
s\forward!
)
forward: () =>
super!
if @ent.state == "catching"
@gc.node.hidden=true
else
@gc\move(@properties.pos)
class Fish extends ecs.Entity
new: (id, pos) =>
@width = 40 -- TODO: randomize fish width
components = {
pred: FishPredictedComponent("pred")
net: ecs.NetworkedComponent("net",{pos: pos, next_loc: pos, next_loc_time: am.current_time!})
graphic: FishGraphicComponent("graphic")
control: require("controllers.fish").FishControllerComponent()
phys: world.PhysicsComponent("phys",{},"circle",{pos.x, pos.y, @width / 256})
}
super(id, components)
destroy: (...) =>
super(...)
error("Where did fish go")
class SpawnFishComponent extends ecs.Component
new: (id, properties, spawnrect) =>
super(id, properties)
join: (entity) =>
graphic = entity\get("graphic")
router = router.r!
set_spawnable = () ->
if router.state == "elected"
graphic\action(() ->
error("Spawn fish callback")
)
set_spawnable!
router\onchange(set_spawnable)
{:Fish, :SpawnFishComponent}
|