Initial
This commit is contained in:
commit
62d2de747e
1 changed files with 130940 additions and 0 deletions
281
Code blocks projekt/modules/floaters.c.save
Normal file
281
Code blocks projekt/modules/floaters.c.save
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
#include "floaters.h"
|
||||
|
||||
#define enemyMinSize 0.75 /**< Ellenségek oldalhosszának kezdeti értéke [m].*/
|
||||
#define enemyMaxSize 4 /**< Az ellenségek, ha összeérnek, összetapadnak, de ennél ne lehetnek nagyobbak [m]. */
|
||||
#define enemyVelocity 0.006 /**< [m/ms] */
|
||||
#define enemySlowing 0.15 /**< Ha az ellenség nekiütközik valaminek, akkor a sebessége ennyiszeresére csökken. */
|
||||
#define slownessDebuffDuration 2000 /**< Ha az ellenség nekiütközik valaminek, akkor a sebessége ennyi ideig lesz alacsnyabb. [ms] */
|
||||
#define projectileSize 0.2 /**< A játékos által lőtt lövedék oldalhossza [m]. */
|
||||
#define projectileVelocity 0.03 /**< A játékos által lőtt lövedék kezdő sebessége [m/ms] */
|
||||
#define projectileVelocityYMax 0.03 /**< A lövedék sebességét befolyásolja a játékos sebessége (a kiulövés pillanatában), illetve a gravitációs gyorsulás, viszont sosem lehet gyorsabb. */
|
||||
#define floaterColor (colors) { (color) {229, 22, 22, 255}, (color) {200, 20, 20, 255}, (color) {168, 16, 16, 255} } /**< A lövedék és az ellenség ugyanolyan színű */
|
||||
|
||||
floater* floaterList = NULL; /**< Láncolt lista, ami az ellenségeket és lövedékeket is tartalmazza. Nagyon hasonló a kettő, ezért célszerű közösen kezelni őket.*/
|
||||
|
||||
///Lista elejére beszúr.
|
||||
floater* addToFloaterList() {
|
||||
floater* newfloater = (floater*) malloc(sizeof(floater));
|
||||
newfloater -> next = floaterList;
|
||||
floaterList = newfloater;
|
||||
return newfloater;
|
||||
}
|
||||
|
||||
///Felszabadítja az ellenségek és lövedékek listáját.
|
||||
void freeFloaterList() {
|
||||
if(floaterList == NULL) return;
|
||||
|
||||
floater* moving = floaterList;
|
||||
|
||||
floater* tmp;
|
||||
while(moving != NULL) {
|
||||
tmp = moving;
|
||||
moving = moving -> next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
floaterList = NULL;
|
||||
}
|
||||
|
||||
///A játékos közelében elhelyez egy új ellenséget.
|
||||
void createEnemy() {
|
||||
|
||||
floater* newEnemy = addToFloaterList();
|
||||
newEnemy -> type = enemy;
|
||||
newEnemy -> velocity = (vector2D) {0, 0};
|
||||
newEnemy -> slownessDebuffLeft = 0;
|
||||
newEnemy -> size = enemyMinSize;
|
||||
|
||||
vector3D playerPosition = getPlayerRenderObject().position;
|
||||
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
newEnemy -> position.x = playerPosition.x + (float) (randomPlusOrMinus() * randomIntWithinBorders(50 - i, 20));
|
||||
newEnemy -> position.y = playerPosition.y + (float) (randomIntWithinBorders(40 - i, 15));
|
||||
i++;
|
||||
}
|
||||
while(!isWithinTheMap(newEnemy -> position, (vector2D) {newEnemy -> size, newEnemy -> size}));
|
||||
|
||||
}
|
||||
|
||||
/** \brief Lövedék létrehozása.
|
||||
* A megadott paraméterek függvényében a létrehozott lövedék az egér irányafele indul el.
|
||||
* \param helyvektor a játékoshoz
|
||||
* \param térvektor a játékos méretéhez
|
||||
* \param síkvektor* játékos sebesség (ezt Newton III. értelmében megváltoztatja
|
||||
* \param koordinátája az egérnek
|
||||
* A játékost ellenkező irányba elmozdítja. A lövedék kezdősebbességéhez hozzáadódik a játékos sebessége.
|
||||
*/
|
||||
void createProjectile(vector3D playerPosition, vector3D playerSize, vector2D* playerVelocity, mousePos mouse) {
|
||||
floater* newProjectile = addToFloaterList();
|
||||
newProjectile -> type = projectile;
|
||||
newProjectile -> position.x = playerPosition.x + playerSize.x / 2;
|
||||
newProjectile -> position.y = playerPosition.y + playerSize.y / 2;
|
||||
newProjectile -> size = projectileSize;
|
||||
|
||||
intVector2D playerCoord = get2DPoint((vector3D) {newProjectile -> position.x, newProjectile -> position.y, 0});
|
||||
int deltaX = mouse.x - playerCoord.x;
|
||||
int deltaY = playerCoord.y - mouse.y;
|
||||
float distance = sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
float compensation = 0;
|
||||
if(distance > 0) compensation = projectileVelocity / distance;
|
||||
|
||||
newProjectile -> velocity = (vector2D) {
|
||||
deltaX * compensation + playerVelocity -> x,
|
||||
deltaY * compensation + playerVelocity -> y
|
||||
};
|
||||
|
||||
playerVelocity -> x -= newProjectile -> velocity.x * 0.25;
|
||||
playerVelocity -> y -= newProjectile -> velocity.y * 0.25;
|
||||
}
|
||||
|
||||
///Listából kiszed.
|
||||
void destroyFloater(floater* floaterToDestroy) {
|
||||
if(floaterList == floaterToDestroy) floaterList = floaterToDestroy -> next;
|
||||
else {
|
||||
floater* previous = floaterList;
|
||||
|
||||
while(previous != NULL && previous -> next != floaterToDestroy)
|
||||
previous = previous -> next;
|
||||
|
||||
previous -> next = floaterToDestroy -> next;
|
||||
}
|
||||
free(floaterToDestroy);
|
||||
}
|
||||
|
||||
/** \brief Megnézi összeér-e két ellenség, ha igen, összeolvasztja őket.
|
||||
* A kisebb ellenség eltűnik, a nagyobbnak a térfogata a kisebbéjével nő.
|
||||
* \param ellenség1
|
||||
* \param ellenség2
|
||||
* \return Összeértek-e?
|
||||
*/
|
||||
static bool mergeEnemies(floater* enemy1, floater* enemy2) {
|
||||
floater* enemyBigger = enemy1 -> size > enemy2 -> size ? enemy1 : enemy2;
|
||||
floater* enemySmaller = enemy1 -> size > enemy2 -> size ? enemy2 : enemy1;
|
||||
|
||||
if(isBoxOverlappingBox(
|
||||
enemy1 -> position, (vector2D) {enemy1 -> size, enemy1 -> size},
|
||||
enemy2 -> position, (vector2D) {enemy2 -> size, enemy2 -> size}
|
||||
)) {
|
||||
enemyBigger -> size = smallerF(fDist(enemyBigger -> size, enemySmaller -> size), enemyMaxSize);
|
||||
|
||||
destroyFloater(enemySmaller);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///Kezeli ha egy ellenség le lett lőve, a lövedék eltűnik, az ellenség mérete pedig csökken, vagy ha túl kicsi, az ellenség eltűnik.
|
||||
static void projectileEnemyCollision(floater* projectile) {
|
||||
floater* currentFloater = floaterList;
|
||||
while(currentFloater != NULL) {
|
||||
|
||||
if(currentFloater -> type == enemy &&
|
||||
isBoxOverlappingBox(
|
||||
projectile -> position, (vector2D) {projectile -> size, projectile -> size},
|
||||
currentFloater -> position, (vector2D) {currentFloater -> size, currentFloater -> size}
|
||||
)
|
||||
) {
|
||||
destroyFloater(projectile);
|
||||
|
||||
currentFloater -> size = sqrt(square(currentFloater -> size) - 0.95 * square(enemyMinSize * enemyMinSize));
|
||||
if(currentFloater -> size < enemyMinSize * 1.05)
|
||||
destroyFloater(currentFloater);
|
||||
}
|
||||
|
||||
currentFloater = currentFloater -> next;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Megnézi, hogy ütközött-e valami egy kockával, ha igen, kezeli.
|
||||
* A kocka mindenképpen megsemmisül.
|
||||
* \param helyvektor a floaterhez
|
||||
* \param mérete a flaoternek
|
||||
* \return Ütköztek-e?
|
||||
* A visszatérési érték alapján megfelelően lehet kezelni az esetet.
|
||||
*/
|
||||
static bool floaterSolidCollision(vector2D position, float size) {
|
||||
block* blockToDestroy;
|
||||
if(
|
||||
isWithinTheMap(position, (vector2D) {size, size}) &&
|
||||
(detectCollision(position, (vector2D) {size, size}, solid, &blockToDestroy) ||
|
||||
detectCollision(position, (vector2D) {size, size}, treasure, &blockToDestroy)) &&
|
||||
blockToDestroy != NULL
|
||||
) {
|
||||
*blockToDestroy = air;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \brief Mozgatja az adott ellenséget.
|
||||
* Figyel minden lehetsége ütközésre.
|
||||
* \param ellenség
|
||||
* \param ms eltelt idő
|
||||
*/
|
||||
static void moveEnemy(floater* thisEnemy, int deltaTime) {
|
||||
float velocity = enemyVelocity;
|
||||
if(thisEnemy -> slownessDebuffLeft > 0) {
|
||||
thisEnemy -> slownessDebuffLeft -= deltaTime;
|
||||
velocity *= enemySlowing;
|
||||
}
|
||||
|
||||
renderObject player = getPlayerRenderObject();
|
||||
vector3D playerPosition = player.position;
|
||||
float deltaX = (playerPosition.x - thisEnemy -> position.x);
|
||||
float deltaY = (playerPosition.y - thisEnemy -> position.y);
|
||||
|
||||
float compensation = 0;
|
||||
float distance = fDist(deltaX, deltaY);
|
||||
if(distance > 0)
|
||||
compensation = velocity / distance;
|
||||
|
||||
thisEnemy -> position.x += deltaX * compensation * deltaTime;
|
||||
thisEnemy -> position.y += deltaY * compensation * deltaTime;
|
||||
|
||||
|
||||
if(floaterSolidCollision(thisEnemy -> position, thisEnemy -> size))
|
||||
thisEnemy -> slownessDebuffLeft = slownessDebuffDuration;
|
||||
|
||||
|
||||
if(isBoxOverlappingBox((vector2D) {player.position.x, player.position.y}, (vector2D){player.size.x, player.size.y},
|
||||
thisEnemy -> position, (vector2D) {thisEnemy -> size, thisEnemy -> size})) setDie(true);
|
||||
|
||||
floater* currentEnemy = floaterList;
|
||||
while(currentEnemy != NULL && (thisEnemy == currentEnemy || !mergeEnemies(thisEnemy, currentEnemy)))
|
||||
currentEnemy = currentEnemy -> next;
|
||||
}
|
||||
|
||||
/** \brief Mozgatja az adott lövedéket.
|
||||
* Figyel minden lehetsége ütközésre.
|
||||
* \param lövedék
|
||||
* \param ms eltelt idő
|
||||
*/
|
||||
static void moveProjectile(floater* thisProjectile, int deltaTime) {
|
||||
thisProjectile -> velocity.y -= g * deltaTime;
|
||||
if(thisProjectile -> velocity.y < -projectileVelocityYMax) thisProjectile -> velocity.y = -projectileVelocityYMax;
|
||||
thisProjectile -> position.x += thisProjectile -> velocity.x * deltaTime;
|
||||
thisProjectile -> position.y += thisProjectile -> velocity.y * deltaTime;
|
||||
|
||||
if(
|
||||
!isWithinTheMap(thisProjectile -> position, (vector2D) {projectileSize, projectileSize}) ||
|
||||
floaterSolidCollision(thisProjectile -> position, thisProjectile -> size)
|
||||
)
|
||||
destroyFloater(thisProjectile);
|
||||
|
||||
projectileEnemyCollision(thisProjectile);
|
||||
}
|
||||
|
||||
///Minden floaterre meghívja a szükséges mozgatási műveletet.
|
||||
void moveFloaters(int deltaTime) {
|
||||
floater* currentFloater = floaterList;
|
||||
|
||||
while(currentFloater != NULL) {
|
||||
|
||||
if(currentFloater -> type == projectile) moveProjectile(currentFloater, deltaTime);
|
||||
else moveEnemy(currentFloater, deltaTime);
|
||||
|
||||
currentFloater = currentFloater -> next;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Visszaadja az adott térfogatban lévő floater testeket.
|
||||
* A sorrend nem elhanyagolható 3D-s testek rajzolásakor. Figyelni kell, melyik melyik másikat takarja el.
|
||||
* Ezért kell "feldarabolni" őket. Itt még csak az egy adott m^3-ben lévő testek adatait adja oda a rajzoló függvénynek.
|
||||
* Maga a feldarabolás már nem ennek a függvénynek a dolga.
|
||||
* \param koord x
|
||||
* \param koord y
|
||||
* \param Hova kell írnia a testeket
|
||||
* \param Max mennyit adhat vissza
|
||||
* A feldarabolásról részletesebben a camera.c modulban.
|
||||
*/
|
||||
void getFloatersRenderObject(int x, int y, renderObject* renderMap, int renderObjectsPerCube) {
|
||||
renderObject enemyRenderObject;
|
||||
enemyRenderObject.colors = floaterColor;
|
||||
|
||||
int floaterCounter = 0;
|
||||
|
||||
floater* currentFloater = floaterList;
|
||||
while(currentFloater != NULL) {
|
||||
|
||||
if(
|
||||
(int)currentFloater -> position.x <= x && x <= (int)(currentFloater -> position.x + currentFloater -> size) &&
|
||||
(int)currentFloater -> position.y <= y && y <= (int)(currentFloater -> position.y + currentFloater -> size)
|
||||
) {
|
||||
enemyRenderObject.position = (vector3D) {currentFloater -> position.x, currentFloater -> position.y, 0.5};
|
||||
enemyRenderObject.size = (vector3D) {currentFloater -> size, currentFloater -> size, currentFloater -> size/2};
|
||||
enemyRenderObject.doesExist = true;
|
||||
|
||||
if(floaterCounter < renderObjectsPerCube - 1) {
|
||||
renderMap[floaterCounter] = enemyRenderObject;
|
||||
floaterCounter++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
currentFloater = currentFloater -> next;
|
||||
}
|
||||
|
||||
enemyRenderObject.doesExist = false;
|
||||
renderMap[floaterCounter] = enemyRenderObject;
|
||||
}
|
||||
Loading…
Reference in a new issue