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

Author Topic: Checking for a non-transparent spot at (x,y)  (Read 3022 times)

0 Members and 1 Guest are viewing this topic.

Adam Eldemire

  • Newbie
  • *
  • Posts: 5
    • View Profile
Checking for a non-transparent spot at (x,y)
« on: September 27, 2009, 09:06:17 pm »
I'm wondering if there's a way to check for a sprite at a certain position. I'm trying to make a game, and I need to check if the space the player is trying to moving to is clear. Is there any way I could do this, preferably based on pixels (so that transparent parts wouldn't register).

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Checking for a non-transparent spot at (x,y)
« Reply #1 on: September 27, 2009, 09:11:27 pm »
You can get the screen image to do that but performances will decrease a lot I think.

or you can manage all the objects' position otherwise than by pixels checking.
SFML / OS X developer

Adam Eldemire

  • Newbie
  • *
  • Posts: 5
    • View Profile
Checking for a non-transparent spot at (x,y)
« Reply #2 on: September 27, 2009, 09:20:23 pm »
I don't get what you mean by "manage all the object's positions otherwise than by pixel checking". Do you mean I should check each pixel of one object and see if it collides with another object? That doesn't seem very efficient.

What I've been is creating a dummy object at the proper position (where the player is trying to move to) and of the right size, hiding it, and checking if it collides with a wall or other solid object. Here's my code:
Code: [Select]

bool Application::ObjAtPos(float x, float y, float xsize, float ysize, std::vector<Object*> * vec)
{
//[TODO]: Make this more efficent
//Right now, it creates an object
Object checker(x,y,this,"data/empty.tga");
checker.SetVisible(false);
checker.GetSprite().Resize(xsize,ysize);
std::vector<Object*> * vec0 = this->GetCollides(&checker);
if(vec0)
{
vec = vec0;
return true;
}
else
{
return false;
}
}

std::vector<Object*> * Application::GetCollides(Object * obj)
{
unsigned int i = 0;
std::vector<Object*> * ObjectCollides = new std::vector<Object*>;
for(i = 0; i <= objmap.size(); i++) //placeholder [TESTCODE]
{
try
{
if(objmap.empty() == true)//is the whole thing empty?
{
if(objmap.at(i))//is it empty?
{
if(collision.PixelPerfectTest(objmap.at(i)->GetSprite(),obj->GetSprite()))
{
ObjectCollides->push_back(objmap.at(i));
}
continue;
}
else //objmap's done
{
break;
}
}
else //empty, also due to stupidty
{
break;
}
}
catch(...)
{
GetLogger()->AddToFile("Some error was encountered.");
}
}

return ObjectCollides;
}


And then to use it:
Code: [Select]

void Object::Update()
{
float etime = app->GetRenderWindow()->GetFrameTime();
//std::cout << etime << "\n";
bool shouldmove = true;
//[TODO]: Find something to put here
//this->GetSprite().SetX(GetSprite().GetPosition().x + this->velocity.x);//Update the x to the correct one
//this->GetSprite().SetY(GetSprite().GetPosition().y + this->velocity.y);//Same
//this->app->GetLogger()->AddToFile(this->GetSprite().GetPosition().x);
//this->app->GetLogger()->AddToFile(this->GetSprite().GetPosition().y);

//new moving code
std::vector<Object*> * c_v = new std::vector<Object*>;
if(app->ObjAtPos(spr.GetPosition().x + (this->velocity.x * etime),spr.GetPosition().y,spr.GetSize().x,spr.GetSize().y,c_v))
{
//std::cout << " Started checking for densities (x).\n";
for(int i = 0;i < c_v->size();i++)
{
if(c_v->at(i)->GetDensity() > this->GetDensity())
{
//denser than this object
shouldmove = false;
std::cout << "Holy shit, higher density!\n";
break;
}
}
if(shouldmove == true)
{
this->Object::spr.SetX(this->Object::spr.GetPosition().x + (this->velocity.x * etime));
}
else
{
}
}
else
{
this->Object::spr.SetX(this->Object::spr.GetPosition().x + (this->velocity.x * etime));
}
//and for the y axis
if(app->ObjAtPos(spr.GetPosition().x,spr.GetPosition().y + (this->velocity.y * etime),spr.GetSize().x,spr.GetSize().y,c_v))
{
//std::cout << " Started checking for densities (y).\n";
for(int i = 0;i < c_v->size();i++)
{
std::cout << c_v->at(i)->GetDensity() << "\n" ;
if(c_v->at(i)->GetDensity() > this->GetDensity())
{
//denser than this object
shouldmove = false;
break;
}
}
if(shouldmove == true)
{
this->Object::spr.SetY(this->Object::spr.GetPosition().y + (this->velocity.y * etime));
}
else
{
}
}
else
{
this->Object::spr.SetY(this->Object::spr.GetPosition().y + (this->velocity.y * etime));
}


//this->Object::spr.SetX(this->Object::spr.GetPosition().x + (this->velocity.x * etime));
//this->Object::spr.SetY(this->Object::spr.GetPosition().y + (this->velocity.y * etime));
OnCollide(); //Does second part of updating
}


If you need anything else, ask.[/code]

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Checking for a non-transparent spot at (x,y)
« Reply #3 on: September 27, 2009, 09:48:39 pm »
Quote from: "Adam Eldemire"
I don't get what you mean by "manage all the object's positions otherwise than by pixel checking". Do you mean I should check each pixel of one object and see if it collides with another object?
No no no. Not at all.
One solution could be having a vector of object, for each get its "rect" and check for a possible collide.

sorry, too sick/tired to read your code.
SFML / OS X developer

Adam Eldemire

  • Newbie
  • *
  • Posts: 5
    • View Profile
Checking for a non-transparent spot at (x,y)
« Reply #4 on: September 27, 2009, 09:56:37 pm »
That's essentially what I'm doing, using the Wiki collision code. However, it doesn't work at all: the 'player' goes straight through the wall.

nomonkeybusiness

  • Newbie
  • *
  • Posts: 11
    • View Profile
Checking for a non-transparent spot at (x,y)
« Reply #5 on: October 23, 2009, 12:31:52 am »
This seems like a really long updatecycle.
Try to narrow it down. Use boundingbox-testings to see if it is really necessary to do the pixelcollisiontesting at all. Here's what I would do with your code:

Code: [Select]
Object::Update()
{
     // Add the two vectors together
     m_vPosition += m_vVelocity;
     
     bool bCollided = CheckCollisionToTerrain();
     
     if(bCollided)
     {
           m_vPosition -= m_vVelocity;
     }

     // other necessary updates here
}