Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SuperOrxoBros_FS17/src/modules/superorxobros/SOBFigure.cc @ 11456

Last change on this file since 11456 was 11420, checked in by jkindle, 8 years ago

Added rotation of coins

File size: 10.2 KB
RevLine 
[11379]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
[11416]23 *      Julien Kindle
[11379]24 *   Co-authors:
[11416]25 *     
[11379]26 *
27 */
28
29/**
30    @file SOBFigure.cc
31    @brief This class represents your figure when you play the minigame. Here the movement of the figure, activating items, ... are handled.
32*/
33
34#include "SOBFigure.h"
35
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38#include "graphics/Model.h"
[11383]39#include "graphics/Camera.h"
[11400]40#include "graphics/ParticleSpawner.h"
[11379]41
[11402]42#include "SOBMushroom.h"
[11412]43#include "SOBGumba.h"
[11405]44#include "SOB.h"
[11412]45#include "SOBFlagstone.h"
[11416]46#include "SOBCastlestone.h"
[11418]47#include <BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
[11400]48
[11379]49namespace orxonox
50{
51    RegisterClass(SOBFigure);
52
53    SOBFigure::SOBFigure(Context* context) : ControllableEntity(context)
54    {
55        RegisterObject(SOBFigure);
56
57        // initialize variables
[11416]58        gravityAcceleration_ = 350.0;
[11383]59
[11416]60        //Vars for movement of player
[11379]61        moveUpPressed_ = false;
62        moveDownPressed_ = false;
63        moveLeftPressed_ = false;
64        moveDownPressed_ = false;
65        firePressed_ = false;
[11418]66        collDisZ_ = 0;
[11416]67        //Times and turning
[11379]68        timeSinceLastFire_ = 0.0;
[11383]69        lastSpeed_z = 0.0;
[11416]70        pitch_ = 0.0;
71        timeCounter_ = 0;
72
73        //Properties of player
74        gotPowerUp_ = false;
[11400]75        isColliding_ = true;
76        particlespawner_ = NULL;
[11383]77
[11416]78        //Properties of players life
[11412]79        predead_ = false;
[11379]80        dead_ = false;
[11416]81        lvlEnded_ = false;
82        reachedLvlEndState_ = 0;
83
[11405]84       
[11416]85        setAngularFactor(0.0); //Means player doesn't turn on collision, so he doesn't fall over while walking over the ground
86        this->enableCollisionCallback(); // Turns on that on every collision function collidesAgainst is executed
[11379]87    }
88
[11400]89
90
91    bool SOBFigure::collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint) {
92
[11418]93        //Inform tick fct that player is colliding and tell him how far away the collision point is from player middle point in z dir
[11400]94        isColliding_ = true;
[11418]95        collDisZ_ = getPosition().z - contactPoint.getPositionWorldOnB().getZ();
[11416]96
[11418]97
[11416]98        //Orxocast returns object with casted type if otherObject has that class, and if not a nullptr
[11402]99        SOBMushroom* mush = orxonox_cast<SOBMushroom*>(otherObject);
[11412]100        SOBGumba* gumba = orxonox_cast<SOBGumba*>(otherObject);
101        SOBFlagstone* flagstone = orxonox_cast<SOBFlagstone*>(otherObject);
[11416]102        SOBCastlestone* castlestone = orxonox_cast<SOBCastlestone*>(otherObject);
[11412]103
[11416]104        //Check if otherObject is a powerup
[11405]105        if (mush != nullptr && !(mush->hasCollided_)) {
106            otherObject->destroyLater();
107            gotPowerUp_ = true;
[11416]108            SOB* SOBGame = orxonox_cast<SOB*>(getGametype()); //Get the Gametype
109            SOBGame->addMushroom(); // Tell the gametype to increase points
110            mush->hasCollided_ = true; // needed because of destroyLater takes some time and player should receive points only once
[11405]111
[11416]112        //Check if otherObject is a Gumba (that walking enemies)
[11412]113        } else if (gumba != nullptr && !(gumba->hasCollided_)) {
114
[11416]115            //If player jumps on its head, kill it, else, kill the player
[11412]116            if (getVelocity().z >= -20) {
117              Vector3 vel = getVelocity();
118              vel.y = -80;
119              vel.z = 200;
120              setVelocity(vel);
121              predead_=true; 
[11418]122              SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
123              SOBGame->setDone(true);
[11416]124
[11412]125          } else {
126            gumba->destroyLater();
127            gumba->hasCollided_ = true;
128            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
129            SOBGame->addGumba();
130
131
[11402]132        }
[11400]133    }
134
[11416]135    //Purpose is that if player hits the flag, he should walk into the castle at the end of the level. For that we use SOBCastlestone
136    if (reachedLvlEndState_ == 0 && flagstone != nullptr && !(flagstone->hasCollided_)) {
137        flagstone->hasCollided_ = true;
138        reachedLvlEndState_ = 1;
139        SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
[11418]140        SOBGame->setDone(true);
[11416]141        SOBGame->addPoints(flagstone->getPoints());
[11418]142       
[11400]143
[11416]144    }
145    if (castlestone != nullptr && !(castlestone->hasCollided_)) {
146        castlestone->hasCollided_ = true;
147        reachedLvlEndState_++;
[11400]148
[11416]149    }
150
[11412]151    return true;
152}
[11383]153
[11379]154
[11416]155//Self implemented sign function that returns either 1 or -1 (and never 0)
[11412]156int SOBFigure::sgn(float x) {
157    if (x < 0.0) return -1;
158    return 1;
159}
160
[11416]161//For those of you who don't have an idea: the tick function is called about 50 times/sec
[11412]162void SOBFigure::tick(float dt)
163{
164    SUPER(SOBFigure, tick, dt);
165
[11416]166
167    bool inputAllowed = true;
168
169    //the particle spawner that generates the fire from the backpack when pressed
[11412]170    if (particlespawner_ == NULL) {
171        for (WorldEntity* object : this->getAttachedObjects())
172        {
[11416]173           if (object->isA(Class(ParticleSpawner)))
[11412]174            particlespawner_ = object;
[11416]175        }
[11405]176    }
[11400]177
178
[11416]179    //Behavior on level end - this is like described above for the movement from the player when hit the flag. He moves then into the castle
180    if (reachedLvlEndState_ != 0) {
181        timeCounter_+= dt;
182        inputAllowed = false;
183    }
184    if (reachedLvlEndState_ == 1 && timeCounter_ >= 1.5) {
185        timeCounter_ = 0;
186        reachedLvlEndState_ = 2;
187    }
[11400]188
[11402]189
[11416]190    //if input blocked, then cancel every movement operation
191    if (!inputAllowed) {
192        moveUpPressed_ = false;
193        moveDownPressed_ = false;
194        moveLeftPressed_ = false;
195        moveRightPressed_ = false;
196    }
[11400]197
[11416]198    //set the gravityto standard 350
199    if (firePressed_ == false) {
200        gravityAcceleration_ = 350.0;
[11400]201
[11416]202    }
[11379]203
[11416]204    if (hasLocalController())
205    {
206        Vector3 velocity = getVelocity();
207        Vector3 position = getPosition();
[11402]208
[11416]209        if (!predead_)
210            velocity.y = 0;
[11418]211        //If player falls in a hole
[11416]212        if (position.z < -100) {
213            dead_ = true;
[11418]214            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
215            SOBGame->setDone(true);
[11416]216        }
[11402]217
[11381]218
[11416]219        if (dead_) {
220            velocity.x = 0;
221            velocity.z = 0;
222            setVelocity(velocity);
223            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
224            if (firePressed_)
225                SOBGame->restart();
226            return;
227        }
[11379]228
229
[11416]230        int maxvelocity_x = 100;
231        int speedAddedPerTick = 5;
232        int camMaxOffset = 25;
[11381]233
[11416]234        timeSinceLastFire_ += dt;
235        lastSpeed_z = velocity.z;
[11381]236
237
[11405]238
[11416]239        //Handle the rocket fire from the jetpack
240        if (velocity.z > 40)
241            particlespawner_->setVisible(true); 
242        else
243            particlespawner_->setVisible(false); 
[11405]244
[11412]245
[11418]246        //If player hits space and collides against an object under him then jump
247        if (inputAllowed && firePressed_ && isColliding_ && (collDisZ_ >= 7.75 && collDisZ_ <+ 8.25)) {
[11416]248            gravityAcceleration_ = 100.0;
[11418]249            velocity.z = 110; 
[11392]250        }
[11381]251
[11392]252
[11420]253        //Left-right movement with acceleration and rotation
[11400]254        float rot = getOrientation().getRoll().valueDegrees();
[11383]255        if (moveRightPressed_) {
[11412]256            if (!(rot < 5.0 && -5.0 < rot))
257                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() - sgn(rot)*dt*Radian(6));
[11400]258
[11383]259            if (std::abs(velocity.x) < maxvelocity_x) {
260                velocity.x += speedAddedPerTick;
[11400]261
[11379]262            }
[11383]263        } else if (moveLeftPressed_) {
[11412]264            if (!(abs(rot) > 175.0 ))
265                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() + sgn(rot)*dt*Radian(6));
[11400]266
[11412]267
268
[11383]269            if (std::abs(velocity.x) < maxvelocity_x) {
270                velocity.x -= speedAddedPerTick;
[11379]271            }
[11383]272        } else {
273            velocity.x /= 1.1;
[11392]274        }
[11379]275
[11392]276
[11416]277        //Again another EndOfLevel behavior
278        if (reachedLvlEndState_ == 1)
279            velocity.x = -2;
280        if (reachedLvlEndState_ == 2)
281            velocity.x = 30;
282        if (reachedLvlEndState_ == 3) {
283            velocity.x = 0;
284            velocity.y = 20;
285        }
286        if (reachedLvlEndState_ == 4) {
287            lvlEnded_ = true;
288            dead_ = true;
289        }
290
291        //velocity = acc. * time
[11383]292        velocity.z -= gravityAcceleration_*dt;
293        setVelocity(velocity);
[11379]294
295
[11416]296        //Camera operation - the camera should always follow the player in a specific region
[11383]297        Camera* cam = getCamera();
298        Vector3 campos = cam->getPosition();
[11379]299
[11383]300        if (campos.x + camMaxOffset < position.x) {
301            campos.x = position.x - camMaxOffset;
302            cam->setPosition(campos);
[11379]303        }
[11405]304        if (campos.x - camMaxOffset > position.x) {
[11383]305            campos.x = position.x + camMaxOffset;
306            cam->setPosition(campos);
307        }
[11379]308
[11383]309
310
[11392]311
[11383]312    }
313
314
[11379]315
[11416]316    // Reset key variables
[11383]317    moveUpPressed_ = false;
318    moveDownPressed_ = false;
319    moveLeftPressed_ = false;
320    moveRightPressed_ = false;
[11416]321
[11400]322    isColliding_ = false;
[11418]323    collDisZ_ = 0;
[11379]324
[11383]325}
[11379]326
327
[11383]328
329
330
[11416]331//The following functions read the input of the player and then set the bools for the movement
[11383]332void SOBFigure::moveFrontBack(const Vector2& value)
333{
334    if (value.x > 0)
[11379]335    {
[11383]336        moveUpPressed_ = true;
337        moveDownPressed_ = false;
[11379]338    }
[11383]339    else
340    {
341        moveUpPressed_ = false;
342        moveDownPressed_ = true;
343    }
344}
[11379]345
[11383]346void SOBFigure::moveRightLeft(const Vector2& value)
347{
348    if (value.x > 0)
[11379]349    {
[11383]350        moveLeftPressed_ = false;
351        moveRightPressed_ = true;
[11379]352    }
[11383]353    else
354    {
355        moveLeftPressed_ = true;
356        moveRightPressed_ = false;
357    }
358}
[11379]359
[11383]360void SOBFigure::boost(bool boost)
361{
[11400]362    firePressed_ = boost;
[11379]363}
[11416]364
365
[11383]366}
Note: See TracBrowser for help on using the repository browser.