Related
Hi I wanted to create a custom hitbox system in Spigot 1.8.8. This is my code but for some reason the list is empty. I want to use this because I want to use it in a plugin I am creating.
public static List<LivingEntity> getLivingEntities(Player caster, Dimension dimension) {
//Input
List<LivingEntity> list = new ArrayList<>();
Vector direction = caster.getLocation().getDirection();
double x = dimension.getX();
double y = dimension.getY();
int frequency = (int) dimension.getZ();
//Calculation
for(int i = frequency; i > 0; i--) {
Collection<Entity> entities = caster.getWorld().getNearbyEntities(caster.getLocation().add(direction.multiply((x/frequency) * i)), y, y, y);
for(Entity e: entities) {
if(e instanceof LivingEntity) {
LivingEntity le = (LivingEntity) e;
if(!list.contains(le)) {
list.add(le);
}
}
}
}
//Output
return list;
}
This is my Dimensions class
public class Dimension {
private double x;
private double y;
private double z;
public Dimension(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return z;
}
public void setZ(double z) {
this.z = z;
}
Does anyone know what the problem might be?
Thank you.
When I try to compile the following code:
Alien::Action::Action(ActionType type, float x, float y) {
Action::type = type;
pos = Vec2(x, y);
}
Alien::Alien(float x, float y, int nMinions) {
srand(time(NULL));
sp = Sprite("img/alien.png");
box = Rect(x, y, sp.GetWidth(), sp.GetHeight());
box.x = x - box.h/2;
box.y = y - box.w/2;
hitpoints = 100;
speed.x = 0.5;
speed.y = 0.5;
minionArray = std::vector<Minion>();
for(int i = 0; i < nMinions; i++) {
int a = rand()%501;
float b = a/1000.0;
float c = b+1;
minionArray.emplace_back(Minion(get(), i*(360/nMinions), c));
}
taskQueue = std::queue<Action>();
}
The IDE (Eclipse) gives the following error message: "undefined reference to 'vtable for Alien'" (line 6 of the code). Since there's no virtual method inside Alien, I don't know the cause of the error. The following is the header file for Alien:
#ifndef ALIEN_H_
#define ALIEN_H_
#include "GameObject.h"
class Alien: public GameObject {
private:
class Action {
public:
enum ActionType {MOVE, SHOOT};
ActionType type;
Action(ActionType type, float x, float y);
Vec2 pos;
};
int hitpoints;
std::queue<Action> taskQueue;
std::vector<Minion> minionArray;
public:
Alien(float x, float y, int nMinions);
~Alien();
void Update(float dt);
void Render();
Alien* get();
bool IsDead();
};
#endif
The code for GameObject is :
#include "GameObject.h"
#include "InputManager.h"
#include "Camera.h"
#include "State.h"
GameObject::~GameObject() {
}
GameObject* GameObject::get() {
return this;
}
Minion::~Minion() {
}
Minion::Minion(GameObject* minionCenter, float arcOffset, float minionSize) {
sp = Sprite("img/minion.png");
center = minionCenter;
translation = arcOffset;
box = Rect(center->box.GetCenter().x+(cos(translation*M_PI/180)*200)-(sp.GetWidth()/2),
center->box.GetCenter().y+(sin(translation*M_PI/180)*200)-(sp.GetHeight()/2),
sp.GetWidth(), sp.GetHeight());
}
void Minion::Shoot(Vec2 pos) {
State::AddObject(new BulletWheel(box.GetCenter().x, box.GetCenter().y, center->box.GetCenter().GetDX(pos.x),
center->box.GetCenter().GetDY(pos.y), center->box.GetCenter().GetDS(pos), 0.3,
translation, center->box.GetCenter(), "img/minionbullet1.png"));
}
void Minion::Update(float dt) {
if(translation < 360)
translation += 0.03*dt;
else
translation += 0.03*dt-360;
/*rotation = translation-90;*/
if(rotation < 360)
rotation += 0.15*dt;
else
rotation += 0.15*dt-360;
box.x = center->box.GetCenter().x+(200*cos((translation)*M_PI/180))-(box.w/2);
box.y = center->box.GetCenter().y+(200*sin((translation)*M_PI/180))-(box.h/2);
}
void Minion::Render() {
sp.Render(box.x - Camera::GetInstance().pos.x, box.y - Camera::GetInstance().pos.y, rotation);
}
bool Minion::IsDead() {
return false;
}
Bullet::Bullet(float x, float y, float dx, float dy, float maxDistance, float speed, std::string sprite) {
sp = Sprite(sprite);
box = Rect(x-(sp.GetWidth()/2), y-(sp.GetHeight()/2), sp.GetWidth(), sp.GetHeight());
Bullet::speed = Vec2(speed*(dx/maxDistance), speed*(dy/maxDistance));
distanceLeft = maxDistance;
rotation = atan2(dy, dx)*(180/M_PI);
}
void Bullet::Update(float dt) {
if(distanceLeft > 0) {
box.x += speed.x*dt;
box.y += speed.y*dt;
distanceLeft -= pow(pow(speed.x*dt,2)+pow(speed.y*dt,2),0.5);
}
}
void Bullet::Render() {
sp.Render(box.x - Camera::GetInstance().pos.x, box.y - Camera::GetInstance().pos.y, rotation);
}
bool Bullet::IsDead() {
return (distanceLeft < 1) ? true : false;
}
Bullet* Bullet::get() {
return this;
}
BulletWheel::BulletWheel(float x, float y, float dx, float dy, float maxDistance, float speed, float arcOffset, Vec2 center, std::string sprite) {
sp = Sprite(sprite);
sp.SetScaleX(2);
sp.SetScaleY(2);
box = Rect(x-(sp.GetWidth()/2), y-(sp.GetHeight()/2), sp.GetWidth(), sp.GetHeight());
BulletWheel::speed = Vec2(speed*(dx/maxDistance), speed*(dy/maxDistance));
distanceLeft = maxDistance;
rotation = atan2(dy, dx)*(180/M_PI);
translation = arcOffset;
BulletWheel::center = center;
}
void BulletWheel::Update(float dt) {
if(translation < 360)
translation += 0.1*dt;
else
translation += 0.1*dt-360;
if(distanceLeft > 0.01) {
center.x += speed.x*dt;
center.y += speed.y*dt;
box.x = center.x+(200*cos((translation)*M_PI/180))-(box.w/2);
box.y = center.y+(200*sin((translation)*M_PI/180))-(box.h/2);
distanceLeft -= pow(pow(speed.x*dt,2)+pow(speed.y*dt,2),0.5);
}
}
void BulletWheel::Render() {
sp.Render(box.x - Camera::GetInstance().pos.x, box.y - Camera::GetInstance().pos.y, rotation);
}
bool BulletWheel::IsDead() {
return distanceLeft < 1;
}
BulletWheel* BulletWheel::get() {
return this;
}
and its header file is:
#ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_
#include "Sprite.h"
#include "Rect.h"
#include "Vec2.h"
#include <queue>
#include <vector>
#include <cmath>
#include <ctime>
class GameObject{
private:
public:
virtual ~GameObject();
virtual void Update(float dt) = 0;
virtual void Render() = 0;
virtual bool IsDead() = 0;
virtual GameObject* get();
int rotation = 0;
int translation = 0;
Sprite sp = Sprite();
Vec2 speed = Vec2();
Rect box = Rect();
};
class Minion : public GameObject {
private:
GameObject* center;
public:
Minion(GameObject* minionCenter, float arcOffset, float minionSize = 1);
~Minion();
void Shoot(Vec2 pos);
void Update(float dt);
void Render();
bool IsDead();
Minion* get();
};
class Bullet : public GameObject {
private:
float distanceLeft;
public:
Bullet(float x, float y, float dx, float dy, float maxDistance, float speed, std::string sprite);
void Update(float dt);
void Render();
bool IsDead();
Bullet* get();
};
class BulletWheel : public GameObject {
private:
float distanceLeft;
Vec2 center;
public:
BulletWheel(float x, float y, float dx, float dy, float maxDistance, float speed, float arcOffset, Vec2 center, std::string sprite);
void Update(float dt);
void Render();
bool IsDead();
BulletWheel* get();
};
#endif /* GAMEOBJECT_H_ */
There are the virtual functions of GameObject, declared inside Alien.cpp:
void Alien::Update(float dt) {
if(rotation > 0)
rotation -= 0.1*dt;
else
rotation -= 0.1*dt+360;
if(InputManager::GetInstance().MousePress(RIGHT_MOUSE_BUTTON)) {
taskQueue.push(Action(Action::MOVE,(InputManager::GetInstance().GetMouseX() + Camera::GetInstance().pos.x - (box.w/2)),
(InputManager::GetInstance().GetMouseY() + Camera::GetInstance().pos.y - (box.h/2))));
}
if(InputManager::GetInstance().MousePress(LEFT_MOUSE_BUTTON)) {
taskQueue.push(Action(Action::SHOOT,(InputManager::GetInstance().GetMouseX() + Camera::GetInstance().pos.x),
(InputManager::GetInstance().GetMouseY() + Camera::GetInstance().pos.y)));
}
if(taskQueue.size() > 0) {
Vec2 pos = taskQueue.front().pos;
if(taskQueue.front().type == Action::MOVE) {
float cos = (box.GetDX(pos.x)/box.GetDS(pos));
float sin = (box.GetDY(pos.y)/box.GetDS(pos));
if(cos != cos) {
cos = 0;
}
if(sin != sin) {
sin = 0;
}
if((box.x+speed.x*cos*dt > pos.x && pos.x > box.x) || (box.x+speed.x*cos*dt < pos.x && pos.x < box.x)) {
box.x = pos.x;
}
else {
box.x += speed.x*cos*dt;
}
if((box.y+speed.y*sin*dt > pos.y && pos.y > box.y) || (box.y+speed.y*sin*dt < pos.y && pos.y < box.y)) {
box.y = pos.y;
}
else {
box.y += speed.y*sin*dt;
}
if(box.x == pos.x && box.y == pos.y) {
taskQueue.pop();
}
}
else {
for(unsigned i = 0; i < minionArray.size(); i++) {
minionArray.at(i).Shoot(pos);
taskQueue.pop();
}
}
}
for(unsigned i = 0; i < minionArray.size(); i++) {
minionArray.at(i).Update(dt);
}
}
void Alien::Render() {
sp.Render(box.x - Camera::GetInstance().pos.x, box.y - Camera::GetInstance().pos.y, rotation);
if(minionArray.size() > 0) {
for(unsigned i = 0; i < Alien::minionArray.size(); i++) {
minionArray.at(i).Render();
}
}
}
bool Alien::IsDead() {
return (Alien::hitpoints <= 0);
}
EDIT: the destructor of Alien was missing.
All classes derived from GameObject must define all pure virtual functions in GameObject. In your case, this is:
virtual void Update(float dt) = 0;
virtual void Render() = 0;
virtual bool IsDead() = 0;
Here is a similar question with more information. Hope this helps!
I am using OpenCV 2.4.10 with Visual Studio 2013 for my code. But I am getting the following linking error:
1>Pathfinding.obj : error LNK2019: unresolved external symbol "public:
class cv::Vec & __cdecl cv::Mat::at >(int,int)"
(??$at#V?$Vec#E$02#cv###Mat#cv##QEAAAEAV?$Vec#E$02#1#HH#Z) referenced
in function "private: struct Pathfinding::Point2A * __cdecl
Pathfinding::GetNeighbors(struct Pathfinding::Point2A,int &)"
(?GetNeighbors#Pathfinding##AEAAPEAUPoint2A#1#U21#AEAH#Z)
1>C:\Users\ysingh\Documents\DstarLite\OpenCV\Astar\x64\Debug\Astar.exe
: fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Here is the header file (please see struct Point2A in class definition) where the above error is referring to:
#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<string>
class Pathfinding
{
private :
//Two dimensional , integer -based point structure , contains additional variables for pathfinding calculation
**struct Point2A**
{
// x, y the coordinates of the point
//dir is the direction from the previous point . see directions coding below
int x, y, dir;
//level: the cost of route from start to this point
//fscore: the essence of the A* algorithm, value is : [level] + [in air distance from destination] * astar_weight
float fScore, level;
//Constructors
Point2A() : x(0), y(0), fScore(0), dir(0){};
Point2A(int _x, int _y, float _level = 0.f, int _dir = 0) :x(_x), y(_y), level(_level), fScore(0), dir(_dir) {};
//== operator overload
bool operator == (const Point2A other);
};
//CompByPos : struct used in the stl map<Point2A, Point2A> during the pathfinding
//it only contains a comparator function
//we need this, because every point is unique by position, but not by fscore
struct CompByPos
{
bool operator()(const Point2A a, const Point2A b) const;
};
//CompByFScore : contains a comparating function, which works by fscore
//it gives priority for the smaller fScore
//used in stl priority_queue<Point2A>
struct CompByFScore
{
bool operator()(const Point2A a, const Point2A b);
};
//mapimg is the map got, pathmap is the same, but the pixels of the path are colored
//pathmap is only valid after calculate path
//blurmap is matimg blurred with opencv function, its used in keeping away from walls
cv::Mat mapimg, pathmap, blurmap;
//astar_weight is the multiplier of A* coefficient
//wall_weight is used in keeping away from walls features
float astar_weight, wall_weight;
//no comment
Point2A start, dest;
//daigonal decides if a pixel (which is a node) has 4 or 8 neighbours
//see direction coding below
//calculated decides if the Pathfinding object has valid path for current map and settings
bool diagonal, calculated;
//mrows and mcols refers to the size of mapimg
//blursize is used in avaoiding wall avoidance feature
int mrows, mcols, blur_size;
//stores the list of directions for the path
std::string dir;
//calculated Eucledian Distance between two points a and b
float Distance(Point2A a, Point2A b);
//returns an array of the points surrounding point p
//the length of the array is not constant, because the function performs
//OnMap checks too. use arraySize ref variable to get the size of the array returned
Point2A* GetNeighbors(Point2A p, int& arraySize);
// Function sets default values
void InitValues();
//Checks if point p is wall
//Class support black and white maps, where black pixels are wall
bool IsWall(Point2A p);
//Function decides if coordinates of this point are on map or not
bool OnMap(int x, int y);
public:
enum ErrorCodes
{
NoError = 0,
NoMap,
StartIsWall,
DestIsWall,
NoPath,
AlreadyCalculated
};
static const int diagonalDirX[];
static const int diagonalDirY[];
static const int nonDiagonalDirX[];
static const int nonDiagonalDirY[];
//constructor :sets default values diagonal = true, astar coefficient 0.3
Pathfinding();
//constructor, argument map is the map on which algorithm is implemented
Pathfinding(cv::Mat map, bool _diagonal = true);
//Set OpenCV Mat image as the map
void SetMap(cv::Mat map);
////sets the A* pathfinding coefficient. 0.f means Dijkstra's algorithm, anything else is A* (positive values recommended).
//The bigger the value, the more the algorithm steers towards the destination
//but setting it too high can result in suboptimal path
//after changing that, have to call CalculatePath again
void SetAWeight(float weight);
//if set to true, each pixel has 8 connected neighbor, else only 4 - see GetDirections() comment
//after changing that, have to call CalculatePath again
void SetDiagonal(bool _diagonal);
//sets the value of how much the algorithm tries to avoid going near walls.
//weight: the amount the walls push away the route. default 10.f
//0.f disables the feature
//avoidZoneLevel: the size of the zone surrounding the walls, in which the upper effect works. default: 5
void SetWallWeight(float weight, int avoidZoneLevel);
//sets the start point. the coordinate system is the OpenCV/image default, the origin is the upper left corner of the image.
//start and destination points have to be set after the map image!
void SetStart(int x, int y);
void SetDestination(int x, int y);
//returns the map, on which the calculated path is marked red
//call this after CalculatePath(), otherwise returns empty map
cv::Mat GetPathMap();
// returns a std::string of numbers, which represent the directions along the path.Direction coding(relative to p) :
//call after CalculatePath()
//if diagonal is set to true if diagonal == false
// [0] [1] [2] [3]
// [3] [p] [4] [2] [p] [0]
// [5] [6] [7] [1]
std::string GetDirections();
//evaluates the algorithm. It's a separate function because it takes some time
//check out the ErrorCodes enum to decode the returned values
ErrorCodes CalculatePath();
};
I am also attaching the .cpp for this class
#include "Pathfinding.h"
bool Pathfinding::Point2A::operator==(const Point2A other) {
return x == other.x && y == other.y;
}
bool Pathfinding::CompByPos::operator()(const Point2A a, const Point2A b) const
{
if (a.x == b.x)
return a.y > b.y;
else
return a.x > b.x;
}
bool Pathfinding::CompByFScore::operator()(const Point2A a, const Point2A b)
{
return a.fScore > b.fScore;
}
float Pathfinding::Distance(Point2A a, Point2A b)
{
float x = static_cast<float>(a.x - b.x);
float y = static_cast<float>(a.y - b.y);
return sqrtf(x*x + y*y);
}
Pathfinding:: Point2A* Pathfinding::GetNeighbors(Point2A p, int& arraySize)
{
arraySize = 0;
uchar size;
if (diagonal)
size = 8;
else
size = 4;
Point2A* ret = new Point2A[size];
for (int i = 0; i < size; i++) {
int x, y;
if (diagonal)
{
x = p.x + diagonalDirX[i];
y = p.y + diagonalDirY[i];
}
else
{
x = p.x + nonDiagonalDirX[i];
y = p.y + nonDiagonalDirY[i];
}
if (!OnMap(x, y))
continue;
float level = p.level + 1.f + (255 - blurmap.at<cv::Vec3b>(y, x)[2]) / 255.f * wall_weight;
Point2A n = Point2A(x, y, level, i);
if (diagonal && (i == 0 || i == 2 || i == 5 || i == 7))
n.level += 0.414213f;
ret[arraySize] = n;
arraySize++;
}
return ret;
}
void Pathfinding::InitValues()
{
astar_weight = 0.3f;
wall_weight = 10.f;
blur_size = 11;
diagonal = true;
calculated = false;
}
bool Pathfinding::IsWall(Point2A p)
{
if (mapimg.at<cv::Vec3b>(p.y, p.x) == cv::Vec3b(0, 0, 0))
return true;
return false;
}
bool Pathfinding::OnMap(int x, int y)
{
if (x >= 0 && y >= 0 && x < mcols && y < mrows)
return true;
return false;
}
const int Pathfinding::diagonalDirX[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
const int Pathfinding::diagonalDirY[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int Pathfinding::nonDiagonalDirX[] = { 1, 0, -1, 0 };
const int Pathfinding::nonDiagonalDirY[] = { 0, 1, 0, -1 };
Pathfinding::Pathfinding()
{
InitValues();
}
Pathfinding::Pathfinding(cv::Mat map, bool _diagonal)
{
InitValues();
SetMap(map);
diagonal = _diagonal;
}
void Pathfinding::SetMap(cv::Mat map)
{
if (!map.empty())
{
mapimg = map;
calculated = false;
mrows = map.rows;
mcols = map.cols;
GaussianBlur(mapimg, blurmap, cv::Size(blur_size, blur_size), 0);
}
}
void Pathfinding::SetAWeight(float weight)
{
if (astar_weight != weight)
{
astar_weight = weight;
calculated = false;
}
}
void Pathfinding::SetDiagonal(bool _diagonal)
{
if (diagonal != _diagonal)
{
diagonal = _diagonal;
calculated = false;
}
}
void Pathfinding::SetWallWeight(float weight, int avoidZoneLevel)
{
if (wall_weight == weight && blur_size == 2 * avoidZoneLevel + 1)
return;
wall_weight = weight;
if (avoidZoneLevel >= 0)
blur_size = 2 * avoidZoneLevel + 1;
calculated = false;
}
void Pathfinding::SetStart(int x, int y)
{
if (!mapimg.empty())
{
if (OnMap(x, y))
{
start = Point2A(x, y);
calculated = false;
}
}
}
void Pathfinding::SetDestination(int x, int y)
{
if (!mapimg.empty())
{
if (OnMap(x, y))
{
dest = Point2A(x, y);
calculated = false;
}
}
}
cv::Mat Pathfinding::GetPathMap()
{
if (calculated) return pathmap;
else return cv::Mat();
}
std::string Pathfinding::GetDirections()
{
if (calculated) return dir;
else return std::string();
}
Pathfinding::ErrorCodes Pathfinding::CalculatePath()
{
if (calculated)
return AlreadyCalculated;
if (mapimg.empty())
return NoMap;
if (IsWall(start))
return StartIsWall;
if (IsWall(dest))
return DestIsWall;
dir = std::string();
mapimg.copyTo(pathmap);
int **closedSet = new int*[mrows];
float **openSet = new float*[mrows];
for (int i = 0; i < mrows; i++) {
closedSet[i] = new int[mcols];
openSet[i] = new float[mcols];
for (int j = 0; j < mcols; j++) {
closedSet[i][j] = 0;
openSet[i][j] = -1.0f;
}
}
std::priority_queue<Pathfinding::Point2A, std::vector<Point2A>, CompByFScore> openSetQue[2];
int osq = 0;
std::map <Pathfinding::Point2A, Pathfinding::Point2A, CompByPos> cameFrom;
start.fScore = Distance(start, dest);
openSetQue[osq].push(start);
openSet[start.y][start.x] = 0.0f;
while (openSetQue[osq].size() != 0) {
Point2A current = openSetQue[osq].top();
if (current == dest) {
while (cameFrom.size() != 0) {
pathmap.at<cv::Vec3b>(current.y, current.x) = cv::Vec3b(0, 0, 255);
dir = std::to_string(current.dir) + dir;
auto it = cameFrom.find(current);
Point2A keytmp = current;
if (it == cameFrom.end()) {
for (int i = 0; i < mrows; i++) {
delete openSet[i];
delete closedSet[i];
}
delete openSet;
delete closedSet;
calculated = true;
dir = dir.substr(1, dir.length() - 1);
return NoError;
}
current = cameFrom[current];
cameFrom.erase(keytmp);
}
}
openSetQue[osq].pop();
closedSet[current.y][current.x] = 1;
int arraySize;
Point2A *neighbors = GetNeighbors(current, arraySize);
for (int i = 0; i < arraySize; i++) {
Point2A neighbor = neighbors[i];
if (closedSet[neighbor.y][neighbor.x] == 1)
continue;
if (IsWall(neighbor)) {
closedSet[neighbor.y][neighbor.x] = 1;
continue;
}
float ngScore = neighbor.level;
if (openSet[neighbor.y][neighbor.x] == -1.0f || ngScore < openSet[neighbor.y][neighbor.x]) {
cameFrom[neighbor] = current;
neighbor.fScore = ngScore + Distance(neighbor, dest) * astar_weight;
if (openSet[neighbor.y][neighbor.x] == -1.0f) {
openSet[neighbor.y][neighbor.x] = ngScore;
openSetQue[osq].push(neighbor);
}
else {
openSet[neighbor.y][neighbor.x] = ngScore;
while (!(neighbor == openSetQue[osq].top())) {
openSetQue[1 - osq].push(openSetQue[osq].top());
openSetQue[osq].pop();
}
openSetQue[osq].pop();
if (openSetQue[osq].size() >= openSetQue[1 - osq].size()) {
osq = 1 - osq;
}
while (!openSetQue[osq].empty()) {
openSetQue[1 - osq].push(openSetQue[osq].top());
openSetQue[osq].pop();
}
osq = 1 - osq;
openSetQue[osq].push(neighbor);
}
}
}
delete neighbors;
}
return NoPath;
}
Here is my main file .cpp too :
#include"Pathfinding.h"
#include<opencv2\highgui\highgui.hpp>
#include<iostream>
Pathfinding pathfinding;
cv::Mat mapimg;
void DisplayMap()
{
cv::Mat tmp;
cv::imshow("Path", tmp);
}
int main()
{
//Open and load the map
mapimg = cv::imread("test.png");
pathfinding.SetMap(mapimg);
pathfinding.SetWallWeight(0.f, 0);
pathfinding.SetStart(1, 1);
pathfinding.SetDestination(39, 53);
pathfinding.SetDiagonal(false);
DisplayMap();
}
I think I am using Pathfinding class twice in the definition of the functions in .cpp ( i.e. Line 29 in .cpp file > Pathfinding:: Point2A* Pathfinding::GetNeighbors(Point2A p, int& arraySize)
My intention is not to throw a bunch of codes at the people but to give them an complete picture for the problem so that people can provide me some useful suggestions. My apologies for this.
My deadlines are near and I am constrained with time. Can someone suggest me some solutions.
I assume your project settings are the problem for this (your write you did a working minimalistic example, so you indeed use right libs and includes).
Please check what the include and lib paths evaluate to (check this inside the configuration site). Maybe you see they are relative paths or a makro was set wrong.
Usually, an "UNRESOLVED EXTERNAL" error means you did not link the right lib (32/64 debug/release these are 4 different combinations!) or the path to the lib is wrong.
See this answer,
If you DID explicitly set up linking with all the necessary libraries,
but linking errors still show, you might be mixing up 64/32 bit
libraries and application.
BUILD -> Configration Manager. check 'platform' is 'x64'
Check that your Project -> Properties -> VC++ Directories -> Library Directories, includes the path where the OpenCV libraries are
And Linker -> General -> Aditional Library Directories
C:\opencv\build\x64\vc11\lib
(on a 64-bit machine running VS2012, it will vary on other setups).
I am receiving error C2512: 'LoadingWorldlet' : no appropriate default constructor available, when I try to compile this file. There is no explicit constructor, so I can not think of a reason for me to be recieving this error.
struct Worldlet {
int x, z;
glm::mat4 worldletMatrix;
std::vector<Voxel> blocks;
};
struct LoadingWorldlet {
int x, z;
std::future<Worldlet> &result;
};
class World {
public:
World();
~World();
void Init();
void InitRenderable();
void UpdateWorldletList(int x, int z);
void Render(Shader* worldShader, Camera *mainPov);
static Worldlet LoadWorldlet(int x, int z, std::ifstream &file);
private:
std::vector<Worldlet> worldlets;
std::vector<LoadingWorldlet> loadingWorldlets;
std::vector<std::string> loadingTitles;
std::vector<int> toRemove;
Renderable cube;
std::string worldName, prefix;
static const float CUBE_SIZE;
static const int LOADLIMIT = 1;
int GetLoadRadius(int r = 0) {
static int i = r;
return i;
}
};
This is the only function in which LoadingWorldlet is used:
void World::UpdateWorldletList(int x, int z) {
static int previousX, previousZ;
for(int index: toRemove) {
worldlets.erase(worldlets.begin() + index);
}
toRemove.clear();
int loaded = 0;
std::vector<int> clearList;
for(auto &loading: loadingWorldlets) {
if(loaded >= LOADLIMIT) break;
worldlets.push_back(loading.result.get());
clearList.push_back(loaded);
loaded++;
}
for(int i: clearList)
loadingWorldlets.erase(loadingWorldlets.begin()+i);
if(previousX != x && previousZ != z) {
int i = 0;
for(auto worldlet: worldlets) {
if(pow(worldlet.x - x, 2) + pow(worldlet.z - z, 2) > GetLoadRadius()) {
toRemove.push_back(i);
}
i++;
}
for(int recX = -GetLoadRadius(); recX < GetLoadRadius(); recX++) {
for(int recZ = -GetLoadRadius(); recZ < GetLoadRadius(); recZ++) {
bool cont = false;
for(auto worldlet: worldlets) {
if (worldlet.x == recX && worldlet.z == recZ) {
cont = true;
break;
}
}
for(auto loading: loadingWorldlets) {
if (loading.x == recX && loading.z == recZ) {
cont = true;
break;
}
}
if(cont || pow(recX - x, 2) + pow(recZ - z, 2) > GetLoadRadius())
continue;
std::ifstream file("./worlds/" + worldName + "/" + prefix + std::to_string(recX) + "X" + std::to_string(recZ) + "Z.json");
if (!file)
continue;
LoadingWorldlet loading;
loading.x = recX;
loading.z = recZ;
loading.result = std::async(LoadWorldlet, recX, recZ, file);
loadingWorldlets.push_back(loading);
}
}
}
}
I have tried adding a default constructor, but then I receive an error about a missing = operator. Doesn't the compiler automatically add in these things? How can I fix the error? If it is important, I am using Visual Studio 2013 preview.
Looking over the code, you'll need to a way to instantiate your reference to std::future<Worldlet> &result;
Typically, this is done through a constructor.
struct LoadingWorldlet
{
LoadingWorldlet( std::future<Worldlet> & inWorldlet ):
result( inWorldlet ) {}
int x, z;
std::future<Worldlet> &result;
};
Otherwise, you could simply not make the data member a reference ( this assumes that other data members don't also have mandatory constructors):
std::future<Worldlet> result;
LeftCollision in CheckCollision() goes true, when ever Object1 collides with Object2(square which is scrolling from right to left of screen) left side. But in the GameObject::Update()
Leftcollision never updates to True, though it changes to true in the CheckCollision section!!
What i want is, whenever the LeftCollision is true, Update should stop, until it becomes false again!!
Below is the code for Header file and CPP file!!
The problem is with LeftCollision updation!! Why is the value not reflected in the Update if condition!!
#pragma once
#include <iostream>
#include <allegro5/allegro5.h>
#include <allegro5/allegro_primitives.h>
#include "Globals.h"
class GameObject
{
private :
int ID;
bool alive;
bool collidable;
protected :
float velX;
float velY;
int dirX;
int dirY;
int boundX;
int boundY;
int maxFrame;
int curFrame;
int frameCount;
int frameDelay;
int frameWidth;
int frameHeight;
int animationColumns;
int animationDirection;
ALLEGRO_BITMAP *image;
public :
float x;
float y;
bool LeftCollision;
bool pause;
GameObject();
void virtual Destroy();
void Init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY);
void virtual Update();
void virtual Render();
float GetX() {return x;}
float GetY() {return y;}
void SetX(float x) {GameObject ::x = x;}
void SetY(float y) {GameObject ::y = y;}
int GetBoundX() {return boundX;}
int GetBoundY() {return boundY;}
int GetID() {return ID;}
void SetID(int ID) {GameObject::ID = ID;}
bool GetAlive() {return alive;}
void SetAlive(bool alive) {GameObject :: alive = alive;}
bool GetCollidable() {return collidable;}
void SetCollidable(bool collidable) {GameObject :: collidable = collidable;}
bool CheckCollisions(GameObject *otherObject);
void virtual Collided(int objectID);
bool Collidable();
};
#include "GameObject.h"
GameObject :: GameObject()
{
x = 0;
y = 0;
velX = 0;
velY = 0;
dirX = 0;
dirY = 0;
boundX = 0;
boundY = 0;
LeftCollision = false;
maxFrame = 0;
curFrame = 0;
frameCount = 0;
frameDelay = 0;
frameWidth = 0;
frameHeight = 0;
animationColumns = 0;
animationDirection = 0;
image = NULL;
alive = true;
collidable = true;
}
void GameObject :: Destroy()
{
}
void GameObject :: Init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY)
{
GameObject :: x = x;
GameObject :: y = y;
GameObject :: velX = velX;
GameObject :: velY = velY;
GameObject :: dirX = dirX;
GameObject :: dirY = dirY;
GameObject :: boundX = boundX;
GameObject :: boundY = boundY;
}
void GameObject :: Update()
{
if(LeftCollision == false)
{
x += velX * dirX;
y += velY * dirY;
}
}
void GameObject :: Render()
{
}
bool GameObject :: CheckCollisions(GameObject *otherObject)
{
float oX = otherObject->GetX();
float oY = otherObject->GetY();
int obX = otherObject->GetBoundX();
int obY = otherObject->GetBoundY();
if( x + boundX > oX - obX &&
x - boundX < oX + obX &&
y + boundY > oY - obY &&
y - boundY < oY + obY && otherObject->GetID() == TRIANGLE)
{
return true;
}
else if(((oX < x + boundX + 14)&&(oX+ 40 >x - boundX))&&!((oY < y + boundY)&&(oY+40 > y - boundY))
&& otherObject->GetID() == SQUARE)
{
y = oY - boundX - 10;
//x = oX + 40;
return true;
}
else if((oX < x + boundX + 14) && (oX > x - boundX) && otherObject->GetID() == SQUARE)
{
LeftCollision = true;
return false;
}
else
{
return false;
LeftCollision = false;
}
}
void GameObject :: Collided(int objectID)
{
}
bool GameObject :: Collidable()
{
return alive && collidable;
}
Is this part of your problem - returning without setting the value
else
{
return false;
LeftCollision = false;
}
The only thing that jumps to mind is that you've got more than one object going around and you're not always using the one you expect. Try putting something like:
printf("here(%s:%d) this=%p\n", __FILE__, __LINE__, this);
at the start of each method to make sure that the this point is what you think it is. The problem may lie in the calling code that you haven't shown.