-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestfield.cpp
More file actions
173 lines (143 loc) · 5.9 KB
/
testfield.cpp
File metadata and controls
173 lines (143 loc) · 5.9 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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Implementation of the example Wall and example Floor
#include "game.h"
#include "field.h"
#include "testfield.h"
//////////////////////////////
TestWall::TestWall(ISceneManager* smgr, IVideoDriver* driver, int x, int y, playground pg)
: Wall(smgr,driver,x,y,pg) // calling constructor of parent class
{
// use a different texture than parent class:
texture=driver->getTexture(texturepath+"st-rock3_cracked.png");
block->setMaterialTexture(0,texture);
// A pointer to a related object which is initially 0 (i.e. no related object).
related=0;
};
void TestWall::introduceTo(Field &f)
{
/*
Example to how to build up relationships between fields.
The field.lvl file contains the line
introduce 14 2 to 1 7
which means that main routine is going to call
playground[14][2]->introduceTo(playground[1][7]);
We assume that such calls only occur for fieldtypes that "know
how to talk to each other" (i.e. being programmed by the same
team). In the example, let's say it can only happen between
objects of type TestWall. And we first check this:
*/
if (f.getFieldType()!=tTestWall) error("TestWall introduced to Non-TestWall!!\n");
// Now we know that f is an object of type TestWall (i.e. a more
// specific type than Field). We do a pointer conversion, so we can
// store it in the variable "related" (which is of type
// TestWall*). So this field can later communicate to the related Field.
related=(TestWall *) &f;
}
void TestWall::sphereOverlap(Sphere &s, f32 xoverlap, f32 yoverlap)
{
/*
This function is called when the sphere touches/overlaps with the
borders of this TestWall. Normally we do just collision detection
(as in the parent class Wall), but here wo do something additional:
We make an example of using the playground (which is a parameter
of the constructor for all Fields). Here we check whether any of
the adjacent Fields is also of type TestWall; if so, we make it
invisible. For that we first need a pointer conversion from
Field *) to the more specific (TestWall *) -- because Field does
not have a member variable "block" that we want to access.
*/
if (x>0 && pg[x-1][y]->getFieldType()==tTestWall)
((TestWall *)pg[x-1][y])->block->setVisible(false);
if (y>0 && pg[x][y-1]->getFieldType()==tTestWall)
((TestWall *)pg[x][y-1])->block->setVisible(false);
if (x<dimx-1 && pg[x+1][y]->getFieldType()==tTestWall)
((TestWall *)pg[x+1][y])->block->setVisible(false);
if (y<dimy-1 && pg[x][y+1]->getFieldType()==tTestWall)
((TestWall *)pg[x][y+1])->block->setVisible(false);
/*
Another example: if the introduceTo function above had been
called for this field, i.e. if the pointer "related" is not 0,
then we set that related field to be visible again.
*/
if (related)
related->block->setVisible(true);
// standard collision detection (a copy of the code parent class)
// Tomas: Actually just call the parent function since it is
// very bad practice to copy / pasting code. (i.e. what if you
// want to change the code, you have to change it in many placse etc)
// Tomas: (this worked)
Wall::sphereOverlap(s, xoverlap, yoverlap);
}
fieldtype TestWall::getFieldType()
{
return tTestWall;
}
/////////////////////////////////
/// Example of a special kind of Floor
LightFloor::LightFloor(ISceneManager* smgr, IVideoDriver* driver, int x, int y, playground pg)
: Floor(smgr,driver,x,y,pg) // calling constructor of parent class
{
// use a different standard texture than parent class:
texture=driver->getTexture(texturepath+"fl-bridgex-closed.png");
block->setMaterialTexture(0,texture);
// use a alternative texture (for when the sphere is on this Floor).
alt_texture = driver->getTexture(texturepath+"fl-plank.png");
timeSpentHere=0.f; // see below
falling=false; // see below
}
// when the sphere enters, change the texture to the alternate one
void LightFloor::sphereEnter(Sphere &s)
{
block->setMaterialTexture(0,alt_texture);
}
// change back when the sphere leaves.
void LightFloor::sphereExit(Sphere &s)
{
block->setMaterialTexture(0,texture);
}
/*
Example for the feature to install a special "handler" for the sphere (that is independent
of the Floor the sphere is on). Then we first have to declare a function that has just the
same input arguments as the following one (and no output):
*/
void fallingSphere(Sphere & s,position2di mousemove,f32 frameDeltaTime,f32 friction)
{
// This handler would accelerate the sphere downwards, ignoring all
// mouse movements or speed in horizontal directions:
vector3df p=s.getPosition();
vector3df v=s.getVelocity();
v.X=v.Z=0.f;
v.Y-=1.f*frameDeltaTime; // falling;
p+=v;
s.setPosition(p);
s.setVelocity(v);
}
// This method gets called whenever the sphere is on the floor for frameDeltaTime
void LightFloor::handleSphere(Sphere &s, position2di mousemove, f32 frameDeltaTime)
{
// We count the total time that the sphere has been on this field:
timeSpentHere+=frameDeltaTime;
// If we have spent more than 3.0 time units here, then the floor is
// removed and the sphere falls downwards. The falling flag is used
// so that we won't start falling more than once.
if (!falling && timeSpentHere>3.f)
{
falling =true;
// removing the floor by making it invisble:
block->setVisible(false);
// Installing the "fallingSphere" handler we have defined
// above. The sphere will no longer behave according to the
// standardSphereProgress-method (of class sphere) but do what the
// fallingSphere handler tells it to. Note that we here give the
// entire "fallingSphere" function as an argument (!) to the
// installAlternateSphereProgress method.
s.installAlternateSphereProgress(fallingSphere);
}
// We always call the standardSphereProgress -- even after the 3.f
// seconds, because that will invoke either the standard progress or
// the alternative handler once it is installed.
s.standardSphereProgress(mousemove, frameDeltaTime, stdfriction);
};
fieldtype LightFloor::getFieldType()
{
return tLightFloor;
}