~ubuntu-branches/ubuntu/quantal/zaz/quantal

« back to all changes in this revision

Viewing changes to src/player.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Miriam Ruiz
  • Date: 2009-08-31 20:08:58 UTC
  • Revision ID: james.westby@ubuntu.com-20090831200858-54lcmcrna6dwk3wr
Tags: upstream-0.2.9+dfsg1
ImportĀ upstreamĀ versionĀ 0.2.9+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Zaz
 
3
 * Copyright (C) Remigiusz Dybka 2009 <remigiusz.dybka@gmail.com>
 
4
 *
 
5
 Zaz is free software: you can redistribute it and/or modify it
 
6
 under the terms of the GNU General Public License as published by the
 
7
 Free Software Foundation, either version 3 of the License, or
 
8
 (at your option) any later version.
 
9
 
 
10
 Zaz is distributed in the hope that it will be useful, but
 
11
 WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
13
 See the GNU General Public License for more details.
 
14
 
 
15
 You should have received a copy of the GNU General Public License along
 
16
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#include "player.h"
 
20
#include "game.h"
 
21
#include <deque>
 
22
 
 
23
Player::Player(Bezier path, BallPath **ballPaths, bool pathLooped, bool invert, bool drawPath)
 
24
        : tex(LoadTexture("player.png")), path(path), drawPath(drawPath), pathLooped(pathLooped), invert(invert),
 
25
        ballPaths(ballPaths),  pickedCol(-1), pickedBonus(BONUS_NONE), picking(false), shooting(false), score(0),
 
26
        accuracyShot(false)
 
27
{
 
28
    BezierPoint p0 = path.points[0];
 
29
 
 
30
    p0.cx = p0.x + (p0.x - p0.cx);
 
31
    p0.cy = p0.y + (p0.y - p0.cy);
 
32
 
 
33
    if (pathLooped)
 
34
        path.points.push_back(p0);
 
35
 
 
36
    pts = path.GenerateUniform(0.05);
 
37
 
 
38
    ptsLen = pts.size() -1;
 
39
    currPos = 0.5;
 
40
    Move(0.0);
 
41
 
 
42
    double mouseSens = atof(settings.get("mouseSensivity", "5").c_str());
 
43
    if (mouseSens < 1)
 
44
        mouseSens = 1;
 
45
 
 
46
    mouseDiv = (mouseSens / 10.0) / 500;
 
47
}
 
48
 
 
49
Player::~Player()
 
50
{
 
51
    glDeleteTextures(1, &tex);
 
52
}
 
53
 
 
54
void Player::UpdateRotation()
 
55
{
 
56
    XY pt1 = pts[currPt - 1];
 
57
    XY pt2 = pts[currPt + 1];
 
58
 
 
59
    double x;
 
60
    double y;
 
61
 
 
62
    if (!invert)
 
63
    {
 
64
        x = pt2.x - pt1.x;
 
65
        y = (pt2.y - pt1.y);
 
66
    }
 
67
    else
 
68
    {
 
69
        x = pt1.x - pt2.x;
 
70
        y = (pt1.y - pt2.y);
 
71
    }
 
72
 
 
73
    rot = atan2(y, x) * (180.0 / PI);
 
74
}
 
75
 
 
76
void Player::Move(double t)
 
77
{
 
78
    currPos += t;
 
79
 
 
80
    if (pathLooped)
 
81
    {
 
82
        while ( currPos < 0.0)
 
83
            currPos+=1.0;
 
84
 
 
85
        while (currPos > 1.0)
 
86
            currPos-=1.0;
 
87
    }
 
88
    else
 
89
    {
 
90
        if (currPos < 0.0)
 
91
            currPos = 0.0;
 
92
 
 
93
        if (currPos > 1.0)
 
94
            currPos = 1.0;
 
95
    }
 
96
 
 
97
    currPt = (int)((ptsLen - 2) * currPos);
 
98
 
 
99
    if (currPt < 1)
 
100
        currPt = 1;
 
101
 
 
102
    if (currPt > ptsLen - 2)
 
103
        currPt = ptsLen - 2;
 
104
 
 
105
    UpdateRotation();
 
106
}
 
107
 
 
108
void Player::Logic(Scenes::FrameEvents events)
 
109
{
 
110
    int p = 0;
 
111
    while (ballPaths[p] != NULL)
 
112
    {
 
113
        if (ballPaths[p]->state.accuracyShotTriggered)
 
114
        {
 
115
            accuracyShot = true;
 
116
            accuracyShotTime = accuracyShotTimeout;
 
117
            ballPaths[p]->state.accuracyShotTriggered = false;
 
118
        }
 
119
 
 
120
        p++;
 
121
    }
 
122
 
 
123
    if (accuracyShot)
 
124
    {
 
125
        accuracyShotTime--;
 
126
        if (accuracyShotTime < 0)
 
127
            accuracyShot = false;
 
128
    }
 
129
 
 
130
    if (shooting)
 
131
    {
 
132
        int p = 0;
 
133
        double ldist = 100;
 
134
        ShotAddr shotBall(-1);
 
135
        int shotPath = -1;
 
136
        ShotAddr nBall(-1);
 
137
 
 
138
        while (ballPaths[p] != NULL)
 
139
        {
 
140
            nBall = ballPaths[p]->PickShot(shootPoint.x, shootPoint.y);
 
141
 
 
142
            if (nBall.pos != -1)
 
143
            {
 
144
                double bx = ballPaths[p]->ballPath[(uint)ballPaths[p]->balls[nBall.pos].pos].x;
 
145
                double by = ballPaths[p]->ballPath[(uint)ballPaths[p]->balls[nBall.pos].pos].y;
 
146
 
 
147
                double dist = sqrt(pow(fabs(bx - shootPoint.x), 2.0) + pow(fabs(by - shootPoint.y), 2.0));
 
148
                if (dist < ldist)
 
149
                {
 
150
                    shotBall = nBall;
 
151
                    shotPath = p;
 
152
                    ldist = dist;
 
153
                }
 
154
            }
 
155
            ++p;
 
156
        }
 
157
 
 
158
        // is this the first ball ?
 
159
        if (shotBall.pos == 0)
 
160
        {
 
161
            // do we have space for a ball before that one ?
 
162
            if (ballPaths[shotPath]->balls[shotBall.pos].pos >= BallPath::stepsPerBall)
 
163
            {
 
164
                // if yes.... was the shot on the right side ?
 
165
                double bx = ballPaths[shotPath]->ballPath[(uint)ballPaths[shotPath]->balls[shotBall.pos].pos].x;
 
166
                double by = ballPaths[shotPath]->ballPath[(uint)ballPaths[shotPath]->balls[shotBall.pos].pos].y;
 
167
 
 
168
                double distBall = sqrt(pow(fabs(bx - shootPoint.x), 2.0) + pow(fabs(by - shootPoint.y), 2.0));
 
169
 
 
170
                bx = ballPaths[shotPath]->ballPath[(uint)ballPaths[shotPath]->balls[shotBall.pos].pos - BallPath::stepsPerBall].x;
 
171
                by = ballPaths[shotPath]->ballPath[(uint)ballPaths[shotPath]->balls[shotBall.pos].pos - BallPath::stepsPerBall].y;
 
172
 
 
173
                double distFirst = sqrt(pow(fabs(bx - shootPoint.x), 2.0) + pow(fabs(by - shootPoint.y), 2.0));
 
174
 
 
175
                if (distFirst < distBall)
 
176
                {
 
177
                    ballPaths[shotPath]->InsertBall(ShotAddr(-1), shootCol, shootBonus);
 
178
                    shotBall.pos= -1;
 
179
                    shooting = false;
 
180
                }
 
181
            }
 
182
        }
 
183
 
 
184
 
 
185
        if (shotBall.pos != -1)
 
186
        {
 
187
            ballPaths[shotPath]->InsertBall(shotBall, shootCol, shootBonus);
 
188
            shooting = false;
 
189
        }
 
190
 
 
191
        if (shooting)
 
192
            if (shootPoint.x > 120 || shootPoint.x < -20 || shootPoint.y > 120 || shootPoint.y < -20)
 
193
            {
 
194
                mix->EnqueueSample(sfx_ouch, sfxVol);
 
195
                score -= 25;
 
196
                shooting = false;
 
197
                picking = true;
 
198
                pickT = 1.0;
 
199
            }
 
200
 
 
201
        shootPoint.x = shootPoint.x + shootVel.x * shootingSpeed;
 
202
        shootPoint.y = shootPoint.y + shootVel.y * shootingSpeed;
 
203
    }
 
204
 
 
205
    if (picking)
 
206
    {
 
207
        pickT += pickV;
 
208
        if (pickT > 1.0)
 
209
            pickT = 1.0;
 
210
    }
 
211
 
 
212
    if (!events.empty)
 
213
    {
 
214
        if (!invert)
 
215
        {
 
216
            Move(double(events.relmouseX) * mouseDiv);
 
217
        }
 
218
        else
 
219
            Move(double(-1 * events.relmouseX) * mouseDiv);
 
220
 
 
221
        if (events.buttDown[0] && picking && !shooting)
 
222
        {
 
223
            shootCol = pickedCol;
 
224
            shootTex = pickedTex;
 
225
            shootBonus = pickedBonus;
 
226
            shootBonusTex = pickedBonusTex;
 
227
 
 
228
            shootVel.x = -sin(rot / (180.0 / PI));
 
229
            shootVel.y = cos(rot / (180.0 / PI));
 
230
 
 
231
            shootPoint.x = pts[currPt].x + holdingDist * shootVel.x;
 
232
            shootPoint.y = pts[currPt].y + holdingDist * shootVel.y;
 
233
 
 
234
            shooting = true;
 
235
            picking = false;
 
236
            reshooting = true;
 
237
 
 
238
            mix->EnqueueSample(sfx_push, sfxVol);
 
239
        }
 
240
 
 
241
 
 
242
        if (events.buttDown[0] && !shooting && !picking)
 
243
        { // we're shoootin :)
 
244
            int p = 0;
 
245
            XY pt1 = pts[currPt - 1];
 
246
            XY pt2 = pts[currPt + 1];
 
247
 
 
248
            double vx = -sin(rot / (180.0 / PI));
 
249
            double vy = cos(rot / (180.0 / PI));
 
250
 
 
251
            double x = pts[currPt].x;
 
252
            double y = pts[currPt].y;
 
253
 
 
254
            int nBall = -1;
 
255
            pickedPath = -1;
 
256
            double ldist = 200.0;
 
257
            pickedBall = -1;
 
258
 
 
259
            while (ballPaths[p] != NULL)
 
260
            {
 
261
                nBall = ballPaths[p]->Pick(x, y, vx, vy);
 
262
 
 
263
                if (nBall != -1)
 
264
                {
 
265
                    double bx = ballPaths[p]->ballPath[(uint)ballPaths[p]->balls[nBall].pos].x;
 
266
                    double by = ballPaths[p]->ballPath[(uint)ballPaths[p]->balls[nBall].pos].y;
 
267
                    double dist = sqrt(pow(fabs(bx - x), 2.0) + pow(fabs(by - y), 2.0));
 
268
 
 
269
                    if (dist < ldist)
 
270
                    {
 
271
                        pickedBall = nBall;
 
272
                        pickedPath = p;
 
273
                        ldist = dist;
 
274
                    }
 
275
                }
 
276
 
 
277
                ++p;
 
278
            }
 
279
 
 
280
            if (pickedBall != -1)
 
281
            {
 
282
                pickedCol = ballPaths[pickedPath]->balls[pickedBall].col;
 
283
                pickedBonus = ballPaths[pickedPath]->balls[pickedBall].bonus;
 
284
                pickedTex = ballPaths[pickedPath]->tex[pickedCol];
 
285
                pickedBonusTex = ballPaths[pickedPath]->tex[NBALLCOLORS + (pickedBonus) - 1];
 
286
                pickPoint.x = ballPaths[pickedPath]->ballPath[(uint)ballPaths[pickedPath]->balls[pickedBall].pos].x;
 
287
                pickPoint.y = ballPaths[pickedPath]->ballPath[(uint)ballPaths[pickedPath]->balls[pickedBall].pos].y;
 
288
 
 
289
                picking = true;
 
290
                reshooting = false;
 
291
                pickT = 0.0;
 
292
                pickV = 1.0 / (double)pickSpeed;
 
293
 
 
294
                deque<Ball>::iterator i;
 
295
                i = ballPaths[pickedPath]->balls.begin();
 
296
                i += pickedBall;
 
297
 
 
298
                ballPaths[pickedPath]->balls.erase(i);
 
299
                ballPaths[pickedPath]->state.comboCnt = 0;
 
300
 
 
301
                mix->EnqueueSample(sfx_pull, sfxVol);
 
302
            }
 
303
        }
 
304
 
 
305
        if (events.buttUp[0])
 
306
        {
 
307
            if (picking && !shooting && !reshooting)
 
308
            {
 
309
                shootCol = pickedCol;
 
310
                shootTex = pickedTex;
 
311
                shootBonus = pickedBonus;
 
312
                shootBonusTex = pickedBonusTex;
 
313
 
 
314
                shootVel.x = -sin(rot / (180.0 / PI));
 
315
                shootVel.y = cos(rot / (180.0 / PI));
 
316
 
 
317
                shootPoint.x = pts[currPt].x + holdingDist * shootVel.x;
 
318
                shootPoint.y = pts[currPt].y + holdingDist * shootVel.y;
 
319
 
 
320
                shooting = true;
 
321
                picking = false;
 
322
                reshooting = false;
 
323
                mix->EnqueueSample(sfx_push, sfxVol);
 
324
            }
 
325
        }
 
326
    }
 
327
}
 
328
 
 
329
void Player::Render()
 
330
{
 
331
    double ts = ((BallPath::ballOneTextureSize * 10.0)/ double(BallPath::ballTextureSize)) * 0.1; // size of one ball in texture coordinates
 
332
 
 
333
    glLoadIdentity();
 
334
 
 
335
    glEnable(GL_TEXTURE_2D);
 
336
    glTranslated(pts[currPt].x, pts[currPt].y, 40);
 
337
    glBindTexture(GL_TEXTURE_2D, tex);
 
338
    glScaled(10, 10, 10);
 
339
    glRotated(rot, 0, 0, 1.0);
 
340
    glBegin(GL_QUADS);
 
341
    glTexCoord2d(0, 0);
 
342
    glVertex3d(-0.5, 0.5, 0);
 
343
    glTexCoord2d(0, 1);
 
344
    glVertex3d(-0.5, -0.5, 0);
 
345
    glTexCoord2d(1, 1);
 
346
    glVertex3d(0.5, -0.5, 0);
 
347
    glTexCoord2d(1, 0);
 
348
    glVertex3d(0.5, 0.5, 0);
 
349
    glEnd();
 
350
    glDisable(GL_TEXTURE_2D);
 
351
 
 
352
    if (shooting)
 
353
    {
 
354
        glLoadIdentity();
 
355
        glEnable(GL_TEXTURE_2D);
 
356
        glTranslated(shootPoint.x, shootPoint.y, 40);
 
357
        glBindTexture(GL_TEXTURE_2D, shootTex);
 
358
        glScaled(5, 5, 5);
 
359
        glBegin(GL_QUADS);
 
360
        glTexCoord2d(0.0, 0.0);
 
361
        glVertex3d(-0.5, 0.5, 0);
 
362
        glTexCoord2d(0.0, ts);
 
363
        glVertex3d(-0.5, -0.5, 0);
 
364
        glTexCoord2d(ts, ts);
 
365
        glVertex3d(0.5, -0.5, 0);
 
366
        glTexCoord2d(ts, 0.0);
 
367
        glVertex3d(0.5, 0.5, 0);
 
368
        glEnd();
 
369
 
 
370
        if (pickedBonus)
 
371
        {
 
372
            glLoadIdentity();
 
373
            glTranslated(shootPoint.x, shootPoint.y, 45);
 
374
            glBindTexture(GL_TEXTURE_2D, shootBonusTex);
 
375
            glScaled(5, 5, 5);
 
376
            glBegin(GL_QUADS);
 
377
            glTexCoord2d(0.0, 0.0);
 
378
            glVertex3d(-0.5, 0.5, 0);
 
379
            glTexCoord2d(0.0, 1);
 
380
            glVertex3d(-0.5, -0.5, 0);
 
381
            glTexCoord2d(1, 1);
 
382
            glVertex3d(0.5, -0.5, 0);
 
383
            glTexCoord2d(1, 0.0);
 
384
            glVertex3d(0.5, 0.5, 0);
 
385
            glEnd();
 
386
        }
 
387
 
 
388
        glDisable(GL_TEXTURE_2D);
 
389
    }
 
390
 
 
391
    if (picking)
 
392
    {
 
393
        double bx = pts[currPt].x + holdingDist * -sin(rot / (180.0 / PI));
 
394
        double by = pts[currPt].y + holdingDist * cos(rot / (180.0 / PI));
 
395
        bx = bx + (pickPoint.x - bx) * (1.0 - pickT);
 
396
        by = by + (pickPoint.y - by) * (1.0 - pickT);
 
397
 
 
398
        double bps = (double)BallPath::ballSize / 1.5;
 
399
        double bs = (double)BallPath::ballSize - (((double)BallPath::ballSize - bps) * pickT);
 
400
 
 
401
        glLoadIdentity();
 
402
        glEnable(GL_TEXTURE_2D);
 
403
        glTranslated(bx, by, 40);
 
404
        glRotated(rot, 0, 0, 1.0);
 
405
        glBindTexture(GL_TEXTURE_2D, pickedTex);
 
406
        glScaled(bs, bs, bs);
 
407
        glBegin(GL_QUADS);
 
408
        glTexCoord2d(0.0, 0.0);
 
409
        glVertex3d(-0.5, 0.5, 0);
 
410
        glTexCoord2d(0.0, ts);
 
411
        glVertex3d(-0.5, -0.5, 0);
 
412
        glTexCoord2d(ts, ts);
 
413
        glVertex3d(0.5, -0.5, 0);
 
414
        glTexCoord2d(ts, 0.0);
 
415
        glVertex3d(0.5, 0.5, 0);
 
416
        glEnd();
 
417
 
 
418
        if (pickedBonus)
 
419
        {
 
420
            glLoadIdentity();
 
421
            glTranslated(bx, by, 45);
 
422
            glRotated(rot, 0, 0, 1.0);
 
423
            glBindTexture(GL_TEXTURE_2D, pickedBonusTex);
 
424
            glScaled(bs, bs, bs);
 
425
            glBegin(GL_QUADS);
 
426
            glTexCoord2d(0, 0);
 
427
            glVertex3d(-0.5, 0.5, 0);
 
428
            glTexCoord2d(0, 1);
 
429
            glVertex3d(-0.5, -0.5, 0);
 
430
            glTexCoord2d(1, 1);
 
431
            glVertex3d(0.5, -0.5, 0);
 
432
            glTexCoord2d(1, 0);
 
433
            glVertex3d(0.5, 0.5, 0);
 
434
            glEnd();
 
435
        }
 
436
 
 
437
        glDisable(GL_TEXTURE_2D);
 
438
    }
 
439
 
 
440
    if (accuracyShot)
 
441
    {
 
442
        glLoadIdentity();
 
443
        glLineWidth(3.0);
 
444
        glTranslated(pts[currPt].x, pts[currPt].y, 30);
 
445
        glRotated(rot, 0, 0, 1.0);
 
446
        glTranslatef(0, 5, 0);
 
447
        glBegin(GL_TRIANGLES);
 
448
 
 
449
        glColor4d(1, 0, 0, 0.5 * double(accuracyShotTime) / double(accuracyShotTimeout));
 
450
        glVertex3d(-1,0,0);
 
451
        glVertex3d(1,0,0);
 
452
        glVertex3d(0, 100, 0);
 
453
 
 
454
        glColor4d(0, 0, 0, 0);
 
455
        glEnd();
 
456
    }
 
457
}
 
458