Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 7, 2009, 2:02:15 AM (15 years ago)
Author:
landauf
Message:

Enhanced Pong gametype: It's now possible to accelerate the ball in the y direction by giving him a spin with a moving bat. Bots also support the new feature. Have fun :)

Location:
code/branches/core5/src/modules/pong
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core5/src/modules/pong/Pong.cc

    r5893 r5898  
    7676            this->ball_->setFieldDimension(this->center_->getFieldDimension());
    7777            this->ball_->setSpeed(0);
     78            this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
    7879            this->ball_->setBatLength(this->center_->getBatLength());
    7980
     
    172173            this->ball_->setPosition(Vector3::ZERO);
    173174            this->ball_->setVelocity(Vector3::ZERO);
     175            this->ball_->setAcceleration(Vector3::ZERO);
    174176            this->ball_->setSpeed(0);
    175177        }
  • code/branches/core5/src/modules/pong/PongAI.cc

    r5831 r5898  
    4949        this->ballEndPosition_ = 0;
    5050        this->randomOffset_ = 0;
     51        this->bChangedRandomOffset_ = false;
    5152        this->relHysteresisOffset_ = 0.02f;
    5253        this->strength_ = 0.5f;
     
    113114                this->ballEndPosition_ = 0;
    114115                this->randomOffset_ = 0;
     116                this->bChangedRandomOffset_ = false;
    115117
    116118                this->calculateRandomOffset();
     
    129131                this->bOscillationAvoidanceActive_ = false;
    130132            }
     133           
     134            // If the ball is close enough, calculate another random offset to accelerate the ball
     135            if (!this->bChangedRandomOffset_)
     136            {
     137                float timetohit = (-this->ball_->getPosition().x + this->ball_->getFieldDimension().x / 2 * sgn(this->ball_->getVelocity().x)) / this->ball_->getVelocity().x;
     138                if (timetohit < 0.05)
     139                {
     140                    this->bChangedRandomOffset_ = true;
     141                    if (rnd() < this->strength_)
     142                        this->calculateRandomOffset();
     143                }
     144            }
    131145
    132146            // Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
     
    184198        Vector3 position = this->ball_->getPosition();
    185199        Vector3 velocity = this->ball_->getVelocity();
     200        Vector3 acceleration = this->ball_->getAcceleration();
    186201        Vector2 dimension = this->ball_->getFieldDimension();
    187202
    188         // calculate end-height: current height + slope * distance
    189         this->ballEndPosition_ = position.z + velocity.z / velocity.x * (-position.x + dimension.x / 2 * sgn(velocity.x));
    190 
    191         // Calculate bounces
    192         for (float limit = 0.35f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
    193         {
    194             // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
    195             float randomError = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
    196 
    197             // Bounce from the lower bound
    198             if (this->ballEndPosition_ > dimension.y / 2)
    199             {
    200                 // Mirror the predicted position at the upper bound and add some random error
    201                 this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + randomError;
    202                 continue;
    203             }
    204             // Bounce from the upper bound
    205             if (this->ballEndPosition_ < -dimension.y / 2)
    206             {
    207                 // Mirror the predicted position at the lower bound and add some random error
    208                 this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + randomError;
    209                 continue;
    210             }
    211             // No bounce - break
    212             break;
     203        // Calculate bounces. The number of predicted bounces is limited by the AIs strength
     204        for (float limit = -0.05f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
     205        {
     206            // calculate the time until the ball reaches the other side
     207            float totaltime = (-position.x + dimension.x / 2 * sgn(velocity.x)) / velocity.x;
     208           
     209            // calculate wall bounce position (four possible solutions of the equation: pos.z + vel.z*t + acc.z/2*t^2 = +/- dim.z/2)
     210            float bouncetime = totaltime;
     211            bool bUpperWall = false;
     212           
     213            if (acceleration.z == 0)
     214            {
     215                if (velocity.z > 0)
     216                {
     217                    bUpperWall = true;
     218                    bouncetime = (dimension.y/2 - position.z) / velocity.z;
     219                }
     220                else if (velocity.z < 0)
     221                {
     222                    bUpperWall = false;
     223                    bouncetime = (-dimension.y/2 - position.z) / velocity.z;
     224                }
     225            }
     226            else
     227            {
     228                // upper wall
     229                float temp = velocity.z*velocity.z + 2*acceleration.z*(dimension.y/2 - position.z);
     230                if (temp >= 0)
     231                {
     232                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
     233                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
     234                    if (t1 > 0 && t1 < bouncetime)
     235                    {
     236                        bouncetime = t1;
     237                        bUpperWall = true;
     238                    }
     239                    if (t2 > 0 && t2 < bouncetime)
     240                    {
     241                        bouncetime = t2;
     242                        bUpperWall = true;
     243                    }
     244                }
     245                // lower wall
     246                temp = velocity.z*velocity.z - 2*acceleration.z*(dimension.y/2 + position.z);
     247                if (temp >= 0)
     248                {
     249                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
     250                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
     251                    if (t1 > 0 && t1 < bouncetime)
     252                    {
     253                        bouncetime = t1;
     254                        bUpperWall = false;
     255                    }
     256                    if (t2 > 0 && t2 < bouncetime)
     257                    {
     258                        bouncetime = t2;
     259                        bUpperWall = false;
     260                    }
     261                }
     262            }
     263
     264            if (bouncetime < totaltime)
     265            {
     266                // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
     267                float randomErrorX = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
     268                float randomErrorZ = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
     269
     270                // ball bounces after <bouncetime> seconds, update the position and continue
     271                velocity.z = velocity.z + acceleration.z * bouncetime;
     272               
     273                if (bUpperWall)
     274                {
     275                    position.z = dimension.y / 2;
     276                    velocity.z = -fabs(velocity.z) + fabs(randomErrorZ);
     277                }
     278                else
     279                {
     280                    position.z = -dimension.y / 2;
     281                    velocity.z = fabs(velocity.z) - fabs(randomErrorZ);
     282                }
     283                   
     284                position.x = position.x + velocity.x * bouncetime + randomErrorX;
     285                this->ballEndPosition_ = position.z;
     286            }
     287            else
     288            {
     289                // ball doesn't bounce, calculate the end position and return
     290                // calculate end-height: current height + slope * distance incl. acceleration
     291                this->ballEndPosition_ = position.z + velocity.z * totaltime + acceleration.z / 2 * totaltime * totaltime;
     292                return;
     293            }
    213294        }
    214295    }
  • code/branches/core5/src/modules/pong/PongAI.h

    r5831 r5898  
    6262            float ballEndPosition_;
    6363            float randomOffset_;
     64            bool bChangedRandomOffset_;
    6465            float relHysteresisOffset_;
    6566            float strength_;
  • code/branches/core5/src/modules/pong/PongBall.cc

    r5892 r5898  
    4646
    4747        this->speed_ = 0;
     48        this->accelerationFactor_ = 1.0f;
    4849        this->bat_ = 0;
    4950        this->batID_ = new unsigned int[2];
     
    7677        Vector3 position = this->getPosition();
    7778        Vector3 velocity = this->getVelocity();
     79        Vector3 acceleration = this->getAcceleration();
    7880
    7981        if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
     
    102104                        velocity.x = -velocity.x;
    103105                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
     106                        acceleration = this->bat_[1]->getVelocity() * this->accelerationFactor_ * -1;
    104107                       
    105108                        this->fireEvent();
     
    122125                        velocity.x = -velocity.x;
    123126                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
     127                        acceleration = this->bat_[0]->getVelocity() * this->accelerationFactor_ * -1;
    124128
    125129                        this->fireEvent();
     
    137141        }
    138142
     143        if (acceleration != this->getAcceleration())
     144            this->setAcceleration(acceleration);
    139145        if (velocity != this->getVelocity())
    140146            this->setVelocity(velocity);
  • code/branches/core5/src/modules/pong/PongBall.h

    r5892 r5898  
    5858                { return this->speed_; }
    5959
     60            void setAccelerationFactor(float factor)
     61                { this->accelerationFactor_ = factor; }
     62            float getAccelerationFactor() const
     63                { return this->accelerationFactor_; }
     64
    6065            void setBatLength(float batlength)
    6166                { this->batlength_ = batlength; }
     
    7277            float fieldHeight_;
    7378            float speed_;
     79            float accelerationFactor_;
    7480            float batlength_;
    7581            PongBat** bat_;
  • code/branches/core5/src/modules/pong/PongCenterpoint.cc

    r5806 r5898  
    4444        this->height_ = 120;
    4545        this->ballspeed_ = 100;
     46        this->ballaccfactor_ = 1.0;
    4647        this->batspeed_ = 60;
    4748        this->batlength_ = 0.25;
     
    5859        XMLPortParam(PongCenterpoint, "battemplate", setBattemplate, getBattemplate, xmlelement, mode);
    5960        XMLPortParam(PongCenterpoint, "ballspeed", setBallSpeed, getBallSpeed, xmlelement, mode);
     61        XMLPortParam(PongCenterpoint, "ballaccfactor", setBallAccelerationFactor, getBallAccelerationFactor, xmlelement, mode);
    6062        XMLPortParam(PongCenterpoint, "batspeed", setBatSpeed, getBatSpeed, xmlelement, mode);
    6163        XMLPortParam(PongCenterpoint, "batlength", setBatLength, getBatLength, xmlelement, mode);
  • code/branches/core5/src/modules/pong/PongCenterpoint.h

    r5738 r5898  
    6868                { return this->ballspeed_; }
    6969
     70            void setBallAccelerationFactor(float ballaccfactor)
     71                { this->ballaccfactor_ = ballaccfactor; }
     72            float getBallAccelerationFactor() const
     73                { return this->ballaccfactor_; }
     74
    7075            void setBatSpeed(float batspeed)
    7176                { this->batspeed_ = batspeed; }
     
    8590
    8691            float ballspeed_;
     92            float ballaccfactor_;
    8793            float batspeed_;
    8894            float batlength_;
Note: See TracChangeset for help on using the changeset viewer.