Blocking Element - Tetris like game using GDI+

wyrd

Well-known member
Joined
Aug 23, 2002
Messages
1,408
Location
California
Update:

- Down arrow makes falling shape fall faster (thanks for suggestion hog)
- A score + bonus is now displayed (thanks for suggestion hog)
- If you win, your time and score is now displayed.
- FPS bottleneck fixed, so game should run at approx. 50 fps (thanks pjv for help)
- Game text is now formatted.
- Fixed minor bug with fading blocks.
- Updated help file.


Some notes:

- This is not a Tetris clone. Its a Tetris style game. To learn how to play go to the Help menu. To start a game, go to File/New Game.
- The game is written in pure C# and GDI+. Nothing fancy was used (including no API).
- The game is complete.
- There are no known bugs (unless you want to include a minor FPS problem which is described below).
- I know the game isnt all that fun, but its my first game and I needed to complete it so I could learn.
- You can run the game by either compiling it or running the .exe under Bin/Release.
- If you find any bugs or have any improvement suggests, please let me know.
- Feel free to tell me what you think. You dont have to be nice, I have a pretty thick backbone. So if you think it sucks, say so.

Okay now that thats out of the way... I could use some help if anyone would like to help me out.

I have the game set to run at 50 fps, but it doesnt run at that speed on my 800mhz system (I get a solid 21-25 fps). I can set the game speed to just loop with no control and get 50 fps, but I dont want to do that since its important that everyone gets the same speed. If anyone would like to look at the code and possibly find out why (other then GDI+ overhead) itd be appreciated. Also, if anyone would like to tell me what FPS they get and their system specs itd help (to show FPS look under the debug menu).

Theres also the problem of my overall design. While designing the game on paper (class hierarchy and all that), it looked good. Unfortunately it started to fall apart near the end (as you can probably see just by looking at it). I could definitely use some help with my designing techniques.. maybe some dos and donts? Feel free to bash my current design and tell me whats wrong with it, I only learn by example.

Thanks.
 

Attachments

Last edited by a moderator:
Smooth.....very smooth :) I like it, only comments at first are; would be nice if the blocks move down faster when you press the down arrow, and to see a rolling score total. Apart from that....very smooth well done:)

Im currently doing the same learning thingy with a tetris clone type game. Ill post it when Im done.
 
Nice game (and code).

FPS problem is a tricky one.. tried changing it to:

C#:
			while (_mode != GameModes.End) {
				// Check if game needs update.
				if (Environment.TickCount > nextTime) {
					// ** BEGIN PJV ADDED **
					int beforeTime = Environment.TickCount;
					// ** END PJV ADDED **

					// Update game.
					_update();

					// Get next update time.
					//nextTime = (1000 / GameSpeed) + Environment.TickCount;

					// Check second update.
					if (Environment.TickCount > nextSecond) {
						// Increase elapsed time.
						_elapsedTime++;

						// Display fps.
						if (_fps) {
							_blockSurface.DisplayText = "FPS: " + fpsCount;
						}

						// Reset fps.
						fpsCount = 0;

						// Get next second.
						nextSecond = 1000 + Environment.TickCount;
					}

					// Update fps.
					fpsCount++;

					// Process game updates.
					Application.DoEvents();

					// ** BEGIN PJV ADDED **
					int frameTime = Environment.TickCount - beforeTime;
					nextTime = Environment.TickCount +
							   ( ( 500 / GameSpeed ) - frameTime );
					// ** END PJV ADDED **
				}
			}

..but for some reason I still need to do the "500/GameSpeed" instead of 1000 to get 50 fps. Weird.

The only thing I can think of to improve the design would be to make use of delegates in the update function (instead of the switch statement).

Pete
 
Last edited by a moderator:
Smooth.....very smooth I like it, only comments at first are; would be nice if the blocks move down faster when you press the down arrow, and to see a rolling score total. Apart from that....very smooth well done

Im currently doing the same learning thingy with a tetris clone type game. Ill post it when Im done.

Hmm.. I was going to add the down arrow but didnt for some reason. *ponders* Maybe I forgot. Ill add it.

.. cant wait to see your Tetris game. :)

I get 33 FPS on a P4 2.4 processor and 512 RAM.

Hmm.. seems like there isnt to much difference in speed.

..but for some reason I still need to do the "500/GameSpeed" instead of 1000 to get 50 fps. Weird.

The only thing I can think of to improve the design would be to make use of delegates in the update function (instead of the switch statement).

If you look up in the constants youll see a GameSpeed constant which is set to 50. Set it to 1000 and itll go as fast as possible. But that leads to uncontrolled speeds which I dont like.

There are lots of places for delegates.. but I read their performance was slow. I suppose I could give em a shot anyway to see just how much slow down they cause.
 
If you look up in the constants youll see a GameSpeed constant which is set to 50. Set it to 1000 and itll go as fast as possible. But that leads to uncontrolled speeds which I dont like.

Yes but when I use the slight alteration I posted above (and change to 500 / GameSpeed -- not changing GameSpeed itself) then I get a steady 50fps (which I assumed was what you wanted). The only question is why doesnt it work with 1000 instead of 500.

Pete
 
Ah, I see. Ill take a look. I would imagine changing the GameSpeed to 100 would have the same effect. *ponders* My math is screwy somewhere.

EDIT:
Okay I found a bottleneck (there are probably others). Looks like you were on the right track with this one.

All the calls to Environment.TickCount were majorly slowing the loop down. I went ahead and added a variable which is updated once a loop, then I just use that variable as the tick count for the loop. It increased the FPS on my machine by about 20. The FPS still dips by about 10 when there are a lot of blocks on the screen.. anyone have suggestions to improve that?

Ill post the updated code when Im done making other changes.
 
Last edited by a moderator:
There is something very unintuitive about the game play that Im not sure I can fully place. I do have a suggestion for improvement though.

Once a block is in the corner, its done for. Theres no way to get rid of it. And, of course, accidental maneuverings will sometimes cause more blocks to get next to it, in turn becoming indestructible. There should be some kind of mechanism to get rid of these blocks if they are unwanted. Perhaps a special block that destroys all surrounding blocks or something.

P4 2.6GHz Hyperthreaded with 512 MB DDR runs at very steady 33 FPS. Also takes up 50% of the processor. Im sorry I didnt bother looking at the code, but there probably needs to be some System.Threading.Thread.CurrentThread.Sleep() commands placed in a few places. I have a feeling the program eats up the processor just waiting for its turn to do something.

Can I do something? No... Ok... How about now? No... Ok... How about now? No... Ok... How about now? No... Ok... How about now? No... Ok... How about now? No... Ok... How about now? No... Ok...
 
Game updated with changes that were suggested (view original post for details + updated d/l). If anyone finds a bug in the new version please let me know. :)

reanjr:
There is something very unintuitive about the game play that Im not sure I can fully place. I do have a suggestion for improvement though.

Hmm.. yeah. Maybe now that the game keeps track of a score Ill allow the user to use up points to do special things (like click on a block to destroy it). Special blocks are good, but then that adds more random elements of luck into the game (another random element of luck wouldnt hurt at this point I suppose). Ill keep it under consideration, although Im not exactly sure how Id implement special blocks.

P4 2.6GHz Hyperthreaded with 512 MB DDR runs at very steady 33 FPS. Also takes up 50% of the processor. Im sorry I didnt bother looking at the code, but there probably needs to be some System.Threading.Thread.CurrentThread.Sleep() commands placed in a few places. I have a feeling the program eats up the processor just waiting for its turn to do something.

I responded to your previous post about my game loop.. but Ill respond here as well. System.Threading.Thread.CurrentThread.Sleep() does not exit. System.Threading.Thread.Sleep() however does, but it doesnt process messages from the form.. which makes it so the form freezes.

If you have any other suggestions Im all ears. In the mean time Ill continue to look over the game and see if I notice anything.
 
Huh... thats odd. In VB, CurrentThread.Sleep exists, but in C# it doesnt seem to.

Oh... if the app isnt already multithreaded, you should try to do that. Two or three threads (maybe one for user input/form, one for main game loop, and one for drawing) in conjunction with some ThreadPriority tweaking could increase performance greatly.

If youre not familiar with doing multithreaded development it can be a bit of a bear to grasp, but it is well worth it.

For instance, the actual game loop I imagine is mostly waiting on its frame incrementer (whatever tells it its time to do a new frame). If that had its own thread, it could be told to sleep for 10 milliseconds or before checking to see if its ready to do something (which I imagine takes far less than 10ms). And/or it could be set to a low thread priority, giving the Drawing loop more time to do its thing when it needs to.

Ive never done multithreaded development in C#, so Im not quite sure how to go about doing it, but judging from VB, its very clean, it just introduces some new complications. Oh, and System.Threading.Mutex is your friend (it took me a while to figure out that existed, meanwhile I was writing my own)
 
Ive only done threading for a school project (which was in Java). Ill look into it if I have some time.. especially since Im curious as to what kind of performance itll give.
 
hog:

Its at the top of the page?

Wyrd:

Cool.. all you need now is a funky background pic and a better help dialog -- something like several screens with pics/animation rather than just a textbox. With all that then it would look quite professional.

Pete
 
hog:
I replaced the original link at the top of the page with the updated copy.

pjv:
Any suggestions for the background?
 
Hmm.. now do you mean a background for the background or for the windows (the squares that display info) or for both?

I still have no idea what type of background to make, heh.
 
I got the game running at a steady 50 fps, regardless of how many blocks are on the screen (thanks to Hamburger1984 for the help). In general, using a TextureBrush w/ graphics.FillRectangle() instead of a Bitmap w/ graphics.DrawImage() increased the FPS by about 10. Amazing :eek:

Since I can no longer edit my post, I attached the updated game below (no real reason to d/l it unless you were having FPS difficulties with the last version).

Bad news about the background. Thanks to my absolutely cruddy design I cant add a background without taking a significant FPS hit or redesigning the whole game engine. I made some bad mistakes, but thats okay, its all a learning experience for the next game I make.

Thanks all for the help and ideas to improve the game. I think this is about all the work Im going to put into it unless someone finds a bug worth fixing. The game is complete and has a steady ~50 FPS. Its time to move on to the next game.
 

Attachments

Wryd, Im going for making a non rectangular window for my game. As my website is about pigs......obviuosly I have decided on a pig:)

I have attached the .exe file which shows it in full pig glory. Perhaps rather than put a bacground image on your form, why not funk the form itself up:):)

DOH......how do ya attach a zip file:confused:
 
Back
Top