Code:
#ifndef BUG_H
#define BUG_H
#include "bitmap.h"
#include "randint.h"
// Miscellaneous prototypes
bool operator<(const BitMap &p, const BitMap &q);
bool operator==(const BitMap &p, const BitMap &q);
//
// class for a simple bug
//
enum Direction {Up, Down, Left, Right };
const int BugBitMaps = 4; // One bitmap for each direction
class Bug {
public:
Bug(SimpleWindow &w, int HitsNeeded = 3,
int DirectionChangeProbability = 0);
bool I****(const Position &MousePosition);
bool IsDying();
void Create();
void Kill();
virtual void Move() = 0;
protected:
// Bug inspectors
SimpleWindow& GetWindow() const;
Position GetPosition() const;
Direction GetDirection() const;
float GetHorizMovement() const;
float GetVertMovement() const;
// float GetPosSlopeMovement() const;
// float GetNegSlopeMovement() const;
int GetDirectionChangeProbability() const;
BitMap& GetBmp(const Direction &d);
const BitMap& GetBmp(const Direction &d) const;
// Bug mutators
void SetWindow(SimpleWindow &w);
void SetDirection(const Direction &d);
void SetHorizMovement(float h);
void SetVertMovement(float v);
// void SetPosSlopeMovement(float h);
// void SetNegSlopeMovement(float v);
void Draw();
void Erase();
void SetPosition(const Position &p);
void ChangeDirection();
Position NewPosition() const;
bool AtRightEdge() const;
bool AtLeftEdge() const;
bool AtBottomEdge() const;
bool AtTopEdge() const;
RandomInt GeneratePercentage;
RandomInt GenerateAngle;
RandomInt GenerateDestinationNumber;
private:
// Data members
SimpleWindow &Window;
vector<BitMap> Bmp;
float GetHorizMovement() const;
float GetVertMovement() const;
// float GetPosSlopeMovement() const;
// float GetNegSlopeMovement() const;
int HitsRequired;
int HitsTaken;
int DirectionChangeProbability;
Direction CurrentDirection;
Position CurrentPosition;
};
class SlowBug : public Bug {
public:
SlowBug(SimpleWindow &w, int HitsNeeded = 4,
int DirectionChange = 10);
void Move();
};
class FastBug : public Bug {
public:
FastBug(SimpleWindow &w, int HitsNeeded = 3,
int DirectionChangeProbability = 20);
void Move();
};
#endif
///////////////////////////////////////////////////////////////////////////
.cpp
#include <iostream>
#include <string>
#include <assert.h>
#include "bug.h"
#include <math.h>
using namespace std;
// Bug(): constructor for a bug
Bug::Bug(SimpleWindow &w, int h, int P) :
Window(w), HitsRequired(h), HitsTaken(0),
GeneratePercentage(1, 100),
DirectionChangeProbability(P), Bmp(BugBitMaps) {
// No body needed
}
void Bug::Create() {
HitsTaken = 0;
Draw();
return;
}
void Bug::Kill() {
Erase();
return;
}
// Hit(): return true if mouse is inside bug
// and Update hit taken count
bool Bug::I****(const Position &MousePosition) {
if (GetBmp(GetDirection()).IsInside(MousePosition)) {
++HitsTaken;
return true;
}
else
return false;
}
// IsDying: is the bug dying
bool Bug::IsDying() {
return HitsTaken >= HitsRequired;
}
// inspectors
SimpleWindow& Bug::GetWindow() const {
return Window;
};
Position Bug::GetPosition() const {
return CurrentPosition;
};
Direction Bug::GetDirection() const {
return CurrentDirection;
};
//*
float Bug::GetPosSlopeMovement() const {
return PosSlopeMovement;
};
float Bug::GetNegSlopeMovement() const {
return NegSlopeMovement;
};
//*
float Bug::GetHorizMovement() const {
return HorizMovement;
};
float Bug::GetVertMovement() const {
return VertMovement;
};
int Bug::GetDirectionChangeProbability() const {
return DirectionChangeProbability;
}
BitMap& Bug::GetBmp(const Direction &d) {
return Bmp[d];
};
const BitMap& Bug::GetBmp(const Direction &d) const {
return Bmp[d];
};
// mutators
void Bug::SetWindow(SimpleWindow &w) {
Window = w;
return;
};
void Bug::SetDirection(const Direction &d) {
CurrentDirection = d;
return;
};
//*
/*
void Bug::SetPosSlopeMovement(float h) {
float n, a, theta;
a = GenerateDestinationNumber(1.0,5.0);
n = GenerateAngle(10,170);
theta = (n - 90)/(.0439);
PosSlopeMovement = cos(theta
return;
};
void Bug::SetNegSlopeMovement(float v) {
return;
};
//*
*/
void Bug::SetHorizMovement(float h) {
HorizMovement = h;
return;
};
void Bug::SetVertMovement(float v) {
VertMovement = v;
return;
};
void Bug::Draw() {
GetBmp(GetDirection()).Draw();
return;
};
void Bug::Erase() {
GetBmp(GetDirection()).Erase();
return;
};
void Bug::ChangeDirection() {
RandomInt R(Up, Right);
SetDirection((Direction ) R.Draw());
return;
};
// AtRightEdge(): determine if bug is at right edge of
// window
bool Bug::AtRightEdge() const {
return (GetPosition().GetXDistance()
+ GetBmp(GetDirection()).GetWidth()
+ GetHorizMovement() >= GetWindow().GetWidth());
}
// AtLeftEdge(): determine if bug is at left edge of
// window
bool Bug::AtLeftEdge() const {
return (GetPosition().GetXDistance()
- GetHorizMovement() <= 0.0);
}
// AtBottomEdge(): determine if bug is at bottom edge
// of window
bool Bug::AtBottomEdge() const {
return (GetPosition().GetYDistance()
+ GetBmp(GetDirection()).GetHeight()
+ GetVertMovement() >= GetWindow().GetHeight());
}
// AtTopEdge(): determine if bug is at top edge
// of window
bool Bug::AtTopEdge() const {
return (GetPosition().GetYDistance() -
GetVertMovement() <= 0.0);
}
// SetPosition(): set position for all bug bitmaps
void Bug::SetPosition(const Position &p) {
for (Direction d = Up; d <= Right;
d = (Direction) (d + 1))
Bmp[d].SetPosition(p);
CurrentPosition = p;
return;
}
// NewPosition(): compute a new position for a bug
Position Bug::NewPosition() const {
const Position OldPosition = GetPosition();
if (GetDirection() == NegSlope)
return OldPosition
+ Position(-GetPosSlopeMovement(),GetNegSlopeMovement());
else if (GetDirection() == PosSlope)
return OldPosition
+ Position(GetPosSlopeMovement(),GetNegSlopeMovement());
if (GetDirection() == Left)
return OldPosition
+ Position(-GetHorizMovement(), 0);
else if (GetDirection() == Right)
return OldPosition
+ Position(GetHorizMovement(), 0);
else if (GetDirection() == Up)
return OldPosition
+ Position(0, -GetVertMovement());
else
return OldPosition
+ Position(0, GetVertMovement());
}
// SlowBug(): construct a slow bug from a bug
SlowBug::SlowBug(SimpleWindow &w, int h, int p) : Bug(w, h, p) {
// Load the bit maps for the bug going in the
// four directions
vector<string> BitMapFiles(BugBitMaps);
BitMapFiles[0] = "sbug-u.bmp";
BitMapFiles[1] = "sbug-d.bmp";
BitMapFiles[2] = "sbug-l.bmp";
BitMapFiles[3] = "sbug-r.bmp";
for (Direction d = Up; d <= Right;
d = (Direction) (d+1)) {
GetBmp(d).SetWindow(GetWindow());
GetBmp(d).Load(BitMapFiles[d]);
assert(GetBmp(d).GetStatus() == BitMapOkay);
}
// Set the distance to move the bug in the
// horizontal and vertical direction
// The distance is based on the size of the bitmap.
SetHorizMovement(GetBmp(Right).GetWidth() / 5.0);
SetVertMovement(GetBmp(Up).GetHeight() / 5.0);
/* SetPosSlopeMovement(GetBmp(Up).GetWidth() / 10.0);
SetNegSlopeMovement(GetBmp(Down).GetHeight() / 10.0);
*/
// Initially make it go up
SetDirection(Up);
SetPosition(Position(3.0, 3.0));
return;
}
// Move(): move a slow bug. When the bug hits a wall it
// turns and goes the opposite direction. It randomly
// changes direction about ChangePercent percent of
// the time
void SlowBug::Move() {
// Erase current image, compute new direction if any and
// draw the image at its new position
Erase();
// Randomly change directions
if (GeneratePercentage.Draw()
< GetDirectionChangeProbability())
ChangeDirection();
SetPosition(NewPosition());
Draw();
// See if this bug is going to hit the edge of the
// window. If so, then turn the bug around
// Get bug position and its size
Direction BugDirection = GetDirection();
// Decide if it needs to turn around
if (BugDirection == Right && AtRightEdge())
SetDirection(Left);
else if (BugDirection == Left && AtLeftEdge())
SetDirection(Right);
else if (BugDirection == Down && AtBottomEdge())
SetDirection(Up);
else if (BugDirection == Up && AtTopEdge())
SetDirection(Down);
}
// FastBug(): constructor for a fast bug
FastBug::FastBug(SimpleWindow &w, int h, int p) : Bug(w, h, p) {
// Load the four bit maps for the bug going in
// the four directions
vector<string> BitMapFiles(BugBitMaps);
BitMapFiles[0] = "fbug-u.bmp";
BitMapFiles[1] = "fbug-d.bmp";
BitMapFiles[2] = "fbug-l.bmp";
BitMapFiles[3] = "fbug-r.bmp";
for (Direction d = Up; d <= Right;
d = (Direction) (d + 1)) {
GetBmp(d).SetWindow(GetWindow());
GetBmp(d).Load(BitMapFiles[d]);
assert(GetBmp(d).GetStatus() == BitMapOkay);
}
// Set the distance to move the bug in the horizontal
// and vertical directions. The distance is based
// on the size of the bitmap. This should be a larger
// distance than a slow bug, so it moves faster
SetHorizMovement(GetBmp(Right).GetWidth() / 5.0);
SetVertMovement(GetBmp(Up).GetHeight() / 5.0);
// Initially make it go down
SetDirection(Down);
SetPosition(Position(6.0, 2.0));
}
// Move(): move a fast bug.
void FastBug::Move() {
// Erase current image, compute new direction if any
// and draw the image at its new position
Erase();
// Change directions randomly
if (GeneratePercentage.Draw()
< GetDirectionChangeProbability())
ChangeDirection();
SetPosition(NewPosition());
Draw();
//See if the bug is going to hit an edge of the
// window. If so, the bug pops out on the other
// side.
// Get bug position and its size
Direction BugDirection = GetDirection();
float BugXSize = GetBmp(GetDirection()).GetWidth();
float BugYSize = GetBmp(GetDirection()).GetHeight();
// Decide if bug pops through at the opposite side
if (BugDirection == Right && AtRightEdge()) {
Erase();
SetPosition(Position(0.0,
GetPosition().GetYDistance()));
Draw();
}
else if (BugDirection == Left && AtLeftEdge()) {
Erase();
SetPosition(
Position(GetWindow().GetWidth() - BugXSize,
GetPosition().GetYDistance()));
Draw();
}
else if (BugDirection == Down && AtBottomEdge()) {
Erase();
SetPosition(
Position(GetPosition().GetXDistance(), 0.0));
Draw();
}
else if (BugDirection == Up && AtTopEdge()) {
Erase();
SetPosition(Position(GetPosition().GetXDistance(),
GetWindow().GetHeight() - BugYSize));
Draw();
}
}