📄 enemy.cpp
字号:
#include <iostream>
#include <string>
#include <assert.h>
#include "enemy.h"
using namespace std;
// construct an Enemy
Enemy::Enemy(SimpleWindow &w, int P) :Window(w), GeneratePercentage(1, 100),
DirectionChangeProbability(P) , Bmp(EnemyBitMaps) {
// nobody needed
}
void Enemy::Create() {
Draw();
return;
}
void Enemy::Kill() {
Erase();
return;
}
// inspectors
SimpleWindow& Enemy::GetWindow() const {
return Window;
}
Position Enemy::GetPosition() const {
return CurrentPosition;
}
Direction Enemy::GetDirection() const {
return CurrentDirection;
}
float Enemy::GetHorizMovement() const {
return HorizMovement;
}
float Enemy::GetVertMovement() const {
return VertMovement;
}
int Enemy::GetDirectionChangeProbability() const {
return DirectionChangeProbability;
}
BitMap& Enemy::GetBmp(const Direction &d) {
return Bmp[d];
}
const BitMap& Enemy::GetBmp(const Direction &d) const {
return Bmp[d];
}
// mutators
void Enemy::SetWindow(SimpleWindow &w) {
Window = w;
return;
}
void Enemy::SetDirection(const Direction &d) {
CurrentDirection = d;
return;
}
void Enemy::SetHorizMovement(float h) {
HorizMovement = h;
return;
}
void Enemy::SetVertMovement(float v) {
VertMovement = v;
return;
}
void Enemy::Draw() {
GetBmp(GetDirection()).Draw();
return;
}
void Enemy::Erase() {
GetBmp(GetDirection()).Erase();
return;
}
void Enemy::ChangeDirection() {
RandomInt R(Up, Left);
SetDirection((Direction ) R.Draw());
return;
}
// determine if Enemy is at right edge of window
bool Enemy::AtRightEdge() const {
return (GetPosition().GetXDistance()
+ GetBmp(GetDirection()).GetWidth()
+ GetHorizMovement() >= 15.5);
}
// determine if Enemy is at left edge of window
bool Enemy::AtLeftEdge() const {
return (GetPosition().GetXDistance()
- GetHorizMovement() <= 0.6);
}
// determine if Enemy is at bottom edge of window
bool Enemy::AtBottomEdge() const {
return (GetPosition().GetYDistance()
+ GetBmp(GetDirection()).GetHeight()
+ GetVertMovement() >= 15.5);
}
// determine if Enemy is at top edge of window
bool Enemy::AtTopEdge() const {
return (GetPosition().GetYDistance() -
GetVertMovement() <= 0.6);
}
// set position for Enemy bitmaps
void Enemy::SetPosition(const Position &p) {
for (Direction d = Up; d <= Left;
d = (Direction) (d + 1))
Bmp[d].SetPosition(p);
CurrentPosition = p;
return;
}
// compute a new position for Enemy
Position Enemy::NewPosition() const {
const Position OldPosition = GetPosition();
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());
}
// construct slow Enemy from a Enemy
SlowEnemy::SlowEnemy(SimpleWindow &w, int p) : Enemy(w, p) {
// load the bit maps for Enemy going into the four directions
vector<string> BitMapFiles(EnemyBitMaps);
BitMapFiles[0] = "bmp\\sEnemy-u.bmp";
BitMapFiles[1] = "bmp\\sEnemy-r.bmp";
BitMapFiles[2] = "bmp\\sEnemy-d.bmp";
BitMapFiles[3] = "bmp\\sEnemy-l.bmp";
for (Direction d = Up; d <= Left;
d = (Direction) (d + 1)) {
GetBmp(d).SetWindow(GetWindow());
GetBmp(d).Load(BitMapFiles[d]);
assert(GetBmp(d).GetStatus() == BitMapOkay);
}
/* Set the distance of moving to the Enemy in the
* horizontal or vertical directions
* The distance is based on the size of the bitmap.
**************************************/
SetHorizMovement(GetBmp(Right).GetWidth() / 10.0);
SetVertMovement(GetBmp(Up).GetHeight() / 10.0);
// initially make it go right
SetDirection(Right);
SetPosition(Position(1.0, 1.0));
return;
}
/* move a slowEnemy. When the Enemy hits a wall it
* turns and goes the opposite direction. It randomly
* changes directions about ChangePercent of
* the time.
**************************/
void SlowEnemy::Move() {
// erase current image, compute new directions if any and
// draw the image at its new position
Erase();
// randomly change directions
if (GeneratePercentage.Draw()
< GetDirectionChangeProbability())
ChangeDirection();
SetPosition(NewPosition());
Draw();
// judge if the Enemy will hit the edge of the
// window. If so, turn it around
// get Enemy position and its size
Direction EnemyDirection = GetDirection();
// decide if it needs to turn around
if (EnemyDirection == Right && AtRightEdge())
SetDirection(Left);
else if (EnemyDirection == Left && AtLeftEdge())
SetDirection(Right);
else if (EnemyDirection == Down && AtBottomEdge())
SetDirection(Up);
else if (EnemyDirection == Up && AtTopEdge())
SetDirection(Down);
}
// construct a fastEnemy
FastEnemy::FastEnemy(SimpleWindow &w, int p) : Enemy(w, p) {
// load the four bit maps for the Enemy going into the four directions
vector<string> BitMapFiles(EnemyBitMaps);
BitMapFiles[0] = "bmp\\fEnemy-u.bmp";
BitMapFiles[1] = "bmp\\fEnemy-r.bmp";
BitMapFiles[2] = "bmp\\fEnemy-d.bmp";
BitMapFiles[3] = "bmp\\fEnemy-l.bmp";
for (Direction d = Up; d <= Left;
d = (Direction) (d + 1)) {
GetBmp(d).SetWindow(GetWindow());
GetBmp(d).Load(BitMapFiles[d]);
assert(GetBmp(d).GetStatus() == BitMapOkay);
}
/* Set the distance of moving to the Enemy in the horizontal
* or vertical directions. The distance is based
* on the size of the bitmap. This should be a larger
* distance than that of a slowEnemy, so it moves faster
*******************************/
SetHorizMovement(GetBmp(Right).GetWidth() / 5.0);
SetVertMovement(GetBmp(Up).GetHeight() / 5.0);
// initially make it run down
SetDirection(Down);
SetPosition(Position(6.0, 2.0));
}
/* move a fastEnemy. When the Enemy hits a wall it
* goes right through it to the other side. It randomly
* changes directions about ChangePercent of
* the time.
***************************/
void FastEnemy::Move() {
// erase current image, compute new direction if nessary
// and draw the image at its new position
Erase();
// change directions randomly
if (GeneratePercentage.Draw() < GetDirectionChangeProbability())
ChangeDirection();
SetPosition(NewPosition());
Draw();
// check if the Enemy will hit the edge of the
// window. If so, the Enemy pops out on the other
// side.
// get Enemy positions and its size
Direction EnemyDirection = GetDirection();
float EnemyXSize = GetBmp(GetDirection()).GetWidth();
float EnemyYSize = GetBmp(GetDirection()).GetHeight();
// judge if Enemy pops through at the opposite side
if (EnemyDirection == Right && AtRightEdge()) {
Erase();
SetPosition(Position(0.6,
GetPosition().GetYDistance()));
Draw();
}
else if (EnemyDirection == Left && AtLeftEdge()) {
Erase();
SetPosition(
Position(15 - EnemyXSize,
GetPosition().GetYDistance()));
Draw();
}
else if (EnemyDirection == Down && AtBottomEdge()) {
Erase();
SetPosition(
Position(GetPosition().GetXDistance(), 0.6));
Draw();
}
else if (EnemyDirection == Up && AtTopEdge()) {
Erase();
SetPosition(Position(GetPosition().GetXDistance(),
15 - EnemyYSize));
Draw();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -