Your Announcements

Simple Game Done - Beta Testers needed – briandra2

briandra2
Member

Posts: 15
From: Brookfield, WI, USA
Registered: 06-28-2001
Yello all,
I finished a simple arcade game and if anyone has any time I would appreciate it if you would test it. This is the first game I've finished, so I guess this would be called the "beta stage" because it works on my computer but I don't know about anyone elses.

You can download it at:

http://mosesproductions.marhost.com/noah.zip

You can read about it at:

http://mosesproductions.marhost.com/

Please write back and tell me of any problems you have with it or anything that could be improved.

Thanks a ton,
briandra2

MeanManInOz
Member

Posts: 388
From: Hobart, Tasmania, Australia
Registered: 06-26-2001
OK then.

1/ You should hide the mouse cursor if it doesn't control anything. If you don't know how, I'd be happy to tell you.

2/ You should probably offer more than one life

3/ Sound would be nice

4/ 640 x 480 is probably the minimum resolution you'd want to aim for nowadays. Direct Draw can certainly handle it. This game looks clunky by modern standards, even as a free game, and all it really needs is to run in a higher resolution.

5/ banana is not spelled bananna ;0)

6/ People will probably flame you if you use your free games to promote redneck politicians. Worshipping God is a personal thing, when it was a national thing ( in Israel ) they blew it every time. Are you sure making people pray in schools will solve America's problems ? Marilyn Manson came from a very religious household, so it doesn't follow that putting someone in a religious setting will make them well behaved ( in fact it showed him the sort of people he could offend in a calculated way to make money with no talent ). And don't get me started on pro life. I assume this means no abortion clinics ? I am strongly anti abortion, but I'm also strongly against women who are raped having to raise their attackers child, and I am also against my child having to go to school with children who are maladjusted because they were unwanted and unloved. This point is probably too political, but I left it anyhow... I applaud your including links to pro creation websites, which I guess goes to show the line of distinction is the point where I agree with you ;0)But why no link to a site that tells people how and why to become a Christian ?

7/ You should get a copy of 3D Studio or similar - I use it for my 2D games to render my sprites, because I can't draw either ;0)

8/ How do you maintain 60 fps ? Why ? 30 fps is what you need for smooth animation - TV runs at 24. In any case, you should do all your calculations in OnIdle() and only draw in your drawing function ( not track anything ). Then you'll get maximum FPS naturally, and for this game 60 fps should be a doddle. I get about 50 on a game which has a higher resolution, sound, and tracks about 20 asteroids as well as shots, etc. ( Guess what game I cloned ;0). I assume it will drop when I find time to add enemy ships and missiles though.

I must say that your transition effects on the title ARE cool though...

All criticisms aside, it's not bad for a first effort. I'd recommend you buy 'Tricks of the Windows Game Programming Gurus' by Andre Lamothe, not because I think you're in desperate need of help, but because I'd say your skills are such that you'd get a lot out of it. The trick with programming is to take criticism as a chance to know what to learn next, and to keep trying to get better. At least, that's what I always do ;0)

MeanManInOz
Member

Posts: 388
From: Hobart, Tasmania, Australia
Registered: 06-26-2001
I've had a bit more of a play - I like the way the difficulty builds as you plau, and I see you can get extra lives ( although I don't like the 'die but keep going model you've used ), but my biggest criticism overal would be your collision detection. You should work on pixel perfect collision detection between the ship and the things it hits - it looks to me right now like you're using PtInRect() at the base of the shape. If you need help with doing it economically in a pixel perfect manner, I've done it and I'd be glad to dig up some code for you.
briandra2
Member

Posts: 15
From: Brookfield, WI, USA
Registered: 06-28-2001
Thank you meanmaninoz. Is there any way you can tell me more about this pixel-perfect collision detection? I'm very interested. Also, do you think it was wise for me to include that setup program with it? Or are computer users smart enough to run the game without icons these days? The reason I ask is that without the setup program the game is like ~33KB while with the setup program the game is ~600KB
briandra2
Member

Posts: 15
From: Brookfield, WI, USA
Registered: 06-28-2001
All right I updated the game a little. It's not worth downloading the game again, but I'll list them anyway.
- Corrected banana misspelling
- Went down to 30 FPS
- Hid cursor during actual game
- Got rid of Mr. Keyes

I'm going to work on putting the game in a higher resolution and stylize
the graphics now.

Thanks for the input

MeanManInOz
Member

Posts: 388
From: Hobart, Tasmania, Australia
Registered: 06-26-2001
OK, here it is. First of all, I'll mention I wrote this before GDI+ was released. If you don't know about GDI+ I've written several articles at www.codeproject.com. If I did this with GDI+, the upside would be it would be faster ( GetPixel is SLOW for GDI, but not so GDI+ ), downside is a DLL to distribute.

Obviously I know the rect of each item I draw, I need the dimensions to draw from the bitmap with all the sprites to the screen. So I step through my asteroids ( in your case rocks ) and check if the rect of the ship intersects any of them. This is how I quickly cull everything far away. If it['s a hit, then I do this:

bool CGame::OnCollision(int i, CRect rcShip, CRect rcAsteroid)
{
// Normalise the rects to each other ( I can't call normaliserect because I want them to stay right relative to each other
while (rcShip.top > 0 && rcAsteroid.top > 0)
{
rcShip.OffsetRect(CPoint(0,-1));
rcAsteroid.OffsetRect(CPoint(0,-1));
}

while (rcShip.left > 0 && rcAsteroid.left > 0)
{
rcShip.OffsetRect(CPoint(-1,0));
rcAsteroid.OffsetRect(CPoint(-1,0));
}

// This should probably be an ASSERT - just making sure that they are still in each others bounds
CRect rcTest;
if (!rcTest.IntersectRect(rcShip, rcAsteroid))
TRACE ("Intersect failed\r\n");

// This next bit pulls out a rect that corresponds to the ship I drew to the screen on the sprite bitmap.

RECT rc;

rc.top = ((m_iShipSprite/10) * 32)+576;
rc.left = ((m_iShipSprite%10) * 32);
rc.right = rc.left + 32;
rc.bottom = rc.top + 32;

if (m_bShield)
{
rc.bottom += 128;
rc.top += 128;
}

// m_pIShip is a DirectDraw surface. Fill it with black and draw the ship.

DDBLTFX dbltfx;
dbltfx.dwSize = sizeof(DDBLTFX);
dbltfx.dwFillColor = RGB(0,0,0);
m_pIShip->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&dbltfx);
m_pIShip->BltFast(rcShip.left,rcShip.top,m_pISprites,&rc, DDBLTFAST_WAIT);

// Get the rect of the Asteroid we drew.

switch (m_Items[i].Type)
{
case big:
rc.top = ((m_Items[i].iSprite/5) * 64);
rc.left = ((m_Items[i].iSprite%5) * 64);
rc.right = rc.left + 62;
rc.bottom = rc.top + 64;
break;
case mid:
rc.top = ((m_Items[i].iSprite/10) * 32) + 384;
rc.left = ((m_Items[i].iSprite%10) * 32);
rc.right = rc.left + 32;
rc.bottom = rc.top + 32;
break;
case sml:
rc.top = ((m_Items[i].iSprite/20) * 16) + 512;
rc.left = ((m_Items[i].iSprite%20) * 16);
rc.right = rc.left + 16;
rc.bottom = rc.top + 16;
break;
}

// Do the same. m_pIShip and m_pIAsteroid stay in memory because it is faster not to constantly create and destroy them and they are very small so it doesn't matter.

m_pIAsteroid->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&dbltfx);
m_pIAsteroid->BltFast(rcAsteroid.left,rcAsteroid.top,m_pISprites,&rc,DDBLTFAST_WAIT);

// Now we get the ships in to device contexts

HDC hdcShip;
m_pIShip->GetDC(&hdcShip);
CDC dcShip;
dcShip.Attach(hdcShip);

HDC hdcAsteroid;
m_pIAsteroid->GetDC(&hdcAsteroid);
CDC dcAsteroid;
dcAsteroid.Attach(hdcAsteroid);

// And steo through our test area to see if there is a spot that is not black on both bitmaps

for ( int x = rcTest.left; x<=rcTest.right; x++)
for ( int y = rcTest.top;y<=rcTest.bottom; y++)
if (dcShip.GetPixel(x,y) != RGB(0,0,0) &&
dcAsteroid.GetPixel(x,y) != RGB(0,0,0))
{
dcAsteroid.Detach();
m_pIAsteroid->ReleaseDC(hdcAsteroid);
dcShip.Detach();
m_pIShip->ReleaseDC(hdcShip);
return true;
}

dcAsteroid.Detach();
m_pIAsteroid->ReleaseDC(hdcAsteroid);
dcShip.Detach();
m_pIShip->ReleaseDC(hdcShip);
return false;
}

If we return true, we hit an asteroid. This method uses simple math to cull anything that doesn't bear investigation and only compares the areas of the two rects that intersected. This usually means we check a very small area indeed.

As for FPS, I use timeGettime to track time ellapsed and use that value as a factor in moving everything, calculating collisions, etc. and then I just draw in my draw function. If you're not doing anything in OnIdle then I suggest you move your engine to a system that does. You'll be amazed how many FPS you get, without having to clamp anything.

Oh, I should mention that I found your mouse cursor confusing - the hot spot is not logical to me.

Finally, do you use DirectInput ? If you do, it would be easy and cool to add joystick and force feedback support. Of course you need a FF joystick to test it. ( I borrowed a friends - FF is cool. )

I hope that helps. I admit I've not worked on this game in at least six months, I keep meaning to get back to it, but I'm currently distracted by ATL ( there is always something.....).

Phillip Martin
Member

Posts: 56
From: Yeppoon, QLD, Australia
Registered: 01-31-2001
Not too bad for your first attempt! Well done!

Do have a few points though:

- I didn't recognise the hammers at first. I thought they were rocks! I also didn't know to shoot them until I found out by accident.

- Sometimes items would appear to far down the screen where I couldn't get them.

- Sometimes fruit would appear under rocks, making it impossible to get.

- The tidal wave was neat

- In the main menu, when the boat follows the mouse cursor, the boat is drawn twice when the boat comes to rest. Looks very strange.

- You could make the clouds float up and down a bit

- Could make the rocks, fruit and hammers, get moved by the tidal wave as well.

- All in all, pretty neat. I had a bit of fun playing too.


And yep, as mean man said, the collision detection needs some work. He explained one method pretty well, so I wont muddy the waters and offer something different

Wtih what mean man said, using the amount of time between update to determine how much to move everything. It is a good method, and how I structure whatever game I write. But with a game as simple as this, it might not be worth the effort to do that. But I think you should at least look into it, and give it a whirl, it is a very important thing to learn for future work that you would do. Making the screen update with the world, at least however many milliseconds apart should be sufficient for this little game.

And yes, the mouse cursor is a bit odd. Using an achor is pretty, but it is counter intuitive. Perhaps you could use an arrow, but made out of wood or something?

On the whole though, good effort.

Phillip Martin

briandra2
Member

Posts: 15
From: Brookfield, WI, USA
Registered: 06-28-2001
Thank you for the code meanman. I don't know why you call yourself mean man because you've been very helpful to me! Also thanks for the input Philip. Anything you have to say is very helpful to me since I'm quite new to game devolpment. Updating the world by the seconds that go by sounds a little confusing, but I'll look into it. Any tutorials that you know on it would help me a lot.

Thanks

MeanManInOz
Member

Posts: 388
From: Hobart, Tasmania, Australia
Registered: 06-26-2001
quote:
Thank you for the code meanman. I don't know why you call yourself mean man because you've been very helpful to me!

You're welcome. MeanManInOz is a long story, but the short version is that it's my IRC nick.

quote:
Also thanks for the input Philip. Anything you have to say is very helpful to me since I'm quite new to game devolpment. Updating the world by the seconds that go by sounds a little confusing, but I'll look into it. Any tutorials that you know on it would help me a lot.

I'll post some code on this for you when I get home tonight.

Phillip Martin
Member

Posts: 56
From: Yeppoon, QLD, Australia
Registered: 01-31-2001
About the updating the world by seconds part. Here is a little bit of information about it, no code, just some backgronud that will hopefully preface MMIO's (Mean Man In Oz - I'm on a computer, I have to use anagrams right? ) code.

Lets say that we have a boat slowly moving at 2 metres every second. This is written as 1 m/s. That turns out to be 7.2 km's per hour, or about 5 or so miles per hour.

So our little boat is moving to the right at 7.2 m/s. Now when we update our world, we measure how long it was since the last update. For arguments sake, lets say it was 0.01 of a second. If it takes that long for each update, that means we have 100 frames per second (1 second divided by 0.01 seconds gives 100 frames).

So now we have has 0.01 of a second gone by, so we calculate how much the boat should have moved. so we do:

Displacement = Speed * time
Displacement = 7.2 m/s * 0.01 s
Displacement = 0.072 metres.

Which isn't very far. But we update our boats position by 0.072 metres.

Now when we draw it on the screen, we could say 1 pixels is 1 metre. So if we are travelling at 7.2 metres per second, we would cover 7.2 pixels every second, or we would see the boat move one pixel every tenth of a second or so. This means that even if the screen only update 5 times per second, the boat would still move 7.2 pixels on the screen in one second. It doesn't matter how fast the screen updates, everything will still move at the proper speed.

A tiny bit of almost c code to maybe clarify things a bit.


lastTime = 0;
while (gameRunning) {
// get the current time in milliseconds
currentTime = getSystemTime();
timeElapsed = (currentTime - lastTime) / 1000;

boat.x = boat.x + boat.x_speed * timeElapsed;

updateTheScreen();

lastTime = currentTime;
}

Phil

[This message has been edited by Phillip Martin (edited July 16, 2001).]

[This message has been edited by Phillip Martin (edited July 16, 2001).]

MeanManInOz
Member

Posts: 388
From: Hobart, Tasmania, Australia
Registered: 06-26-2001
Thanks Phillip - I forgot and this is exactly the sort of example I was going to give. The point is that processing in OnIdle means you don't know how often it will be called, but the result is working the same speed on every computer, just the frame rate will increase with processor speed and graphics resources.
Phillip Martin
Member

Posts: 56
From: Yeppoon, QLD, Australia
Registered: 01-31-2001
Not a problem at all : ) Glad to finally be of some help to someone.

Hope it helped you out briandra!

Phil

briandra2
Member

Posts: 15
From: Brookfield, WI, USA
Registered: 06-28-2001
Thanks Phil and meanman. I'm getting a little busier in my life, so I'm not working on the game as much. I'll tell you when I update it.