40 |
using namespace world; |
using namespace world; |
41 |
using namespace px; |
using namespace px; |
42 |
|
|
43 |
|
namespace |
44 |
|
{ |
45 |
|
class Signal { |
46 |
|
public: |
47 |
|
virtual ~Signal() {}; |
48 |
|
virtual void emit_from (Object *source) = 0; |
49 |
|
}; |
50 |
|
|
51 |
|
class SimpleSignal : public Signal{ |
52 |
|
public: |
53 |
|
SimpleSignal (Object *src, Object *dst, const string &msg) |
54 |
|
: source (src), dest(dst), message(msg) |
55 |
|
{} |
56 |
|
|
57 |
|
void emit_from (Object *src) { |
58 |
|
if (source == src) |
59 |
|
SendMessage (dest, message); |
60 |
|
} |
61 |
|
private: |
62 |
|
Object *source, *dest; |
63 |
|
string message; |
64 |
|
}; |
65 |
|
|
66 |
|
class SignalList { |
67 |
|
typedef vector<Signal *> ListT; |
68 |
|
ListT m_signals; |
69 |
|
|
70 |
|
public: |
71 |
|
~SignalList() { clear(); } |
72 |
|
void clear() { |
73 |
|
delete_sequence (m_signals.begin(), m_signals.end()); |
74 |
|
m_signals.clear(); |
75 |
|
} |
76 |
|
|
77 |
|
void add (Signal *sig) { m_signals.push_back(sig); } |
78 |
|
|
79 |
|
void emit_from (Object *source) { |
80 |
|
for (unsigned i=0; i<m_signals.size(); ++i) { |
81 |
|
m_signals[i]->emit_from (source); |
82 |
|
} |
83 |
|
} |
84 |
|
}; |
85 |
|
} |
86 |
|
|
87 |
//---------------------------------------- |
//---------------------------------------- |
88 |
// Rubber band |
// Rubber band |
89 |
//---------------------------------------- |
//---------------------------------------- |
135 |
model.kill(); |
model.kill(); |
136 |
} |
} |
137 |
|
|
138 |
void |
void RubberBand::tick(double) |
|
RubberBand::tick(double) |
|
139 |
{ |
{ |
140 |
V2 v = get_p2()-get_p1(); |
V2 v = get_p2()-get_p1(); |
141 |
double vv = px::length(v); |
double vv = px::length(v); |
152 |
model.update_second (get_p2()); |
model.update_second (get_p2()); |
153 |
} |
} |
154 |
|
|
155 |
V2 |
V2 RubberBand::get_force(Actor *a) |
|
RubberBand::get_force(Actor *a) |
|
156 |
{ |
{ |
157 |
return V2(); |
return V2(); |
158 |
} |
} |
159 |
|
|
160 |
V2 |
V2 RubberBand::get_p1() const |
|
RubberBand::get_p1() const |
|
161 |
{ |
{ |
162 |
return V2(actor->get_pos()[0], actor->get_pos()[1]); |
return V2(actor->get_pos()[0], actor->get_pos()[1]); |
163 |
} |
} |
164 |
|
|
165 |
V2 |
V2 RubberBand::get_p2() const |
|
RubberBand::get_p2() const |
|
166 |
{ |
{ |
167 |
if (!stone) |
if (!stone) |
168 |
return V2(actor2->get_pos()[0], actor2->get_pos()[1]); |
return V2(actor2->get_pos()[0], actor2->get_pos()[1]); |
310 |
|
|
311 |
namespace |
namespace |
312 |
{ |
{ |
|
MouseForce *mouseforce; |
|
|
|
|
313 |
class Level { |
class Level { |
314 |
public: |
public: |
315 |
Level(int ww, int hh) : fields(ww,hh) { |
Level(int ww, int hh) : fields(ww,hh) { |
340 |
ForceList forces; |
ForceList forces; |
341 |
ActorList actorlist; // List of movable, dynamic objects |
ActorList actorlist; // List of movable, dynamic objects |
342 |
vector<RubberBand *> rubbers; |
vector<RubberBand *> rubbers; |
343 |
|
SignalList signals; |
344 |
}; |
}; |
345 |
|
|
346 |
|
MouseForce *mouseforce; |
347 |
Level *level; |
Level *level; |
348 |
} |
} |
349 |
|
|
354 |
// PHYSICS SIMULATION |
// PHYSICS SIMULATION |
355 |
//====================================================================== |
//====================================================================== |
356 |
|
|
|
const double MINVEL = 0.0001; |
|
|
|
|
357 |
/* Calculate the total acceleration on an actor A at time TIME. The |
/* Calculate the total acceleration on an actor A at time TIME. The |
358 |
actor's current position X and velocity V are also passed. Note |
actor's current position X and velocity V are also passed. Note |
359 |
that the position and velocity entries in ActorInfo will be updated |
that the position and velocity entries in ActorInfo will be updated |
397 |
} |
} |
398 |
|
|
399 |
ActorInfo *ai = a->get_actorinfo(); |
ActorInfo *ai = a->get_actorinfo(); |
400 |
f += ai->forceacc2; |
f += ai->forceacc; |
401 |
|
|
402 |
return f / ai->mass; |
return f / ai->mass; |
403 |
} |
} |
891 |
} |
} |
892 |
} |
} |
893 |
|
|
894 |
bool |
bool world::HasRubberBand (Actor *a, Stone *st) |
|
world::HasRubberBand (Actor *a, Stone *st) |
|
895 |
{ |
{ |
896 |
for (unsigned i=0; i<level->rubbers.size(); ++i) { |
for (unsigned i=0; i<level->rubbers.size(); ++i) { |
897 |
RubberBand &r = *level->rubbers[i]; |
RubberBand &r = *level->rubbers[i]; |
901 |
return false; |
return false; |
902 |
} |
} |
903 |
|
|
904 |
|
//---------------------------------------- |
905 |
|
// Signals |
906 |
|
//---------------------------------------- |
907 |
|
|
908 |
|
void world::AddSignal (Object *src, Object *dst, const string &msg) |
909 |
|
{ |
910 |
|
level->signals.add (new SimpleSignal (src, dst, msg)); |
911 |
|
} |
912 |
|
|
913 |
|
void world::EmitSignals (Object *src) |
914 |
|
{ |
915 |
|
level->signals.emit_from (src); |
916 |
|
} |
917 |
|
|
918 |
namespace |
namespace |
919 |
{ |
{ |
1178 |
a->get_actorinfo()->grabbed = false; |
a->get_actorinfo()->grabbed = false; |
1179 |
} |
} |
1180 |
|
|
|
const ActorInfo & |
|
|
world::GetActorInfo(Actor *a) |
|
|
{ |
|
|
return *a->get_actorinfo(); |
|
|
} |
|
|
|
|
1181 |
void |
void |
1182 |
world::Tick(double dtime) |
world::Tick(double dtime) |
1183 |
{ |
{ |
1191 |
ActorInfo *ai = (*i)->get_actorinfo(); |
ActorInfo *ai = (*i)->get_actorinfo(); |
1192 |
if (!ai->grabbed && !(*i)->is_dead()) |
if (!ai->grabbed && !(*i)->is_dead()) |
1193 |
{ |
{ |
|
ai->forceacc2 = ai->forceacc; |
|
|
ai->forceacc = V2(); |
|
1194 |
tick_actor(*i, timestep); |
tick_actor(*i, timestep); |
1195 |
} |
} |
1196 |
|
ai->forceacc = V2(); |
1197 |
} |
} |
1198 |
// Tell floors and items about new stones. |
// Tell floors and items about new stones. |
1199 |
for (unsigned i=0; i<changed_stones.size(); ++i) |
for (unsigned i=0; i<changed_stones.size(); ++i) |