|
This thread is locked; no one can reply to it. |
1
2
|
Snake Collision |
elamre
Member #13,750
November 2011
|
AH that was my problem, totally forgot about that. Also i tried to make them all 0, but that wouldnt work either. But i forgot that it FIRST substracts from the value, and only after that checks. Hence my problem. Ok the tail works great, my only problem is the collision checking, i use while(snake.Dead() == false){ the functions to run the game are here } return 0; where bool Snake::Dead(){ return dead } However i die instantly! EDIT: Still, even though this is done, why didnt my old code work? (other then the fact i used +1 on the wrong location) Kind regards, ELmar
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Well, for one thing, you didn't keep track of how many segments were currently in the body, you checked against all 100 positions in the array regardless of current size. I never saw any more of your older code, so I couldn't say why it didn't work. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
The rest is in my first post. EDIT 1if(player1.getX() == player2.getX){
2 if(player1.getY() == player2.getY())
3 Collision = true;
4 }
5
6int Snake::getX()
7{
8 return head.x;
9}
10//This was the easy part
11//But for the tail to check???
12 for (list<player2.segment>::iterator it = player2.body.begin() ; it != player2.body.end() ; ++it)
13{
14segment& s = *it;
15 if ((it->x == player1.x) && (it->y == player1.y)) {
16 Collision = true;}
17 }
I know the variables are private, but wouldnt it help if i made them public? that way i can easier check for a collision between tail and the head of another snake.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
bool CheckForSnakeCollision(const Snake& s1 , const Snake& s2) { // check head one against body two // check head two against body one } You don't need to make anything public or use a friend declaration either, but you could : class Snake { // ... friend CheckForSnakeCollision(const Snake& s1 , const Snake& s2); }; Or you can use getter variables that return const references : class Snake { // ... const list<segment>& Body() {return body;} const segment& Head() {return head;} };
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
hmm, the friend one i dont get really. so it grants a class the same permissions as another class? But why would i want that in this case? Also, isnt this very inefficient? checking for 2 lists if there are any collisions?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
elamre said: hmm, the friend one i dont get really. so it grants a class the same permissions as another class? But why would i want that in this case? You can either friend a function prototype which gives it access to private members of the class, or you can friend another class, doing the same thing. Quote:
The getter, Use Snake::Body() and Snake::Head() on opposing snakes, and iterate over each body segment, checking it against the head of the other snake. Quote: Also, isnt this very inefficient? checking for 2 lists if there are any collisions? Imagine your snakes are 1000 segments long, and you only check each time a snake moves, that is only (60/ticks_per_move)*1000 checks every second. If you moved on every frame, that would be 60000*2 checks, or 120000. Computers are capable of millions of calculations per second, so don't worry about things like that yet. Only look into them if they are actually causing you problems. If you're really worried, then use a vector instead of a list. That gives you direct access instead of indirect access, but it also makes adding and removing segments take longer (which is still probably the least of your worries). In short, don't worry about it. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
Haha, ok so the calculations should be just fine . const list<segment>& Body() {return body;} const segment& Head() {return head;} Now to retrieve the values of the following code: bool CheckForSnakeCollision(const Snake& s1 , const Snake& s2) { for (s1.list<segment>::iterator it = s1.body.begin() ; it != s1.body.end() ; ++it) { if ((it->x == s2.get_x) && (it->y == s2.get_y)) { return true;} } return false; } //where get_y and get_x: int Snake::get_x() { return head.x } //same goes for get_y, but then returning head.y But obviously this wont work. I cant seem to find a way to call the first part of the for loop (The iterator part) from another object. Should this be done by getters as well???
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
I forgot you need to make the getters 'const' : 1class Snake {
2 const list<segment>& Body() const {return body;}
3 const segment& Head() const {return head;}
4};
5
6bool SnakeVsSnake(const Snake& s1 , const Snake& s2) {
7 const list<segment>& s1body = s1.Body();
8 const list<segment>& s2body = s2.Body();
9 const segment& s1head = s1.Head();
10 const segment& s2head = s2.Head();
11 for (list<segment>::const_iterator it = s1body.begin() ; it != s1body.end() ; ++it) {
12 if ((it->x == s2head.x) && (it->y == s2head.y)) {
13 return true;// head two hit body one
14 }
15 }
16 for (list<segment>::const_iterator it = s2body.begin() ; it != s2body.end() ; ++it) {
17 if ((it->x == s1head.x) && (it->y == s1head.y)) {
18 return true;// head one hit body two
19 }
20 }
21 return false;
22}
And you'll still need to check each snake head vs its own body as well. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
Nice! void showCollision(const Snake& p1, const Snake& p2, const Snake& p3, const Snake& p4, Setup S1) { if(SnakeVsSnake(p1,p2)==1){ S1.DrawText("Player 2 hit player 1"); p2.stopMoving(); } else if(SnakeVsSnake(p1,p2)==2){ S1.DrawText("Player 1 hit player 2"); p1.stopMoving(); } }
Now this works fine! for 1 thing, i cant use p2/p1.stopMoving. This is because we are using a pointer here were we dont need that(right?) and thats also why it IS working for the S1.DrawText(const *char). void showCollision(const Snake& p1, Snake P1, const Snake& p2, Snake P2, const Snake& p3, Snake P3, const Snake& p4, Sake P4, Setup S1) { if(SnakeVsSnake(p1,p2)==1){ S1.DrawText("Player 2 hit player 1"); P2.stopMoving(); } else if(SnakeVsSnake(p1,p2)==2){ S1.DrawText("Player 1 hit player 2"); P1.stopMoving(); } }
However then we get a code with 9 arguments! where i think only 5 are needed(at max)is there a way to go from const& p1 to p1? main.cpp passing `const Snake' as `this' argument of `bool Snake::stopMoving()' discards qualifiers
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
If you need to modify a snake object (by using Snake::StopMoving()) then you should not be using a 'const Snake&', but a 'Snake&' only. That way you can still modify it. The warning came up because you are trying to call a non-const member function on a const Snake object. To simplify code, you can use an array (this example uses a modified SnakeVsSnake called SnakeHitSnake that only checks if snake 1 hit snake 2 but not the other way around) : void ShowCollision(....) { Snake& snakes[4] = {p1 , p2 , p3 , p4};// Or use a Snake* [4]. const char* text[4] = {"p1" , "p2" , "p3" , "p4"}; char* buf[1024]; for (unsigned int i = 0 ; i < 4 ; ++i) { for (unsigned int j = i + 1 ; j < 4 ; ++j) { if (SnakeHitSnake(snakes[i] , snakes[j])) { snakes[i].StopMoving(); sprintf(buf , "%s hit %s!" , text[i] , text[j]); } } } }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
Both of your methods arent working. Ive been looking around a bit, and cant find a proper way to do it. Snake* myObject[4]; int i; Snake * objectPointer; for (i = 0; i < 50; i++) { objectPointer = new Snake; }
But then ill have to copy all the values of the reference object, for a dummy object. and i think this is wasting resources a bit much. Also a total different question, is there a function to draw a string in allegro? Ive been searching a lot lately, but all i can come up with are 2 functions which use const * char. And i cant seem to convert a string to a const char (Or i have to use functions which require runtime librarys, in which case i cant port it to for example linux anymore) thx
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Define "aren't working". Why are you trying to make 50 new snakes? elamre said: So my guess is that i need to get rid of the constant in order to make my reference object functions work. However i do not know how to easily do this.
Edgar said: If you need to modify a snake object (by using Snake::StopMoving()) then you should not be using a 'const Snake&', but a 'Snake&' only. That way you can still modify it. The warning came up because you are trying to call a non-const member function on a const Snake object. Just don't use the 'const' keyword - in the member function declaration, or in the function prototype. elamre said: Also a total different question, is there a function to draw a string in allegro? Ive been searching a lot lately, but all i can come up with are 2 functions which use const * char. And i cant seem to convert a string to a const char (Or i have to use functions which require runtime librarys, in which case i cant port it to for example linux anymore)
See the manual : http://www.allegro.cc/manual/5/ To get a const char* from a std::string, use the string::c_str() method : string s = "Lalalala"; printf("%s\n" , s.c_str());
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
elamre
Member #13,750
November 2011
|
Yeah the 50 was a mistake :p. It was from an example i found. also not working = it cant convert const snake to snake*. Thats when using the following code: Snake *snakes[4] = {p1,p2,p3,p4};
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
elamre said: Also the s.c_str() is not working. Ive tried it before and googled it. But i cannot come up with a solution for that problem. And yes i did include <String> and even <CString> yet no succes!
#include <string> using std::string;// so you can refer to it as 'string', instead of 'std::string'.
Quote: also not working = it cant convert const snake to snake*. Thats when using the following code: Snake *snakes[4] = {p1,p2,p3,p4}; I told you, if you need to modify a Snake object, don't use a const reference or pointer. Also, you would have to use &p1, etc... to take the address of the objects in your example code. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
1
2
|