[Orxonox-commit 1177] r5898 - in code/branches/core5: data/levels src/modules/pong

landauf at orxonox.net landauf at orxonox.net
Wed Oct 7 02:02:15 CEST 2009


Author: landauf
Date: 2009-10-07 02:02:15 +0200 (Wed, 07 Oct 2009)
New Revision: 5898

Modified:
   code/branches/core5/data/levels/presentation_pong.oxw
   code/branches/core5/src/modules/pong/Pong.cc
   code/branches/core5/src/modules/pong/PongAI.cc
   code/branches/core5/src/modules/pong/PongAI.h
   code/branches/core5/src/modules/pong/PongBall.cc
   code/branches/core5/src/modules/pong/PongBall.h
   code/branches/core5/src/modules/pong/PongCenterpoint.cc
   code/branches/core5/src/modules/pong/PongCenterpoint.h
Log:
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 :)

Modified: code/branches/core5/data/levels/presentation_pong.oxw
===================================================================
--- code/branches/core5/data/levels/presentation_pong.oxw	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/data/levels/presentation_pong.oxw	2009-10-07 00:02:15 UTC (rev 5898)
@@ -63,7 +63,7 @@
 
   <MovableEntity rotationrate=5 rotationaxis="0,0,1">
     <attached>
-      <PongCenterpoint name=pongcenter dimension="200,120" balltemplate=pongball battemplate=pongbat ballspeed=200 batspeed=130 batlength=0.25>
+      <PongCenterpoint name=pongcenter dimension="200,120" balltemplate=pongball battemplate=pongbat ballspeed=200 ballaccfactor=1.0 batspeed=130 batlength=0.25>
         <attached>
           <Model position="0,0,60" mesh="cube.mesh" scale3D="105,1,1" />
           <Model position="0,0,-60" mesh="cube.mesh" scale3D="105,1,1" />

Modified: code/branches/core5/src/modules/pong/Pong.cc
===================================================================
--- code/branches/core5/src/modules/pong/Pong.cc	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/Pong.cc	2009-10-07 00:02:15 UTC (rev 5898)
@@ -75,6 +75,7 @@
             this->ball_->setPosition(0, 0, 0);
             this->ball_->setFieldDimension(this->center_->getFieldDimension());
             this->ball_->setSpeed(0);
+            this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
             this->ball_->setBatLength(this->center_->getBatLength());
 
             if (!this->bat_[0])
@@ -171,6 +172,7 @@
         {
             this->ball_->setPosition(Vector3::ZERO);
             this->ball_->setVelocity(Vector3::ZERO);
+            this->ball_->setAcceleration(Vector3::ZERO);
             this->ball_->setSpeed(0);
         }
 

Modified: code/branches/core5/src/modules/pong/PongAI.cc
===================================================================
--- code/branches/core5/src/modules/pong/PongAI.cc	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongAI.cc	2009-10-07 00:02:15 UTC (rev 5898)
@@ -48,6 +48,7 @@
         this->ballDirection_ = Vector2::ZERO;
         this->ballEndPosition_ = 0;
         this->randomOffset_ = 0;
+        this->bChangedRandomOffset_ = false;
         this->relHysteresisOffset_ = 0.02f;
         this->strength_ = 0.5f;
         this->movement_ = 0;
@@ -112,6 +113,7 @@
                 this->ballDirection_.y = sgn(ballvel.z);
                 this->ballEndPosition_ = 0;
                 this->randomOffset_ = 0;
+                this->bChangedRandomOffset_ = false;
 
                 this->calculateRandomOffset();
                 this->calculateBallEndPosition();
@@ -128,6 +130,18 @@
                 delay = true;
                 this->bOscillationAvoidanceActive_ = false;
             }
+            
+            // If the ball is close enough, calculate another random offset to accelerate the ball
+            if (!this->bChangedRandomOffset_)
+            {
+                float timetohit = (-this->ball_->getPosition().x + this->ball_->getFieldDimension().x / 2 * sgn(this->ball_->getVelocity().x)) / this->ball_->getVelocity().x;
+                if (timetohit < 0.05)
+                {
+                    this->bChangedRandomOffset_ = true;
+                    if (rnd() < this->strength_)
+                        this->calculateRandomOffset();
+                }
+            }
 
             // Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
             if (!this->bOscillationAvoidanceActive_)
@@ -183,33 +197,100 @@
     {
         Vector3 position = this->ball_->getPosition();
         Vector3 velocity = this->ball_->getVelocity();
+        Vector3 acceleration = this->ball_->getAcceleration();
         Vector2 dimension = this->ball_->getFieldDimension();
 
-        // calculate end-height: current height + slope * distance
-        this->ballEndPosition_ = position.z + velocity.z / velocity.x * (-position.x + dimension.x / 2 * sgn(velocity.x));
-
-        // Calculate bounces
-        for (float limit = 0.35f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
+        // Calculate bounces. The number of predicted bounces is limited by the AIs strength
+        for (float limit = -0.05f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
         {
-            // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
-            float randomError = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+            // calculate the time until the ball reaches the other side
+            float totaltime = (-position.x + dimension.x / 2 * sgn(velocity.x)) / velocity.x;
+            
+            // calculate wall bounce position (four possible solutions of the equation: pos.z + vel.z*t + acc.z/2*t^2 = +/- dim.z/2)
+            float bouncetime = totaltime;
+            bool bUpperWall = false;
+            
+            if (acceleration.z == 0)
+            {
+                if (velocity.z > 0)
+                {
+                    bUpperWall = true;
+                    bouncetime = (dimension.y/2 - position.z) / velocity.z;
+                }
+                else if (velocity.z < 0)
+                {
+                    bUpperWall = false;
+                    bouncetime = (-dimension.y/2 - position.z) / velocity.z;
+                }
+            }
+            else
+            {
+                // upper wall
+                float temp = velocity.z*velocity.z + 2*acceleration.z*(dimension.y/2 - position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = true;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = true;
+                    }
+                }
+                // lower wall
+                temp = velocity.z*velocity.z - 2*acceleration.z*(dimension.y/2 + position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = false;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = false;
+                    }
+                }
+            }
 
-            // Bounce from the lower bound
-            if (this->ballEndPosition_ > dimension.y / 2)
+            if (bouncetime < totaltime)
             {
-                // Mirror the predicted position at the upper bound and add some random error
-                this->ballEndPosition_ = dimension.y - this->ballEndPosition_ + randomError;
-                continue;
+                // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
+                float randomErrorX = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+                float randomErrorZ = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+
+                // ball bounces after <bouncetime> seconds, update the position and continue
+                velocity.z = velocity.z + acceleration.z * bouncetime;
+                
+                if (bUpperWall)
+                {
+                    position.z = dimension.y / 2;
+                    velocity.z = -fabs(velocity.z) + fabs(randomErrorZ);
+                }
+                else
+                {
+                    position.z = -dimension.y / 2;
+                    velocity.z = fabs(velocity.z) - fabs(randomErrorZ);
+                }
+                    
+                position.x = position.x + velocity.x * bouncetime + randomErrorX;
+                this->ballEndPosition_ = position.z;
             }
-            // Bounce from the upper bound
-            if (this->ballEndPosition_ < -dimension.y / 2)
+            else
             {
-                // Mirror the predicted position at the lower bound and add some random error
-                this->ballEndPosition_ = -dimension.y - this->ballEndPosition_ + randomError;
-                continue;
+                // ball doesn't bounce, calculate the end position and return
+                // calculate end-height: current height + slope * distance incl. acceleration
+                this->ballEndPosition_ = position.z + velocity.z * totaltime + acceleration.z / 2 * totaltime * totaltime;
+                return;
             }
-            // No bounce - break
-            break;
         }
     }
 

Modified: code/branches/core5/src/modules/pong/PongAI.h
===================================================================
--- code/branches/core5/src/modules/pong/PongAI.h	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongAI.h	2009-10-07 00:02:15 UTC (rev 5898)
@@ -61,6 +61,7 @@
             Vector2 ballDirection_;
             float ballEndPosition_;
             float randomOffset_;
+            bool bChangedRandomOffset_;
             float relHysteresisOffset_;
             float strength_;
 

Modified: code/branches/core5/src/modules/pong/PongBall.cc
===================================================================
--- code/branches/core5/src/modules/pong/PongBall.cc	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongBall.cc	2009-10-07 00:02:15 UTC (rev 5898)
@@ -45,6 +45,7 @@
         RegisterObject(PongBall);
 
         this->speed_ = 0;
+        this->accelerationFactor_ = 1.0f;
         this->bat_ = 0;
         this->batID_ = new unsigned int[2];
         this->batID_[0] = OBJECTID_UNKNOWN;
@@ -75,6 +76,7 @@
 
         Vector3 position = this->getPosition();
         Vector3 velocity = this->getVelocity();
+        Vector3 acceleration = this->getAcceleration();
 
         if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
         {
@@ -101,6 +103,7 @@
                         position.x = this->fieldWidth_ / 2;
                         velocity.x = -velocity.x;
                         velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
+                        acceleration = this->bat_[1]->getVelocity() * this->accelerationFactor_ * -1;
                         
                         this->fireEvent();
                     }
@@ -121,6 +124,7 @@
                         position.x = -this->fieldWidth_ / 2;
                         velocity.x = -velocity.x;
                         velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
+                        acceleration = this->bat_[0]->getVelocity() * this->accelerationFactor_ * -1;
 
                         this->fireEvent();
                     }
@@ -136,6 +140,8 @@
             }
         }
 
+        if (acceleration != this->getAcceleration())
+            this->setAcceleration(acceleration);
         if (velocity != this->getVelocity())
             this->setVelocity(velocity);
         if (position != this->getPosition())

Modified: code/branches/core5/src/modules/pong/PongBall.h
===================================================================
--- code/branches/core5/src/modules/pong/PongBall.h	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongBall.h	2009-10-07 00:02:15 UTC (rev 5898)
@@ -57,6 +57,11 @@
             float getSpeed() const
                 { return this->speed_; }
 
+            void setAccelerationFactor(float factor)
+                { this->accelerationFactor_ = factor; }
+            float getAccelerationFactor() const
+                { return this->accelerationFactor_; }
+
             void setBatLength(float batlength)
                 { this->batlength_ = batlength; }
             float getBatLength() const
@@ -71,6 +76,7 @@
             float fieldWidth_;
             float fieldHeight_;
             float speed_;
+            float accelerationFactor_;
             float batlength_;
             PongBat** bat_;
             unsigned int* batID_;

Modified: code/branches/core5/src/modules/pong/PongCenterpoint.cc
===================================================================
--- code/branches/core5/src/modules/pong/PongCenterpoint.cc	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongCenterpoint.cc	2009-10-07 00:02:15 UTC (rev 5898)
@@ -43,6 +43,7 @@
         this->width_ = 200;
         this->height_ = 120;
         this->ballspeed_ = 100;
+        this->ballaccfactor_ = 1.0;
         this->batspeed_ = 60;
         this->batlength_ = 0.25;
 
@@ -57,6 +58,7 @@
         XMLPortParam(PongCenterpoint, "balltemplate", setBalltemplate, getBalltemplate, xmlelement, mode);
         XMLPortParam(PongCenterpoint, "battemplate", setBattemplate, getBattemplate, xmlelement, mode);
         XMLPortParam(PongCenterpoint, "ballspeed", setBallSpeed, getBallSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballaccfactor", setBallAccelerationFactor, getBallAccelerationFactor, xmlelement, mode);
         XMLPortParam(PongCenterpoint, "batspeed", setBatSpeed, getBatSpeed, xmlelement, mode);
         XMLPortParam(PongCenterpoint, "batlength", setBatLength, getBatLength, xmlelement, mode);
     }

Modified: code/branches/core5/src/modules/pong/PongCenterpoint.h
===================================================================
--- code/branches/core5/src/modules/pong/PongCenterpoint.h	2009-10-06 23:42:47 UTC (rev 5897)
+++ code/branches/core5/src/modules/pong/PongCenterpoint.h	2009-10-07 00:02:15 UTC (rev 5898)
@@ -67,6 +67,11 @@
             float getBallSpeed() const
                 { return this->ballspeed_; }
 
+            void setBallAccelerationFactor(float ballaccfactor)
+                { this->ballaccfactor_ = ballaccfactor; }
+            float getBallAccelerationFactor() const
+                { return this->ballaccfactor_; }
+
             void setBatSpeed(float batspeed)
                 { this->batspeed_ = batspeed; }
             float getBatSpeed() const
@@ -84,6 +89,7 @@
             std::string battemplate_;
 
             float ballspeed_;
+            float ballaccfactor_;
             float batspeed_;
             float batlength_;
 




More information about the Orxonox-commit mailing list