Skip to content

Commit

Permalink
refactor: named animal data
Browse files Browse the repository at this point in the history
  • Loading branch information
Cadecraft committed Apr 7, 2024
1 parent bff60a5 commit 94a3316
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ add_executable(PlatScifi
src/worldobjects/staticdeadly.h
src/worldobjects/leveltp.h
src/worldobjects/spike.h
src/worldobjects/animal.cpp
)
target_link_libraries(PlatScifi PRIVATE sfml-graphics)
target_compile_features(PlatScifi PRIVATE cxx_std_17)
Expand Down Expand Up @@ -67,6 +68,7 @@ set(ASSETS
LiberationSans-Regular.ttf
enemy_bird_0.png
enemy_bird_1.png
enemy_fipa_0.png
)

foreach(ASSET ${ASSETS})
Expand Down
Binary file added src/assets/enemy_fipa_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/assets/level_1.csv
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ LevelTp, 55, 28
// Moving Platform
MovingCollider, 8, 32, 5, 2, 300, 20, 32
// Animal
Animal, 50, 15
Animal, bird, 50, 15
Animal, fipa, 55, 15
2 changes: 1 addition & 1 deletion src/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void Renderer::renderWorld(GameState& gameState) {
for (std::vector<WorldObject*>::iterator it = gameState.objectsBegin(); it != gameState.objectsEnd(); it++) {
renderFromData((*it)->getRenderData());
}
// TODO: Render UI
// TODO: render on-screen debug messages (ex. "enemy_fipa spawned")
// TODO: refactor/abstract this
sf::Text levelName;
levelName.setFont(assetHandler.getMainFont());
Expand Down
33 changes: 33 additions & 0 deletions src/worldobjects/animal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "animal.h"

// Define the default data for all named animals (<name, data>)
const std::map<std::string, AnimalData> Animal::animalDefaults = {
{
"bird", // Name
{
"Bird", // Display name
"enemy_bird", // Texture prefix
1, // Animation frame max
2.0, // Width
2.0, // Height
{
// Object attributes
ObjectAttribute::Collision
}
}
},
{
"fipa",
{
"Fipa",
"enemy_fipa",
0,
3.0,
3.0,
{
ObjectAttribute::Collision,
ObjectAttribute::Deadly
}
}
}
};
44 changes: 40 additions & 4 deletions src/worldobjects/animal.h
Original file line number Diff line number Diff line change
@@ -1,28 +1,62 @@
#pragma once

#include <map>
#include <vector>
#include "../worldobject.h"
#include "../constants.h"

// The default data for a specific animal type
struct AnimalData {
std::string displayName;
std::string texturePrefix;
int animFrameMax;
double width;
double height;
std::set<ObjectAttribute> objectAttributes;
};

// The data for an animal in the world
class Animal : public WorldObject {
private:
double velx = 0;
double vely = 0;
bool onGround = false;
long frameCount = 0;
std::string texturePrefix;
int animFrameNum = 0;
int animFrameMax = 1;
bool moveRight = false;

public:
// Constructor
Animal(double spawnx, double spawny) : WorldObject() {
// Define the default data for all named animals (<name, data>)
static const std::map<std::string, AnimalData> animalDefaults;

// Constructor (define everything specifically)
Animal(std::string texturePrefix, int animFrameMax, double spawnx, double spawny) : WorldObject() {
locx = spawnx;
locy = spawny;
width = 2.0;
height = 2.0;
this->texturePrefix = texturePrefix;
this->animFrameMax = animFrameMax;
objectAttributes.insert(ObjectAttribute::Collision);
}

// Constructor for named animals
Animal(std::string name, double spawnx, double spawny) : WorldObject() {
locx = spawnx;
locy = spawny;
if (animalDefaults.find(name) == animalDefaults.end()) {
// Could not find the animal
name = "bird";
}
width = (*animalDefaults.find(name)).second.width;
height = (*animalDefaults.find(name)).second.height;
this->texturePrefix = (*animalDefaults.find(name)).second.texturePrefix;
this->animFrameMax = (*animalDefaults.find(name)).second.animFrameMax;
objectAttributes = (*animalDefaults.find(name)).second.objectAttributes;
}

// TODO: different AI based on animal type (enum? stringly typed?)

// Input: acceleration
Expand Down Expand Up @@ -54,7 +88,7 @@ class Animal : public WorldObject {
// Override update: gravity and acceleration, and AI logic
UpdateResult update(WorldState& worldState, std::vector<WorldObject*>& objects) {
// AI Logic
accelerate(-0.01, 0);
accelerate(moveRight ? 0.01 : -0.01, 0);
jump();
// Physics
if (!LEVEL_DESIGN_MODE) {
Expand Down Expand Up @@ -83,6 +117,8 @@ class Animal : public WorldObject {
velx = 0;
collided = true;
overlapped = true;
// For AI
moveRight = !moveRight;
}
}
if (locx + width >= object->getLocx() && locx < object->getLocx() + object->getWidth()) {
Expand Down Expand Up @@ -140,7 +176,7 @@ class Animal : public WorldObject {
width,
height,
{ 255, 0, 0 },
"assets/enemy_bird_" + std::to_string(animFrameNum) + ".png"
"assets/" + texturePrefix + "_" + std::to_string(animFrameNum) + ".png"
};
}
};
18 changes: 14 additions & 4 deletions src/worldspawner.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <iostream>
#include "worldspawner.h"

void WorldSpawner::spawnWorld(GameState& gameState, std::string levelName) {
Expand Down Expand Up @@ -64,14 +65,23 @@ void WorldSpawner::spawnWorld(GameState& gameState, std::string levelName) {
std::stoi(parsed[7])
));
} else if (parsed[0] == "Animal") {
if (parsed.size() < 3) throw;
gameState.spawnObject(new Animal(
std::stoi(parsed[1]), std::stoi(parsed[2])
));
if (parsed.size() < 4) throw;
if (parsed.size() < 5) {
// Size of 4: spawn a named animal
gameState.spawnObject(new Animal(
parsed[1], std::stoi(parsed[2]), std::stoi(parsed[3])
));
} else {
// Size of 5 or more: spawn a specific animal
gameState.spawnObject(new Animal(
parsed[1], std::stoi(parsed[2]), std::stoi(parsed[3]), std::stoi(parsed[4])
));
}
}
}
} catch (std::exception& e) {
// Failed: re-clear the world
std::cout << "ERR: Failed to re-clear the world (level: " << levelName << ")" << std::endl;
gameState.clear();
return;
}
Expand Down

0 comments on commit 94a3316

Please sign in to comment.