Difference between revisions of "Complete roguelike tutorial using C++ and libtcod - part 9: spells and ranged combat"
(pasted →The scroll of lightning bolt) |
(pasted →Some helpers) |
||
Line 10: | Line 10: | ||
This dreadful spell will deal 20 damage to the closest monster, up to a distance of 5 tiles. So the first thing we need is some helper functions to get the closest monster within a range. | This dreadful spell will deal 20 damage to the closest monster, up to a distance of 5 tiles. So the first thing we need is some helper functions to get the closest monster within a range. | ||
===Some helpers=== | |||
The easiest is a function to get the distance from an actor to a specific tile of the map : | |||
Actor.hpp | |||
float getDistance(int cx, int cy) const; | |||
Actor.cpp | |||
float Actor::getDistance(int cx, int cy) const { | |||
int dx=x-cx; | |||
int dy=y-cy; | |||
return sqrtf(dx*dx+dy*dy); | |||
} | |||
Well that was a small warmup. Don't forget to include math.h for the sqrtf function. Now let's do something manlier. | |||
Engine.hpp | |||
Actor *getClosestMonster(int x, int y, float range) const; | |||
This function returns the closest monster from position x,y within range. If range is 0, it's considered infinite. If no monster is found within range, it returns NULL. | |||
Engine.cpp | |||
Actor *Engine::getClosestMonster(int x, int y, float range) const { | |||
Actor *closest=NULL; | |||
float bestDistance=1E6f; | |||
First we declare some variable. closest is the closest monster found so far. bestDistance is the distance for the closest monster found so far. We initialize it with a value higher than any possible value (1E6 == 1000000) so that the first monster in the range will be a candidate. So let's iterate over the actors list and check alive monsters : | |||
for (Actor **iterator=actors.begin(); | |||
iterator != actors.end(); iterator++) { | |||
Actor *actor=*iterator; | |||
if ( actor != player && actor->destructible | |||
&& !actor->destructible->isDead() ) { | |||
Now let's check if the guy is within range and closer than what we found so far. | |||
float distance=actor->getDistance(x,y); | |||
if ( distance < bestDistance && ( distance <= range || range == 0.0f ) ) { | |||
bestDistance=distance; | |||
closest=actor; | |||
} | |||
} | |||
} | |||
return closest; | |||
} | |||
[[Category:Developing]] | [[Category:Developing]] |
Revision as of 12:04, 16 October 2015
Complete roguelike tutorial using C++ and libtcod -originally written by Jice Text in this tutorial was released under the Creative Commons Attribution-ShareAlike 3.0 Unported and the GNU Free Documentation License (unversioned, with no invariant sections, front-cover texts, or back-cover texts) on 2015-09-21. |
---|
|
In this article, we'll start to add diversity to the gameplay by adding three new spells :
- lightning bolt : deals damages to the closest enemy
- fireball : powerful area effect spell
- confusion : turns the selected enemy into a randomly wandering zombie for a few turns
The scroll of lightning bolt
This dreadful spell will deal 20 damage to the closest monster, up to a distance of 5 tiles. So the first thing we need is some helper functions to get the closest monster within a range.
Some helpers
The easiest is a function to get the distance from an actor to a specific tile of the map :
Actor.hpp
float getDistance(int cx, int cy) const;
Actor.cpp
float Actor::getDistance(int cx, int cy) const { int dx=x-cx; int dy=y-cy; return sqrtf(dx*dx+dy*dy); }
Well that was a small warmup. Don't forget to include math.h for the sqrtf function. Now let's do something manlier.
Engine.hpp
Actor *getClosestMonster(int x, int y, float range) const;
This function returns the closest monster from position x,y within range. If range is 0, it's considered infinite. If no monster is found within range, it returns NULL.
Engine.cpp
Actor *Engine::getClosestMonster(int x, int y, float range) const { Actor *closest=NULL; float bestDistance=1E6f;
First we declare some variable. closest is the closest monster found so far. bestDistance is the distance for the closest monster found so far. We initialize it with a value higher than any possible value (1E6 == 1000000) so that the first monster in the range will be a candidate. So let's iterate over the actors list and check alive monsters :
for (Actor **iterator=actors.begin(); iterator != actors.end(); iterator++) { Actor *actor=*iterator; if ( actor != player && actor->destructible && !actor->destructible->isDead() ) { Now let's check if the guy is within range and closer than what we found so far.
float distance=actor->getDistance(x,y); if ( distance < bestDistance && ( distance <= range || range == 0.0f ) ) { bestDistance=distance; closest=actor; } } } return closest; }