Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Switchboy

Pages: 1 [2]
16
SFML projects / Re: Isometric RTS
« on: June 16, 2020, 10:30:46 pm »
I finally made some progress with drawing sprites, which is not my strongest point. So I could add more buildings to my game:
Mill
Receives food, will allow the construction of farms and food related research. For now I am goin to borrow the concept from age of Empires. But I will look into another way of implementing farms when the game is more mature
Lumber camp
Receives wood and allows research of wood gathering technology

Barracks
Will train melee soldiers and allows for melee related research

Both the mill and lumbercamp are animated sprites:



I am already regretting the way I wrote my buttons and buildings classes. It is really a lot of work to add new stuff this way. I have to edit five files to do so. But it is a good learning experience to bump your head a couple of times for future projects!


New playable release:
https://github.com/switchboy/IsoRTS/releases/tag/melee

17
SFML projects / Isometric RTS
« on: June 02, 2020, 04:29:30 pm »
About my project
For the last couple of months, I’ve been working in my spare time to create an isometrically projected RTS a la Age of Empires. Development has been on and off depending on how busy real life is. Bear is mind this is my second big project in C++. I've made an RPG roguelike before (which was quite far in development) but that codebase became such a mess that in the end I had to abandon it. So rather then start from scratch I decided to create another game in another (in my opinion underdeveloped by indie developers) genre.
 


The project goals that have been reached:
- Create a custom game engine based upon an isomorphic projection.
- Have actors move around in this world by issuing mouse commands.
- For pathfinding use A-star and or bidirectional A-star.
- Add collectable resources to the world
- Make villagers gather the different resources and bring them to a ‘town center’
- Use these resources to build different buildings
- Require specific buildings to house new population
- Make certain the buildings produce units
- Implement Fog of war
- Interact like an RTS game
- Robust villager AI for doing a task
- Show different animations for these resources
- Generate random map on game startup
- Make the units able fight each other using melee
- Make the actors fight each other using ranged attacks
- Make certain buildings able to perform a ranged attack
- Working minimap

Attainable project goals for the near future:
- Fighting animations
- Different units
- More buildings then houses and town centers
- Different colors on units and buildings for the eight teams
- Implant a basic Rock/Paper/Scissors for damage calculations during battle
- Researchable upgrades for units and buildings
- Flesh out the research with a tech tree
- Basic AI to play against
- Add sounds

Aim for the moon project goal:
- Working netcode to play against friends!

Cool! So where is the code?
https://github.com/switchboy/IsoRTS

Allright, I want to see it in action!
To show off some of the current gameplay I’ve attached a devlog video. For those of you who do not speak dutch it is better to watch it without sound :P



What do you think?

18
General / Re: Trowing projectiles on 2d isometric map
« on: May 27, 2020, 10:08:37 pm »
Well getting a good night sleep helped me solve it!

The answer was in hindsight pretty obvious:
I was doing my movement calculations in world space instead of screenspace! And going "up" ment going to a lower Y value. This is working code now:

Code: [Select]
projectile::projectile(int projectileStartX, int projectileStartY, int projectileTargetX, int projectileTargetY, int projectileType, int damageOnImpact, int splashDamageOnImpact)
{
this->X = worldSpace(projectileStartX, projectileStartY, true);
this->Y = worldSpace(projectileStartX, projectileStartY, false);
this->Z = 0;
this->projectileType = projectileType;
this->damageOnImpact = damageOnImpact;
this->projectileTarget = { projectileTargetX, projectileTargetY };
this->projectilePosition = {projectileStartX, projectileStartY};
this->splashDamageOnImpact = splashDamageOnImpact;
float travelTimeInSeconds = distEuclidean(projectileStartX * 32.f, projectileStartY * 32.f, projectileTargetX * 32.f, projectileTargetY * 32.f) / 128.f; //32 pixel/s
this->deltaX = (this->X - float(worldSpace(this->projectileTarget.x, this->projectileTarget.y, true))) / travelTimeInSeconds;
this->deltaY = (this->Y - float(worldSpace(this->projectileTarget.x, this->projectileTarget.y, false))) / travelTimeInSeconds;
this->deltaZ = travelTimeInSeconds*3;
this->timeFired = currentGame.getTime();
this->reachedTarget = false;
this->X += 32;
}

void projectile::updatePosition()
{
if (!reachedTarget) {
//speed is in pixels per second
if (this->timeFired + 0.016 < currentGame.getTime()) {
this->timeFired = currentGame.getTime();
this->X -= this->deltaX/60.f;
this->Y -= this->deltaY/60.f;
this->Z -= this->deltaZ;
this->deltaZ -= 0.096f;
if (this->Z >= 0.0f) {
doDamage();
reachedTarget = true;
}
}
}
}

Near the end of this video shows the script in action!




19
General / Solved: Trowing projectiles on 2d isometric map
« on: May 26, 2020, 09:39:44 pm »
I am creating an isometric RTS with SFML I have most of the unit AI and basic melee combat in place.

For a little demo see my devlog:


Now comes the hard part. It would be fun to add ranged units. In order to acomadate for this I've created a projectile class and started to work to try and render a paraboloic 3d trajectory in my 2d isometric space.

My projectiles move along x,y,z axis and I then translate their coördinates to my isometric projection:

Code: [Select]
screenX = x*2 //since a tile is 64 pixels wide and 32 tall
screenY = y+z //since any upward movement is only visable in the Y axis

around this concept I made the following class:

Code: [Select]
struct mouseWorldCord
{
    int x;
    int y;
};

class projectile
{
public:
projectile(int projectileStartX, int projectileStartY, int projectileTargetX, int projectileTargetY, int projectileType, int damageOnImpact, int splashDamageOnImpact);
void updatePosition();
void drawProjectile();
void doDamage();
void doSplashDamage();

private:
mouseWorldCord projectilePosition;
mouseWorldCord projectileTarget;
float timeFired;
int projectileType;
int damageOnImpact;
int splashDamageOnImpact;
float X;
float Y;
float Z;
float deltaX;
float deltaY;
float deltaZ;
bool reachedTarget;
};


std::vector<projectile> listOfProjectiles;

projectile::projectile(int projectileStartX, int projectileStartY, int projectileTargetX, int projectileTargetY, int projectileType, int damageOnImpact, int splashDamageOnImpact)
{
this->X = worldSpace(projectileStartX, projectileStartY, true)/2;
this->Y = worldSpace(projectileStartX, projectileStartY, false);
this->Z = 0;
this->projectileType = projectileType;
this->damageOnImpact = damageOnImpact;
this->projectileTarget = { projectileTargetX, projectileTargetY };
this->projectilePosition = {projectileStartX, projectileStartY};
this->splashDamageOnImpact = splashDamageOnImpact;
float travelTimeInSeconds = distEuclidean(projectileStartX * 32.f, projectileStartY * 32.f, projectileTargetX * 32.f, projectileTargetY * 32.f) / 32.f; //32 pixel/s
this->deltaX = ((projectileStartX * 32.f) - (projectileTargetX * 32.f)) / travelTimeInSeconds;
this->deltaY = ((projectileStartY * 32.f) - (projectileTargetY * 32.f)) / travelTimeInSeconds;
this->deltaZ = travelTimeInSeconds / 2;
this->timeFired = currentGame.getTime();
this->reachedTarget = false;
}

void projectile::updatePosition()
{
if (!reachedTarget) {
//speed is in pixels per second
if (this->timeFired + 0.016 < currentGame.getTime()) {
this->timeFired = currentGame.getTime();
this->X += this->deltaX/60.f;
this->Y += this->deltaY/60.f;
this->Z += this->deltaZ/60.f;
this->deltaZ -= 0.016f;
if (this->Z <= 0.0f) {
doDamage();
reachedTarget = true;
}
}
}
}

void projectile::drawProjectile()
{
int xScreenCord = this->X * int(2);
int yScreenCord = this->Y + this->Z;
currentGame.spriteArrow.setPosition(xScreenCord, yScreenCord);
window.draw(currentGame.spriteArrow);
}

void projectile::doDamage()
{
if (currentGame.occupiedByActorList[this->projectileTarget.x][this->projectileTarget.y] != -1) {
listOfActors[currentGame.occupiedByActorList[this->projectileTarget.x][this->projectileTarget.y]].takeDamage(this->damageOnImpact);
}
else if (currentGame.occupiedByBuildingList[this->projectileTarget.x][this->projectileTarget.y] != -1)
{
listOfBuildings[currentGame.occupiedByBuildingList[this->projectileTarget.x][this->projectileTarget.y]].takeDamage(this->damageOnImpact);
}
}


What I want to achieve is have a fixed horizontal velocity. I broke this down in an x-vector and y-vector. I vary the z velocity. My aim is to have the velocity decrease over time and be at 0 in the middle of the path and then have a negative velocity the second half which increases each frame. Just like gravity is pulling on the projectile. In this way I get a nice parabolic trajectory for my arrow without complicated math. Or so I thought.

I must have made a mistake somewhere because my arrow is not moving as intended. It just follows a straight line of the screen. There is probably something amiss in my initial deltaZ velocity.

Maybe a fresh set of eyes looking at the code will help.

Pages: 1 [2]