-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbots.coffee
More file actions
97 lines (82 loc) · 2.5 KB
/
bots.coffee
File metadata and controls
97 lines (82 loc) · 2.5 KB
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
PI = Math.PI
TAU = PI * 2
repeat = (x, limit) -> x - (Math.floor x / limit) * limit
roundRange = (x, range) -> (Math.round x / range) * range
class @BotComponent
all = []
@findByOwner = (owner) ->
for comp in all
return comp if comp.doc.owner is owner
null
constructor: (ent) ->
all.push @
@doc = ent.doc
@doc.name ?= 'Robot ' + Random.id().slice(0, 4)
@doc.owner ?= null
@doc.plan ?= []
setOwner: (owner) ->
@doc.owner = owner
setName: (name) ->
Meteor.call 'botSetName', @doc._id, name
advance: (delta) ->
plan = @doc.plan
if action = plan?[0]
switch action.type
when 'walk'
doc = @doc
pos = doc.pos
target = action.pos
pos[2] = target[2]
# factor = 1 - 1 / (1 + 5 * delta)
dx = target[0] - pos[0]
dy = target[1] - pos[1]
dist = Math.sqrt dx * dx + dy * dy
if dist > 0
ang = Math.atan2 dy, dx
rot = doc.rot
rot -= roundRange rot - ang, TAU
if rot < ang
rot = Math.min ang, rot + delta
else
rot = Math.max ang, rot - delta
doc.rot = rot
angleDiff = ang - doc.rot
stepSize = 5 * Math.max 0, (Math.cos angleDiff) - 0.8
stepSize = Math.max stepSize, dist - 3
stepSize = delta * Math.min 1, stepSize
if dist > stepSize
fwdX = stepSize * Math.cos doc.rot
fwdY = stepSize * Math.sin doc.rot
# if factor < 1 then dx *= factor; dy *= factor
pos[0] += fwdX
pos[1] += fwdY
else
pos[0] = target[0]
pos[1] = target[1]
else
plan.shift()
# DB collection on server, published collection on client.
@BotDocs = new Meteor.Collection "bots"
# Entities
@Bots = new Asteroid.EntityCollection @BotDocs
@Bots.addComponent Asteroid.Transform
@Bots.addComponent BotComponent
# ES performs auto advancing on server.
@myES = new Asteroid.EntitySystem
@myES.addEntityCollection @Bots
if Meteor.isServer
Meteor.publish 'region', (x, y) ->
Bots.publish 'bots', @
Meteor.methods
moveBotTo: (x, y) ->
myBot = BotComponent.findByOwner @userId
return unless myBot
myBot.doc.plan = [
type: 'walk'
pos: [ x, y, 0 ]
]
botSetName: (_id, name) ->
bot = Bots.findById _id
return unless bot.doc.owner is @userId
return unless 1 <= name.length <= 20
bot.doc.name = name