[Orxonox-commit 3417] r8104 - code/branches/tetris/src/modules/pong
dafrick at orxonox.net
dafrick at orxonox.net
Wed Mar 23 07:40:37 CET 2011
Author: dafrick
Date: 2011-03-23 07:40:36 +0100 (Wed, 23 Mar 2011)
New Revision: 8104
Modified:
code/branches/tetris/src/modules/pong/Pong.cc
code/branches/tetris/src/modules/pong/Pong.h
code/branches/tetris/src/modules/pong/PongBall.cc
code/branches/tetris/src/modules/pong/PongBall.h
Log:
Started documenting Pong.
Modified: code/branches/tetris/src/modules/pong/Pong.cc
===================================================================
--- code/branches/tetris/src/modules/pong/Pong.cc 2011-03-22 14:22:54 UTC (rev 8103)
+++ code/branches/tetris/src/modules/pong/Pong.cc 2011-03-23 06:40:36 UTC (rev 8104)
@@ -26,11 +26,17 @@
*
*/
+/**
+ @file Pong.cc
+ @brief Implementation of the Pong class.
+*/
+
#include "Pong.h"
#include "core/CoreIncludes.h"
#include "core/EventIncludes.h"
#include "core/command/Executor.h"
+
#include "PongCenterpoint.h"
#include "PongBall.h"
#include "PongBat.h"
@@ -39,11 +45,16 @@
namespace orxonox
{
+ // Events to allow to react to scoring of a player, in the level-file.
CreateEventName(PongCenterpoint, right);
CreateEventName(PongCenterpoint, left);
CreateUnloadableFactory(Pong);
+ /**
+ @brief
+ Constructor. Registers and initializes the object.
+ */
Pong::Pong(BaseObject* creator) : Deathmatch(creator)
{
RegisterObject(Pong);
@@ -55,29 +66,40 @@
this->setHUDTemplate("PongHUD");
+ // Pre-set the timer, but don't start it yet.
this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Pong::startBall, this)));
this->starttimer_.stopTimer();
+ // Set the type of Bots for this particular Gametype.
this->botclass_ = Class(PongBot);
}
+ /**
+ @brief
+ Destructor. Cleans up, if initialized.
+ */
Pong::~Pong()
{
if (this->isInitialized())
this->cleanup();
}
+ /**
+ @brief
+ Cleans up the Gametype by destroying the ball and the bats.
+ */
void Pong::cleanup()
{
- if (this->ball_)
+ if (this->ball_ != NULL) // Destroy the ball, if present.
{
this->ball_->destroy();
this->ball_ = 0;
}
+ // Destroy both bats, if present.
for (size_t i = 0; i < 2; ++i)
{
- if (this->bat_[0])
+ if (this->bat_[0] != NULL)
{
this->bat_[0]->destroy();
this->bat_[0] = 0;
@@ -85,16 +107,22 @@
}
}
+ /**
+ @brief
+ Starts the Pong minigame.
+ */
void Pong::start()
{
- if (this->center_)
+ if (this->center_ != NULL) // There needs to be a PongCenterpoint, i.e. the area the game takes place.
{
- if (!this->ball_)
+ if (this->ball_ == NULL) // If there is no ball, create a new ball.
{
this->ball_ = new PongBall(this->center_);
+ // Apply the template for the ball specified by the centerpoint.
this->ball_->addTemplate(this->center_->getBalltemplate());
}
+ // Attach the ball to the centerpoint and set the parameters as specified in the centerpoint, the ball is attached to.
this->center_->attach(this->ball_);
this->ball_->setPosition(0, 0, 0);
this->ball_->setFieldDimension(this->center_->getFieldDimension());
@@ -102,17 +130,17 @@
this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
this->ball_->setBatLength(this->center_->getBatLength());
- if (!this->bat_[0])
+ // If one of the bats is missing, create it. Apply the template for the bats as specified in the centerpoint.
+ for (size_t i = 0; i < 2; ++i)
{
- this->bat_[0] = new PongBat(this->center_);
- this->bat_[0]->addTemplate(this->center_->getBattemplate());
+ if (this->bat_[i] == NULL)
+ {
+ this->bat_[i] = new PongBat(this->center_);
+ this->bat_[i]->addTemplate(this->center_->getBattemplate());
+ }
}
- if (!this->bat_[1])
- {
- this->bat_[1] = new PongBat(this->center_);
- this->bat_[1]->addTemplate(this->center_->getBattemplate());
- }
+ // Attach the bats to the centerpoint and set the parameters as specified in the centerpoint, the bats are attached to.
this->center_->attach(this->bat_[0]);
this->center_->attach(this->bat_[1]);
this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
@@ -126,31 +154,45 @@
this->bat_[0]->setLength(this->center_->getBatLength());
this->bat_[1]->setLength(this->center_->getBatLength());
+ // Set the bats for the ball.
this->ball_->setBats(this->bat_);
}
- else
+ else // If no centerpoint was specified, an error is thrown.
{
COUT(1) << "Error: No Centerpoint specified." << std::endl;
+ // TODO: End the game?
}
+ // Start the timer. After it has expired the ball is started.
this->starttimer_.startTimer();
-
+ // Set variable to temporarily force the player to spawn.
bool temp = this->bForceSpawn_;
this->bForceSpawn_ = true;
+ // Call start for the parent class.
Deathmatch::start();
+ // Reset the variable.
this->bForceSpawn_ = temp;
}
+ /**
+ @brief
+ Ends the Pong minigame.
+ */
void Pong::end()
{
this->cleanup();
+ // Call end for the parent class.
Deathmatch::end();
}
+ /**
+ @brief
+ Spawns players, and fills the rest up with bots.
+ */
void Pong::spawnPlayersIfRequested()
{
// first spawn human players to assign always the left bat to the player in singleplayer
@@ -163,44 +205,63 @@
this->spawnPlayer(it->first);
}
+ /**
+ @brief
+ Spawns the input player.
+ @param player
+ The player tp be spawned.
+ */
void Pong::spawnPlayer(PlayerInfo* player)
{
- if (!this->bat_[0]->getPlayer())
+ assert(player);
+
+ // If the first (left) bat has no player.
+ if (this->bat_[0]->getPlayer() == NULL)
{
player->startControl(this->bat_[0]);
this->players_[player].state_ = PlayerState::Alive;
}
- else if (!this->bat_[1]->getPlayer())
+ // If the second (right) bat has no player.
+ else if (this->bat_[1]->getPlayer() == NULL)
{
player->startControl(this->bat_[1]);
this->players_[player].state_ = PlayerState::Alive;
}
+ // If both bats are taken.
else
return;
- if (player && player->getController() && player->getController()->isA(Class(PongAI)))
+ // If the player is an AI, it receives a pointer to the ball.
+ if (player->getController() != NULL && player->getController()->isA(Class(PongAI)))
{
PongAI* ai = orxonox_cast<PongAI*>(player->getController());
ai->setPongBall(this->ball_);
}
}
+ /**
+ @brief
+ Is called when the player scored.
+ */
void Pong::playerScored(PlayerInfo* player)
{
Deathmatch::playerScored(player);
- if (this->center_)
+ if (this->center_ != NULL) // If there is a centerpoint.
{
+ // Fire an event for the player that has scored, to be able to react to it in the level, e.g. by displaying fireworks.
if (player == this->getRightPlayer())
this->center_->fireEvent(FireEventName(PongCenterpoint, right));
else if (player == this->getLeftPlayer())
this->center_->fireEvent(FireEventName(PongCenterpoint, left));
- if (player)
+ // Also announce, that the player has scored.
+ if (player != NULL)
this->gtinfo_->sendAnnounceMessage(player->getName() + " scored");
}
- if (this->ball_)
+ // If there is a ball present, reset its position, velocity and acceleration.
+ if (this->ball_ != NULL)
{
this->ball_->setPosition(Vector3::ZERO);
this->ball_->setVelocity(Vector3::ZERO);
@@ -208,32 +269,50 @@
this->ball_->setSpeed(0);
}
- if (this->bat_[0] && this->bat_[1])
+ // If there are bats reset them to the middle position.
+ if (this->bat_[0] != NULL && this->bat_[1] != NULL)
{
this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
}
+ // Restart the timer to start the ball.
this->starttimer_.startTimer();
}
+ /**
+ @brief
+ Starts the ball with some default speed.
+ */
void Pong::startBall()
{
- if (this->ball_ && this->center_)
+ if (this->ball_ != NULL && this->center_ != NULL)
this->ball_->setSpeed(this->center_->getBallSpeed());
}
+ /**
+ @brief
+ Get the left player.
+ @return
+ Returns a pointer to the player playing on the left. If there is no left player, NULL is returned.
+ */
PlayerInfo* Pong::getLeftPlayer() const
{
- if (this->bat_ && this->bat_[0])
+ if (this->bat_ != NULL && this->bat_[0] != NULL)
return this->bat_[0]->getPlayer();
else
return 0;
}
+ /**
+ @brief
+ Get the right player.
+ @return
+ Returns a pointer to the player playing on the right. If there is no right player, NULL is returned.
+ */
PlayerInfo* Pong::getRightPlayer() const
{
- if (this->bat_ && this->bat_[1])
+ if (this->bat_ != NULL && this->bat_[1] != NULL)
return this->bat_[1]->getPlayer();
else
return 0;
Modified: code/branches/tetris/src/modules/pong/Pong.h
===================================================================
--- code/branches/tetris/src/modules/pong/Pong.h 2011-03-22 14:22:54 UTC (rev 8103)
+++ code/branches/tetris/src/modules/pong/Pong.h 2011-03-23 06:40:36 UTC (rev 8104)
@@ -26,45 +26,69 @@
*
*/
+/**
+ @file Pong.h
+ @brief Declaration of the Pong class.
+ @ingroup Pong
+*/
+
#ifndef _Pong_H__
#define _Pong_H__
#include "pong/PongPrereqs.h"
#include "tools/Timer.h"
+
#include "gametypes/Deathmatch.h"
namespace orxonox
{
+
+ /**
+ @brief
+ Implements a Pong minigame.
+
+ //TODO: Add details to different classes used and how.
+ PongBall, is the ball, PongBats are the things that can be moved by the players (ControllableEntities), PongCenterpoint is the playing field. (x-z area)
+
+ @author
+ Fabian 'x3n' Landau
+
+ @ingroup Pong
+ */
class _PongExport Pong : public Deathmatch
{
public:
- Pong(BaseObject* creator);
- virtual ~Pong();
+ Pong(BaseObject* creator); //!< Constructor. Registers and initializes the object.
+ virtual ~Pong(); //!< Destructor. Cleans up, if initialized.
- virtual void start();
- virtual void end();
+ virtual void start(); //!< Starts the Pong minigame.
+ virtual void end(); ///!< Ends the Pong minigame.
- virtual void spawnPlayer(PlayerInfo* player);
+ virtual void spawnPlayer(PlayerInfo* player); //!< Spawns the input player.
- virtual void playerScored(PlayerInfo* player);
+ virtual void playerScored(PlayerInfo* player); //!< Is called when the player scored.
+ /**
+ @brief Set the PongCenterpoint (the playing field).
+ @param center A pointer to the PongCenterpoint to be set.
+ */
void setCenterpoint(PongCenterpoint* center)
{ this->center_ = center; }
- PlayerInfo* getLeftPlayer() const;
- PlayerInfo* getRightPlayer() const;
+ PlayerInfo* getLeftPlayer() const; //!< Get the left player.
+ PlayerInfo* getRightPlayer() const; //!< Get the right player.
protected:
- virtual void spawnPlayersIfRequested();
+ virtual void spawnPlayersIfRequested(); //!< Spawns players, and fills the rest up with bots.
- void startBall();
- void cleanup();
+ void startBall(); //!< Starts the ball with some default speed.
+ void cleanup(); //!< Cleans up the Gametype by destroying the ball and the bats.
- WeakPtr<PongCenterpoint> center_;
- WeakPtr<PongBall> ball_;
- WeakPtr<PongBat> bat_[2];
- Timer starttimer_;
+ WeakPtr<PongCenterpoint> center_; //!< The playing field.
+ WeakPtr<PongBall> ball_; //!< The Pong ball.
+ WeakPtr<PongBat> bat_[2]; //!< The two bats.
+ Timer starttimer_; //!< A timer to delay the start of the game.
};
}
Modified: code/branches/tetris/src/modules/pong/PongBall.cc
===================================================================
--- code/branches/tetris/src/modules/pong/PongBall.cc 2011-03-22 14:22:54 UTC (rev 8103)
+++ code/branches/tetris/src/modules/pong/PongBall.cc 2011-03-23 06:40:36 UTC (rev 8104)
@@ -26,11 +26,18 @@
*
*/
+/**
+ @file PongBall.cc
+ @brief Implementation of the PongBall class.
+*/
+
#include "PongBall.h"
#include "core/CoreIncludes.h"
#include "core/GameMode.h"
+
#include "gametypes/Gametype.h"
+
#include "PongBat.h"
namespace orxonox
@@ -39,6 +46,10 @@
const float PongBall::MAX_REL_Z_VELOCITY = 1.5;
+ /**
+ @brief
+ Constructor. Registers and initializes the object.
+ */
PongBall::PongBall(BaseObject* creator)
: MovableEntity(creator)
{
@@ -56,6 +67,10 @@
this->registerVariables();
}
+ /**
+ @brief
+ Destructor.
+ */
PongBall::~PongBall()
{
if (this->isInitialized())
@@ -67,6 +82,10 @@
}
}
+ /**
+ @brief
+ Register variables to synchronize over the network.
+ */
void PongBall::registerVariables()
{
registerVariable( this->fieldWidth_ );
@@ -78,17 +97,28 @@
registerVariable( this->batID_[1], VariableDirection::ToClient, new NetworkCallback<PongBall>( this, &PongBall::applyBats) );
}
+ /**
+ @brief
+ Is called every tick.
+ //TODO: Explain in detail what happens here.
+ @param dt
+ The time since the last tick.
+ */
void PongBall::tick(float dt)
{
SUPER(PongBall, tick, dt);
+ // Get the current position, velocity and acceleration of the ball.
Vector3 position = this->getPosition();
Vector3 velocity = this->getVelocity();
Vector3 acceleration = this->getAcceleration();
+ // If the ball has gone over the top or bottom boundary of the playing field (i.e. the ball has hit the top or bottom delimiters).
if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
{
+ // Its velocity in z-direction is inverted (i.e. it bounces off).
velocity.z = -velocity.z;
+ // And its position is set as to not overstep the boundary it has just crossed.
if (position.z > this->fieldHeight_ / 2)
position.z = this->fieldHeight_ / 2;
if (position.z < -this->fieldHeight_ / 2)
@@ -97,24 +127,31 @@
this->fireEvent();
}
+ // If the ball has crossed the left or right boundary of the playing field (i.e. a player has just scored, if the bat isn't there to parry).
if (position.x > this->fieldWidth_ / 2 || position.x < -this->fieldWidth_ / 2)
{
float distance = 0;
- if (this->bat_)
+ if (this->bat_ != NULL) // If there are bats.
{
- if (position.x > this->fieldWidth_ / 2 && this->bat_[1])
+ // If the right boundary has been crossed.
+ if (position.x > this->fieldWidth_ / 2 && this->bat_[1] != NULL)
{
+ // Calculate the distance (in z-direction) between the ball and the center of the bat, weighted by half of the effective length of the bat (with additional 10%)
distance = (position.z - this->bat_[1]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
- if (fabs(distance) <= 1)
+ if (fabs(distance) <= 1) // If the bat is there to parry.
{
+ // Set the ball to be exactly at the boundary.
position.x = this->fieldWidth_ / 2;
+ // Invert its veloxity in x-direction (i.e. it bounces off).
velocity.x = -velocity.x;
+ // Adjust the velocity in the z-direction, depending on where the ball hit the bat.
velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
acceleration = this->bat_[1]->getVelocity() * this->accelerationFactor_ * -1;
this->fireEvent();
}
+ // If the left player scores.
else if (GameMode::isMaster() && position.x > this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
{
if (this->getGametype() && this->bat_[0])
@@ -124,18 +161,24 @@
}
}
}
- if (position.x < -this->fieldWidth_ / 2 && this->bat_[0])
+ // If the left boundary has been crossed.
+ else if (position.x < -this->fieldWidth_ / 2 && this->bat_[0] != NULL)
{
+ // Calculate the distance (in z-direction) between the ball and the center of the bat, weighted by half of the effective length of the bat (with additional 10%)
distance = (position.z - this->bat_[0]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
- if (fabs(distance) <= 1)
+ if (fabs(distance) <= 1) // If the bat is there to parry.
{
+ // Set the ball to be exactly at the boundary.
position.x = -this->fieldWidth_ / 2;
+ // Invert its veloxity in x-direction (i.e. it bounces off).
velocity.x = -velocity.x;
+ // Adjust the velocity in the z-direction, depending on where the ball hit the bat.
velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
acceleration = this->bat_[0]->getVelocity() * this->accelerationFactor_ * -1;
this->fireEvent();
}
+ // If the right player scores.
else if (GameMode::isMaster() && position.x < -this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
{
if (this->getGametype() && this->bat_[1])
@@ -148,6 +191,7 @@
}
}
+ // Set the position, velocity and acceleration of the ball, if they have changed.
if (acceleration != this->getAcceleration())
this->setAcceleration(acceleration);
if (velocity != this->getVelocity())
@@ -156,22 +200,33 @@
this->setPosition(position);
}
+ /**
+ @brief
+ Set the speed of the ball (in x-direction).
+ @param speed
+ The speed to be set.
+ */
void PongBall::setSpeed(float speed)
{
- if (speed != this->speed_)
+ if (speed != this->speed_) // If the speed changes
{
this->speed_ = speed;
+ // Set the speed in the direction of the balls current velocity.
Vector3 velocity = this->getVelocity();
if (velocity.x != 0)
velocity.x = sgn(velocity.x) * this->speed_;
- else
+ else // If the balls current velocity is zero, the speed is set in a random direction.
velocity.x = this->speed_ * sgn(rnd(-1,1));
this->setVelocity(velocity);
}
}
+ /**
+ @brief
+ Set the
+ */
void PongBall::setBats(WeakPtr<PongBat>* bats)
{
if (this->bDeleteBats_)
Modified: code/branches/tetris/src/modules/pong/PongBall.h
===================================================================
--- code/branches/tetris/src/modules/pong/PongBall.h 2011-03-22 14:22:54 UTC (rev 8103)
+++ code/branches/tetris/src/modules/pong/PongBall.h 2011-03-23 06:40:36 UTC (rev 8104)
@@ -26,16 +26,36 @@
*
*/
+/**
+ @file PongBall.h
+ @brief Declaration of the PongBall class.
+ @ingroup Pong
+*/
+
#ifndef _PongBall_H__
#define _PongBall_H__
#include "pong/PongPrereqs.h"
#include "util/Math.h"
+
#include "worldentities/MovableEntity.h"
namespace orxonox
{
+
+ /**
+ @brief
+ This class manages the ball for Pong.
+
+ //TODO: Describe what it's responnsibilities are.
+ Only moves in x-z area.
+
+ @author
+ Fabian 'x3n' Landau
+
+ @ingroup Pong
+ */
class _PongExport PongBall : public MovableEntity
{
public:
More information about the Orxonox-commit
mailing list