38 |
|
|
39 |
using namespace std; |
using namespace std; |
40 |
using namespace world; |
using namespace world; |
41 |
|
using namespace px; |
42 |
|
|
43 |
namespace test |
namespace test |
44 |
{ |
{ |
62 |
|
|
63 |
struct Sphere : public Shape |
struct Sphere : public Shape |
64 |
{ |
{ |
65 |
Sphere (const px::V2 &c, double r) |
Sphere (const V2 &c, double r) |
66 |
: Shape(SHAPE_Sphere), center(c), radius(r) |
: Shape(SHAPE_Sphere), center(c), radius(r) |
67 |
{} |
{} |
68 |
|
|
69 |
// Variables. |
// Variables. |
70 |
px::V2 center; |
V2 center; |
71 |
double radius; |
double radius; |
72 |
}; |
}; |
73 |
} |
} |
95 |
} |
} |
96 |
|
|
97 |
//---------------------------------------- |
//---------------------------------------- |
98 |
|
// Rubber band |
99 |
|
//---------------------------------------- |
100 |
|
namespace world |
101 |
|
{ |
102 |
|
class RubberBand { |
103 |
|
public: |
104 |
|
RubberBand (Actor *a1, Actor *a2, double strength=10, double length=2); |
105 |
|
RubberBand (Actor *a1, Stone *st, double strength=10, double length=2); |
106 |
|
~RubberBand(); |
107 |
|
|
108 |
|
void tick(double); |
109 |
|
V3 get_force(Actor *a); |
110 |
|
private: |
111 |
|
V2 get_p1() const; |
112 |
|
V2 get_p2() const; |
113 |
|
|
114 |
|
// Variables. |
115 |
|
Actor *actor, *actor2; |
116 |
|
Stone *stone; |
117 |
|
display::RubberID model; |
118 |
|
double strength, length; |
119 |
|
}; |
120 |
|
} |
121 |
|
|
122 |
|
RubberBand::RubberBand (Actor *a1, Actor *a2, double strength_, double length_) |
123 |
|
: actor(a1), actor2(a2), stone(0), model(0) |
124 |
|
, strength(strength_), length(length_) |
125 |
|
{ |
126 |
|
assert(actor); |
127 |
|
assert(length >= 0); |
128 |
|
model = display::AddRubber(get_p1(),get_p2()); |
129 |
|
} |
130 |
|
|
131 |
|
RubberBand::RubberBand (Actor *a1, Stone *st, double strength_, double length_) |
132 |
|
: actor(a1), actor2(0), stone(st), model(0) |
133 |
|
, strength(strength_), length(length_) |
134 |
|
{ |
135 |
|
assert(actor); |
136 |
|
assert(length >= 0); |
137 |
|
model = display::AddRubber(get_p1(), get_p2()); |
138 |
|
} |
139 |
|
|
140 |
|
RubberBand::~RubberBand() { |
141 |
|
model.kill(); |
142 |
|
} |
143 |
|
|
144 |
|
void |
145 |
|
RubberBand::tick(double) |
146 |
|
{ |
147 |
|
V2 v = get_p2()-get_p1(); |
148 |
|
double vv = px::length(v); |
149 |
|
|
150 |
|
if (vv > length) { |
151 |
|
V2 force = v * strength*(vv-length)/vv; |
152 |
|
V3 f(force[0],force[1],0); |
153 |
|
actor->add_force(f); |
154 |
|
if (actor2) |
155 |
|
actor2->add_force(-f); |
156 |
|
} |
157 |
|
|
158 |
|
model.update_first (get_p1()); |
159 |
|
if (!stone) |
160 |
|
model.update_second (get_p2()); |
161 |
|
} |
162 |
|
|
163 |
|
V3 |
164 |
|
RubberBand::get_force(Actor *a) |
165 |
|
{ |
166 |
|
return V3(); |
167 |
|
} |
168 |
|
|
169 |
|
V2 |
170 |
|
RubberBand::get_p1() const |
171 |
|
{ |
172 |
|
return V2(actor->get_pos()[0], actor->get_pos()[1]); |
173 |
|
} |
174 |
|
|
175 |
|
V2 |
176 |
|
RubberBand::get_p2() const |
177 |
|
{ |
178 |
|
if (!stone) |
179 |
|
return V2(actor2->get_pos()[0], actor2->get_pos()[1]); |
180 |
|
else |
181 |
|
return V2(stone->get_pos().x+0.5, stone->get_pos().y+0.5); |
182 |
|
} |
183 |
|
|
184 |
|
|
185 |
|
|
186 |
|
//---------------------------------------- |
187 |
// Field |
// Field |
188 |
//---------------------------------------- |
//---------------------------------------- |
189 |
namespace |
namespace |
335 |
~Level() { |
~Level() { |
336 |
fields = FieldArray(0,0); |
fields = FieldArray(0,0); |
337 |
for_each(actorlist.begin(), actorlist.end(), mem_fun(&Actor::dispose)); |
for_each(actorlist.begin(), actorlist.end(), mem_fun(&Actor::dispose)); |
338 |
|
delete_sequence (rubbers.begin(), rubbers.end()); |
339 |
} |
} |
340 |
|
|
341 |
bool contains (GridPos p) { |
bool contains (GridPos p) { |
355 |
int w, h; // Width and height of the level |
int w, h; // Width and height of the level |
356 |
ForceList forces; |
ForceList forces; |
357 |
ActorList actorlist; // List of movable, dynamic objects |
ActorList actorlist; // List of movable, dynamic objects |
358 |
|
vector<RubberBand *> rubbers; |
359 |
}; |
}; |
360 |
|
|
361 |
Level *level; |
Level *level; |
783 |
player::AddActor(iplayer,a); |
player::AddActor(iplayer,a); |
784 |
} |
} |
785 |
} |
} |
786 |
|
|
787 |
return true; |
return true; |
788 |
} |
} |
789 |
|
|
820 |
return 0; |
return 0; |
821 |
} |
} |
822 |
|
|
823 |
|
//---------------------------------------- |
824 |
|
// Force fields |
825 |
|
//---------------------------------------- |
826 |
|
|
827 |
|
|
828 |
void |
void |
829 |
world::AddForceField(ForceField *ff) |
world::AddForceField(ForceField *ff) |
830 |
{ |
{ |
840 |
} |
} |
841 |
|
|
842 |
//---------------------------------------- |
//---------------------------------------- |
843 |
|
// Rubber bands |
844 |
|
//---------------------------------------- |
845 |
|
|
846 |
|
void |
847 |
|
world::AddRubberBand (Actor *a, Stone *st, double strength,double length) |
848 |
|
{ |
849 |
|
level->rubbers.push_back(new RubberBand (a, st, strength, length)); |
850 |
|
} |
851 |
|
|
852 |
|
|
853 |
|
void |
854 |
|
world::AddRubberBand (Actor *a, Actor *a2, double strength,double length) |
855 |
|
{ |
856 |
|
level->rubbers.push_back(new RubberBand (a, a2, strength, length)); |
857 |
|
} |
858 |
|
|
859 |
|
|
860 |
|
void |
861 |
|
world::KillRubberBand (Actor *a, Stone *st) |
862 |
|
{ |
863 |
|
} |
864 |
|
|
865 |
|
void |
866 |
|
world::KillRubberBand (Actor *a, Actor *a2) |
867 |
|
{ |
868 |
|
} |
869 |
|
|
870 |
|
//---------------------------------------- |
871 |
// Layer |
// Layer |
872 |
// |
// |
873 |
// Changes to a layer are cached and only applied at the end of a |
// Changes to a layer are cached and only applied at the end of a |
1134 |
mouseforce->tick(timestep); |
mouseforce->tick(timestep); |
1135 |
for_each(level->forces.begin(), level->forces.end(), |
for_each(level->forces.begin(), level->forces.end(), |
1136 |
bind2nd(mem_fun(&ForceField::tick), timestep)); |
bind2nd(mem_fun(&ForceField::tick), timestep)); |
1137 |
|
|
1138 |
|
for_each (level->rubbers.begin(), level->rubbers.end(), |
1139 |
|
bind2nd(mem_fun(&RubberBand::tick), timestep)); |
1140 |
|
|
1141 |
g_timer.tick(timestep); |
g_timer.tick(timestep); |
1142 |
laser::RecalcLightNow(); // recalculate laser beams if necessary |
laser::RecalcLightNow(); // recalculate laser beams if necessary |
1143 |
timeaccu -= timestep; |
timeaccu -= timestep; |