|
Error with random results |
Paladin
Member #6,645
December 2005
|
In my game, I have it detect when a square leaves the screen, and when this happens a variable is decreased by one which soon after this makes a new square. (In my main loop, when this variable is less than another, it makes a new square) What happens is that it only works about 4 times and the direction and even the amount of times it works is almost completely random(I have the function write to log what it does, and the log is almost always different), but it never always works. Also, sometimes the squares stop moving abruptly, and I can seem to figure it out.
That is all the code involving the squares, and I can't seem to figure this out. If you guys could help, that would be great. I wish I could break it down further, but I really have no clue why it would do this. |
X-G
Member #856
December 2000
|
A couple of things. 1) The square you remove from the list is most of the time not the one that left the screen -- |
Paladin
Member #6,645
December 2005
|
1) What do you mean? Are you saying that I have the wrong x and y values or something? 2) I have the rectfill in update so that it gets rid of the old square. The values change in that function, so if I didn't do it here, a drawn square would just remain where it's at while it keeps updating. (I know it's horrible, but I couldn't think of anything better) 3) I expect it to create 10 squares, then once one square leaves the screen, have that same square be replaced with new values. What happens is that they leave, and SOMETIMES the squares are replaced, but they often move about half-way across the screen, then abruptly stop, while SOMETIMES one of them moves right past it. It's very strange, but I'm not sure how to fix it. |
X-G
Member #856
December 2000
|
1) Regardless of which square exits the screen, it's the last square in the list that gets overwritten. 2) Redraw the entire screen every logic frame. 3) See #1 -- |
Paladin
Member #6,645
December 2005
|
1) I know that's the case, and I thought that might be the error. 2) Every logic frame? I'm relatively new to this as you might have been able to tell, so do you mean like every second or what? And how would you code this? 3) How would I avoid making it the last one every time? |
Elverion
Member #6,239
September 2005
|
As for the logic frame, I think he means you should do something like this... while( running ) { while( do_logic ) { update(); } draw(); } rather than doing logic and drawing at the same time. Look further into Allegro timers and stuff to find out more about that. There was a pretty informative post towards this a few days ago if i remember correctly. But, sorry, I don't know where your problem is. If you limit it down to a smaller portion of code where the problem might be, I'm sure many would be happy to review your code more closely. -- |
Paladin
Member #6,645
December 2005
|
Ok I've completely updated my source to make it "cleaner" and it managed to fix one problem, which where they just stopped in the middle of the screen, but now they don't always make a new square and it flickers like crazy(I used the update every logic second thing). I think I've also managed to locate the main problem which is here:
That detects when the square exits through the other end of the end, which is why I add the size of the square to the coordinates. Problem is I don't think it detects it correctly, so I've come to conclusion that this script is the problem. Here is my timer code if you are interested:
and like I said, that does work, but it flickers like crazy. Thanks for the help so far guys, but could you try to answer the problems above? Many thanks to you guys. |
Elverion
Member #6,239
September 2005
|
I think I might have possibly found your problem, but it's hard to tell without more code. For each direction, you are doing this: if(squares<i>.x == -squares<i>.size) You should check if each squares x is less than or equal to the left boundary rather than if it is equal to -squares.size. If the speed is always 1, then it should work, but even then, it's a bad way of doing it. As for screen flicker, need to see your update_screen() function before I can make any suggestions. Are you using a double-buffer or pageflipping? Are you vsyncing, or letting it be handled automatically(with pageflipping)? -- |
LordHolNapul
Member #3,619
June 2003
|
I've ot the same problem in my game 2 years ago... You must control the time. Windows is Multitasking and sometimes leave your application without refresh. That means that your update process will calculate an out of range X and Y position. What you must do is to control the Delta Time while an update , and the following update, overflow from ... 30 milliseconds. In that case you must not consider this update and reset your time to the previous (so X and Y are not incremented), because all the system is going slow... In my game I make appear a text with "CPU SLOW" message... when the system return to loop at normal speed, you can proceed with your normal X/Y updating. Try and let me know. |
Paladin
Member #6,645
December 2005
|
Elverion - I put that in, and the squares didn't stop coming! YES!!! But it still flickers, and I have no idea what I'm using. Roberto Mutti - To be completely honest with you, I have no idea what your talking about. You must remember I'm very new to C and Allegro, so I'm not very experienced. Here is my screen code now:
That's the code I used, thank god you guys figured it out. |
X-G
Member #856
December 2000
|
1) Don't clear the screen, 2) Where do you blit the buffer to screen? -- |
Paladin
Member #6,645
December 2005
|
1) Why not clear the screen? If I didn't, wouldn't the old squares still be there? 2) I use buffer with my main menu when I want to keep my mouse in front of the text. I used it in a really crappy method, but it works. |
gnolam
Member #2,030
March 2002
|
Quote: 1) Why not clear the screen? If I didn't, wouldn't the old squares still be there? No, because you'll blit your buffer over it. Quote: 2) I use buffer with my main menu when I want to keep my mouse in front of the text. I used it in a really crappy method, but it works. That... didn't answer X-G's question. -- |
Elverion
Member #6,239
September 2005
|
Brian, don't pay too much mind to the delta-time method...it's overly complicated and is a bit difficult for newer programmers to come to grasp with. Try using the fixed logic method instead until you think you are ready for delta-time. Now about the flickering, this is caused because of the vertical retrace. See, your monitor and your screen bitmap are not in sync with each other, which is why it's getting all flickery. To fix this, call vsync(); just before you blit your buffer to the screen. Also, in your clear_screen function, it looks like you can remove Since you should be drawing over top of the old screen with the new buffer, clearing the screen would be wasteful. -- |
Paladin
Member #6,645
December 2005
|
Oh, so you want me to blit a blank buffer on there, ok. I was blitting text to a buffer, then blitting the buffer to the screen, then the cursor to the screen that way when I "hovered" over the options, the mouse would stay on top. I didn't really intend on using it to cover everything up. To use vsync, I only need to type in EDIT: I added vsync, works real nice, now it seems to jump a little bit here and there and seems choppy, but the flickering definantely stopped. I am using a very, very flawed version of detecting collisions that I was hoping you guys could look over. What I did was I detected every single pixel on the edges of the cursor, and I was wondering if there was an easier way? Here's the code I've been using:
I hope this is my last question for awhile. Thanks everyone. |
Elverion
Member #6,239
September 2005
|
I think you should try page-flipping, it removed that jerkiness for me, and I've been using it since. Actually, I setup a class to attempt to use page-flipping, and if it cannot be setup (OS does not allow for multipul video bitmaps), then it will fall back on a simple memory double-buffer. It works pretty well, and I could give you the source code to it. It's been tested on Windows and Gentoo Linux. Simple square collisions can be done with "collision boxes". That is, you setup a rectangle, and simply check if something is within those points. Here's a chunk of code from a menu button in my game.
-- |
Paladin
Member #6,645
December 2005
|
Yeah, if you could show me how to use pageflipping, that would be great. And for the collisions, I'm surprised I didn't think of that before. Thanks a lot. |
Elverion
Member #6,239
September 2005
|
I'll attach my screensystem source, with a well commented example on how to use it, and the Dev-CPP project file. It's very simple; you almost can't screw it up. You can use it however you want, with no need to give me credit(as if it's all that difficult and deserved credit). Anyways, page-flipping is simply creating an array of 2 BITMAP *s, then you draw to page one, flip it to the screen, and while that one is being used as the screen bitmap, you draw to the other. You just keep switching between which one is getting drawn, and which one is getting drawn to. Setup: BITMAP *pages[2] = NULL; pages[0] = create_video_bitmap(w, h); pages[1] = create_video_bitmap(w, h); int page = 0; draw/flip: show_video_bitmap(pages[page]); page = (page+1) % 2; // this makes it 1 if it was 0, and 0 if it was 1
-- |
Paladin
Member #6,645
December 2005
|
I honestly looked through it, but I don't know how C++ works, so is there a way I can use this with C? |
Elverion
Member #6,239
September 2005
|
Nope, I guess not. Just use the chunks of code from my last post for creating your page-flipping mechanism, and drawing it. then, to draw onto your buffer, draw to pages[page]. I'm sure you can figure out how to do it. If you need more information, consult the allegro manual. -- |
Paladin
Member #6,645
December 2005
|
Ok, I guess I won't be learning anything unless I actually try it completely on my own. Thanks for all your help guys. |
|