|
This thread is locked; no one can reply to it. |
1
2
|
Snake Collision |
elamre
Member #13,750
November 2011
|
Hello all, bool Snake::collision() { for(int i=0; i<100;i++){ if((x+1)==xPrevious[i] && y==yPrevious[i-1]){ return false; } } }
and my files Sliding text?
|
gnolam
Member #2,030
March 2002
|
-- |
elamre
Member #13,750
November 2011
|
Ok sorry! It is perfectly fine running. Not crashing nor problems with compiling. void Snake::moveRight() { if(!collision()){ if(x>610) x=10; toPrevious(); x+=10; } else textout_ex( screen, font, "Me gusta Collision Y", 320, 240, makecol(0, 0, 255), makecol(0, 0, 0)); } So it detects a collision even though there is none!
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
elamre said:
bool Snake::collision() { for(int i=0; i<100;i++){ if((x+1)==xPrevious[i] && y==yPrevious[i-1]){ return false; } } }
Think about what you are doing - you are checking if x plus one is the same as any of the last 100 x values and the current y is the same as the yPrevious value one before the current (i) yPrevious value. Does that make sense? Try storing your snake values in a std::list : 1struct segment {
2 int x;
3 int y;
4}
5
6class snake {
7private :
8 list<segment> body;
9 segment head;
10
11public :
12 void UpdateSnake() {
13 if (!body.empty() && !body.grow()) {
14 body.erase(body.begin());
15 }
16 body.push_back(head);
17 head.x += xdir;
18 head.y += ydir;
19 dead = CheckCollision();
20 }
21 bool CheckCollision() {
22 for (list<segment>::iterator it = body.begin() ; it != body.end() ; ++it) {
23 if ((it->x == head.x) && (it->y == head.y)) {return true;}
24 }
25 return false;
26 }
27
28};
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
|
Well to me it makes a lot of sense to be honest. if it wants to go up, it will check first if the above position is equal to one of the previous positions. thanks for your help until now . But im still a bit stuck with this problem.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
elamre said: Well to me it makes a lot of sense to be honest. if it wants to go up, it will check first if the above position is equal to one of the previous positions. But you're still only checking if it moves up, and you don't know if it has. And, you're not checking the right index for the previous Y value (You should use i, not i - 1). Quote:
And with your code, Thankx. But i have no clue how to use this, i have added it to my snake, but the list doesnt have a type, and when making it int it doesnt work. (Im unknown with lists). Also where to call for update snake? where does head.x and head.y reffer to? and the body.empty and body.grow are listfunctions i assume? That's okay, I'll walk you through it. A list is a C++ container template defined in the system header list and contained in the std namespace. This means to use it you will need to : #include <list> // include the header that defines list using std::list;// tell the compiler we will be using list to refer to std::list To use a template, you need to tell it what type it will be using. list<segment> body;// declares a list of segment objects named body To iterate over a list, you need to use a list<TYPE>::iterator. iterators are just an efficient way to move back and forth over the objects contained in the list (or more generally, container). 1
2// list iteration method one
3list<segment>::iterator it = body.begin();// The list::begin() method returns an iterator pointing to the beginning of the list. It may return the same value as list::end().
4while (it != body.end()) {
5 segment& s = *it;// iterators point to the elements stored in the list
6 printf("s.x = %i , s.y = %i\n" , s.x , s.y);
7 ++it;// move the iterator to point to the next element
8}
9
10// list iteration method two
11for (list<segment>::iterator it = body.begin() ; it != body.end() ; ++it) {
12 segment& s = *it;// using a reference allows us to modify the object stored in the list if we want to
13 printf("s.x = %i , s.y = %i\n" , s.x , s.y);
14}
For more information on the Standard Template Library containers (like list), take a look here : And I actually made a typo. body.grow() doesn't exist - it is not a member of the list class. What I meant was that if the snake will grow on this update, then you should not erase the tail of the snake (which is stored at the beginning of the list). So, something more like this : --growcounter; bool grow = (growcounter == 0); if (growcounter == 0) {growcounter = time_between_growth;} if (!body.empty() && !grow) { body.erase(body.begin()); } If you have any more questions or can't get it to work, post your errors here, and your questions too. 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
|
Im tying to implent the code(and having a hard time with it) But doesnt the segment structure have to be declared in the snake class aswell? or can i just declare it wherever i want? Edit:
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
The segment structure can be declared anywhere before a class or function that uses it. This means it can go in a separate header, or in the same header as the one for your snake class, before you declare it. Be specific with your problems. 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
|
// list iteration method one list<segment>::iterator it = body.begin();// The list::begin() method returns an iterator pointing to the beginning of the list. It may return the same value as list::end(). while (it != body.end()) { segment& s = *it;// iterators point to the elements stored in the list printf("s.x = %i , s.y = %i\n" , s.x , s.y); ++it;// move the iterator to point to the next element } // list iteration method two for (list<segment>::iterator it = body.begin() ; it != body.end() ; ++it) { segment& s = *it;// using a reference allows us to modify the object stored in the list if we want to printf("s.x = %i , s.y = %i\n" , s.x , s.y); } Im getting what this code is doing (only the printf function, u suppose this is like cout?) But have no clue where to use it. And your last piece of code (with the growcounter) i suppose this is my grow() function?
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
If you don't know what printf does, you need to get yourself a C/C++ reference guide to look at. This one might be okay : You'll want to iterate over the list when you check each segment in the body list against the head segment to find out if the snake ran over itself and died. 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 |
Thomas Fjellstrom
Member #476
June 2000
|
I'd just like to say that 4.9.9.2 IS allegro 5, just a WIP/Alpha version. And if you're having problems with the 5.0.x releases, don't hesitate to ask for help on the installation forum. -- |
elamre
Member #13,750
November 2011
|
@Thomas, OT, 1struct segment {
2 int x;
3 int y;
4 int growcounter;
5 void grow();
6
7 void segment::grow()
8 {
9 --growcounter;
10 bool grow = (growcounter == 0);
11 if (growcounter == 0) {growcounter = 5;}
12 if (!body.empty() && !grow) {
13 body.erase(body.begin());
14 }
15};
But still it says that class std::list<........> 'has no member named 'grow';
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You don't need a separate grow function, and the growth variables should be in your snake class, not your segment class. To combine the examples I gave would give you : void Snake::UpdateSnake() { --growcounter; bool grow = (growcounter == 0); if (growcounter == 0) {growcounter = time_between_growth;} if (!body.empty() && !grow) { body.erase(body.begin()); } body.push_back(head); head.x += xdir; head.y += ydir; dead = CheckCollision(); } growcounter and time_between_growth are both members of the snake class. 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
|
Ah oh ok, thx.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
xdir and ydir are the x and y directions, or velocities, which I assume are 1, or however wide and tall a square or segment is. Only call Snake::Update when you want your snake to move (ie, not on every frame). Better yet, rename Update to Move, and make a new Update function : void Snake::Update() { --update_counter; if (update_counter == 0) { Move(); update_counter = time_til_next_update; } }
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
|
I have no clue on how to do it anymore :s. So what what you gave me: void Snake::movePlayer() { clear_keybuf(); if (key[KEY_UP]) moveUp(); else if (key[KEY_DOWN]) moveDown(); else if (key[KEY_RIGHT])moveRight(); else if (key[KEY_LEFT])moveLeft(); Draw(); } Thanks for keeping so patient, and helping me so much! Much appreciated!
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
1void Snake::CheckInputs() {
2 if (key[KEY_RIGHT]) {
3 xdir = 1;// or however wide a square / segment is
4 ydir = 0;
5 }
6 if (key[KEY_LEFT]) {
7 xdir = -1;// or the reverse of above
8 ydir = 0;
9 }
10 if (key[KEY_UP]) {
11 xdir = 0;
12 ydir = -1;
13 }
14 if (key[KEY_DOWN]) {
15 xdir = 0;
16 ydir = 1;
17 }
18}
That way, the direction will be set until the next time someone presses a key. You don't have to move right away when they press a key. It's up to you though. If you want them to move whenever you press a key, just add in Move() to the if clauses there after setting the direction. while (!quit) { while (ticks < 1) {rest(1);} snake.CheckInputs(); snake.Update(); snake.Display(); }
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
|
Owh btw, how can i do the drawing for the tail? just by reading out all the segments? (so in a for loop, like i did for the array tail)
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Just iterate over them, like I showed you earlier. 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, its the same idea . head.x=x; head.y=y; So it draws the initial position of the head. But does not change when pressing a key! =/ my main (i know using rest is not very good, ill change that later on).
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Then there is something wrong with CheckInputs or Update. Post both of them as they are now. 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
|
1void Snake::Update() {
2 --update_counter;
3 if (update_counter == 0) {
4 Move();
5 update_counter = 10;
6 }
7}
8
9void Snake::CheckInputs() {
10clear_keybuf();
11 if (key[KEY_RIGHT]) {
12 xdir = 1;// or however wide a square / segment is
13 ydir = 0;
14 }
15 if (key[KEY_LEFT]) {
16 xdir = -1;// or the reverse of above
17 ydir = 0;
18 }
19 if (key[KEY_UP]) {
20 xdir = 0;
21 ydir = -1;
22 }
23 if (key[KEY_DOWN]) {
24 xdir = 0;
25 ydir = 1;
26 }
27}
It doesnt draw anything anymore now =/
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
elamre said: So it draws the initial position of the head. But does not change when pressing a key! =/
elamre said: It doesnt draw anything anymore now =/ So is it drawing or isn't it? Just post everything you have, in a zip file if necessary. 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
|
Here it is . I cant seem to attach the file :s.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
First problem - your Snake::Snake(int,int) constructor doesn't initialize all it's values. This means update_counter,xdir,ydir,growcounter may all be zero, but they aren't guaranteed to be. So when you hit these lines the counter variables subtract endlessly and are never equal to zero : 1void Snake::Update() {
2 --update_counter; 3 if (update_counter == 0) { 4 Move();
5 update_counter = 10;
6 }
7}
8
9void Snake::Move() {
10 --growcounter; 11 bool grow = (growcounter == 0); 12 if (growcounter == 0) { 13 growcounter = 5;
14 }
15 if (!body.empty() && !grow) {
16 body.erase(body.begin());
17 }
18 body.push_back(head);
19 head.x += xdir;
20 head.y += ydir;
21 //dead = CheckCollision();
22}
You still need to add in drawing the body to Snake::Draw 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 |
|
1
2
|