DSPlatformMaker/source/Enemy.cpp
2020-12-19 09:39:41 +02:00

232 lines
7.1 KiB
C++

#include "Enemy.hpp"
#include "zombie.h"
glImage* mushroomImage;
glImage zombieImage[8];
short zombieBmp[128*16];
int zombSpriteID;
Enemy::Enemy() {
}
Enemy::~Enemy() {
}
void Enemy::Update (float fElapsedTime) {
if (this->posY > nLevelHeight) return;
if (this->posX > nLevelWidth) return;
if (this->posX < 0) return;
if (this->markForRemoval) return;
switch (type) {
case Enemy_Mushroom:
case Enemy_LifeUp: {
if (mushroom.risingTimer > 0.0f) {
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
mushroom.risingTimer -= fElapsedTime;
posY -= fElapsedTime;
if (mushroom.risingTimer <= 0.0f) {
mushroom.risingTimer = 0.0f;
}
}
velX = 5;
} else {
// gravity
velY += 20.0f * fElapsedTime;
isOnGround = false;
for (int i = 0; i < 5; i++) {
float newX = posX + fElapsedTime * velX * .2f;
float newY = posY + fElapsedTime * velY * .2f;
if (velX < 0) {
if (IsSolid(GetTile(newX + 0.0f, posY + 0.0f), DIR_LEFT) ||
IsSolid(GetTile(newX + 0.0f, posY + 0.9f), DIR_LEFT)) {
velX = -velX;
newX = (int)newX + 1;
}
} else if (velX > 0) {
if (IsSolid(GetTile(newX + 1.0f, posY + 0.0f), DIR_RIGHT) ||
IsSolid(GetTile(newX + 1.0f, posY + 0.9f), DIR_RIGHT)) {
velX = -velX;
newX = (int)newX;
}
}
if (velY < 0) {
// no triggering blocks
if (IsSolid(GetTile(newX + 0.0f, newY), DIR_UP) ||
IsSolid(GetTile(newX + 0.9f, newY), DIR_UP)) {
velY = 0;
newY = (int)newY + 1;
}
}
if (velY > 0) {
if (IsSolid(GetTile(newX + 0.0f, newY + 1.0f), DIR_DOWN) ||
IsSolid(GetTile(newX + 0.9f, newY + 1.0f), DIR_DOWN)) {
velY = 0;
newY = (int)newY;
}
}
posX = newX; posY = newY;
}
if (isOnGround) {
if (velX == 0) velX = 5;
}
Rectangle ri = { (int)(posX * 100), (int)(posY * 100), 100, 100};
Rectangle rp = { (int)(fPlayerPosX * 100 + 20), (int)(fPlayerPosY * 100), 100, 80 };
if (RectangleIntersect(ri, rp)) {
if (type == Enemy_LifeUp)
IncreaseMaxHP();
else
HealPlayer();
// have to be overlapping with the mushroom quite a bit
this->markForRemoval = true;
score += 1000; // todo: increase lives
}
}
break;
}
case Enemy_Flower:
case Enemy_Time: {
if (mushroom.risingTimer > 0.0f) {
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
mushroom.risingTimer -= fElapsedTime;
posY -= fElapsedTime;
if (mushroom.risingTimer <= 0.0f) {
mushroom.risingTimer = 0.0f;
}
}
} else {
// gravity
velY += 20.0f * fElapsedTime;
isOnGround = false;
for (int i = 0; i < 5; i++) {
float newX = posX + fElapsedTime * velX * .2f;
float newY = posY + fElapsedTime * velY * .2f;
if (velX < 0) {
if (IsSolid(GetTile(newX + 0.0f, posY + 0.0f), DIR_LEFT) ||
IsSolid(GetTile(newX + 0.0f, posY + 0.9f), DIR_LEFT)) {
velX = -velX;
newX = (int)newX + 1;
}
} else if (velX > 0) {
if (IsSolid(GetTile(newX + 1.0f, posY + 0.0f), DIR_RIGHT) ||
IsSolid(GetTile(newX + 1.0f, posY + 0.9f), DIR_RIGHT)) {
velX = -velX;
newX = (int)newX;
}
}
if (velY < 0) {
// no triggering blocks
if (IsSolid(GetTile(newX + 0.0f, newY), DIR_UP) ||
IsSolid(GetTile(newX + 0.9f, newY), DIR_UP)) {
velY = 0;
newY = (int)newY + 1;
}
}
if (velY > 0) {
if (IsSolid(GetTile(newX + 0.0f, newY + 1.0f), DIR_DOWN) ||
IsSolid(GetTile(newX + 0.9f, newY + 1.0f), DIR_DOWN)) {
velY = 0;
newY = (int)newY;
}
}
posX = newX; posY = newY;
}
Rectangle ri = { (int)(posX * 100), (int)(posY * 100), 100, 100};
// offset the player rectangle a bit to avoid collecting while inside the box
Rectangle rp = { (int)(fPlayerPosX * 100 + 20), (int)(fPlayerPosY * 100), 100, 80 };
if (RectangleIntersect(ri, rp)) {
// have to be overlapping with the mushroom quite a bit
this->markForRemoval = true;
score += 1000;
if (type == Enemy_Time) {
inGameTime += 10.f;
} else {
DamagePlayer();
}
}
}
break;
}
}
}
void Enemy::CommonDrawAtOffset(glImage* img, float pX, float pY, float oX, float oY, int flipMode) {
int sx = (posX - oX) * 16;
int sy = (posY - oY) * 16 + 1;
//glSprite(sx, sy, flipMode, img);
DrawImage(img, img->width, img->height, sx, sy);
}
void Enemy::Draw (float fOffsetX, float fOffsetY) {
glImage* toDraw = nullptr;
int flipMode = 0;
switch (type) {
case Enemy_Mushroom: {
flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0;
// This should move the mushroom to behind the blocks during its rise anim
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
CommonDrawAtOffset(&tilesImage[33], posX, posY, fOffsetX, fOffsetY, flipMode);
if (homeX != 0 || homeY != 0) {
int mx = (homeX - fOffsetX) * 16;
int my = (homeY - fOffsetY) * 16;
DrawTile('U',mx,my,'.');
}
}
break;
}
case Enemy_Flower: {
flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0;
// This should move the mushroom to behind the blocks during its rise anim
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
CommonDrawAtOffset(&tilesImage[36], posX, posY, fOffsetX, fOffsetY, flipMode);
if (homeX != 0 || homeY != 0) {
int mx = (homeX - fOffsetX) * 16;
int my = (homeY - fOffsetY) * 16;
DrawTile('U',mx,my,'.');
}
}
break;
}
case Enemy_Time: {
flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0;
// This should move the mushroom to behind the blocks during its rise anim
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
CommonDrawAtOffset(&tilesImage[37], posX, posY, fOffsetX, fOffsetY, flipMode);
if (homeX != 0 || homeY != 0) {
int mx = (homeX - fOffsetX) * 16;
int my = (homeY - fOffsetY) * 16;
DrawTile('U',mx,my,'.');
}
}
break;
}
case Enemy_LifeUp: {
flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0;
// This should move the mushroom to behind the blocks during its rise anim
if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) {
CommonDrawAtOffset(&tilesImage[38], posX, posY, fOffsetX, fOffsetY, flipMode);
if (homeX != 0 || homeY != 0) {
int mx = (homeX - fOffsetX) * 16;
int my = (homeY - fOffsetY) * 16;
DrawTile('U',mx,my,'.');
}
}
break;
}
case Enemy_Zombie:
flipMode = this->zombie.movingLeft ? GL_FLIP_H : 0;
toDraw = &zombieImage[1];
CommonDrawAtOffset(toDraw, posX, posY, fOffsetX, fOffsetY, flipMode);
break;
}
}
void Enemy::CommonLoad() {
mushroomImage = &tilesImage[33];
decompress(zombieBitmap, zombieBmp, LZ77);
zombSpriteID = glLoadTileSet(zombieImage,16,16,128,16, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_16, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)zombieBmp);
}