Game Programming Practices

BlitzMax Forums/BlitzMax Beginners Area/Game Programming Practices

psychoullis(Posted 2010) [#1]
I play around with BM for fun and relaxation. Even though I like programming very much I know nothing about programming 'the right way'.

I was wondering if you know any books or websites about 2D game practices. For example, how do you structure all the objects in a game. Is there a parent object that all the rest extend from? Or not? What is the most efficient way to check for collisions?

Something like that. I found a couple of books but either they have very general programming concepts or they are extremely focused on one subjects. I am looking for something general and overall about 2D game programming.

thanks!


Czar Flavius(Posted 2010) [#2]
Make as an abstract type a gameobject with methods to draw and update. Store all your created objects in a big list (you can use the New method to ensure this). Iterate through the list updating the objects and drawing any that are on the screen. Extend from this your players, aliens, bullets etc. Have a Game type that contains this list and has methods to update the game.


psychoullis(Posted 2010) [#3]
Hey thanks!
This is the point where I am (sort of) :)

I have 2 extends (player and enemies). I have 1 player alive in the game and 10 enemies.

Let's not add any bullets for the moment. How would you check for collisions (efficiently)?
EDIT: I mean the method not the actual code... I created bounding boxes so that I can use the CollideRect command, and it works :)

Thanks again


Czar Flavius(Posted 2010) [#4]
It depends on the situation. There are some build in collision commands but I've never used them. You can just loop through every other object and check to see if the coordinates overlap, like this:
Function collides2:Int(size1, size2, location1:TVec2, location2:TVec2)
	Local size = Max(size1, size2)
	Return (location1.x + size >= location2.x - size ..
		And location1.x - size <= location2.x + size ..
		And location1.y + size >= location2.y - size ..
		And location1.y - size <= location2.y + size)
End Function


For only 11 objects it will be fast enough.


psychoullis(Posted 2010) [#5]
Ah maybe you missed my EDIT tag but thanks...

I read and learned how to detect the collision between 2 BBoxes.

I was just wondering what is the best way to do it in the game. It would be a waste to check every entity in the game with all the rest, since you will check all of them twice. So I probably need to do it progressively or something... I still haven't figured it out :)

Any suggestions?


abelian_grape(Posted 2010) [#6]
How many objects are going to be on screen at any given time? I would utilize the list that Czar mentioned so that you can determine what objects are currently being drawn on screen and only check those against each other. That way you're not checking collisions for things that aren't even visible, and chances are the number of objects on screen will not be enough so as to slow down your program when checking them against each other. At least if you have a sufficiently fast computer you should be all set. I will think more about this though, because it does seem superfluous to check everything against each other, and essentially double counting. There has to be a combinatorial way to solve this problem.

EDIT: Good point, Czar. In that case, it might be safe to check everything in the game if it currently "exists" regardless of whether or not it is being shown.

What I would then do is have an array of objects (not specific extensions so that way you could check a character against a tree, etc.) so that the objects in existence are organized into this array. Then check the first entry in the array against all other entries inductively. So check objects[0] against objects[1], objects[0] against objects[2], all the way to objects[0] against objects[num_objects - 1]. Then check the object at index 1 against all objects after it, so objects[1] against objects[2], objects[1] against objects[3], and so on. This will prevent double counting.

Some code, not sure if it runs:
Global gameObjects:TList = CreateList()

'Fill your list with your objects

Global num_objects:Int = CountList(gameObjects) 'This is the number of objects in existence

Global objects:TObject[] = New TObject[num_objects] 'The array provides indices that the List does not have, thus assuring that we will not double count since everything has a "definite place"

'Let's check some collisions!
Local i:Int = 0

If i < (num_objects - 1)
   For Local j:Int = (i + 1) To (num_objects - 1)
      objects[i].CheckCollisions(objects[j])
   Next
   
   i:+1
EndIf



So just to be sure you understand, we're letting i be the index of the base object starting at object at location 0 in our array, and then checking it against every other object in the For, Next loop (here I'm assuming your CheckCollisions method is called by the base object and takes as a parameter the object you are checking against). Once we've checked our base object against all other objects in the array sequentially, then we shift the index up so our base object is the object at index 1, and then sequentially check, until our base object is the last object in the list, in which case we don't need to check anything, hence the strict inequality in the If statement conditional.

abelian_grape


Czar Flavius(Posted 2010) [#7]
Well be careful only updating that which is visible, you don't want enemies elsewhere on the map going through walls etc. On any computer that wasn't around in the dinosaur age, don't worry about checking inefficiency with around 10 objects!


psychoullis(Posted 2010) [#8]
hahaha thanks guys... The number 10 I just used it for example...

I want to learn to program in such way that my program is scalable...


abelian_grape(Posted 2010) [#9]
Check my post edit psychoullis. I think it might be helpful. If not, it certainly helped me in my own programming, haha!

abelian_grape


Czar Flavius(Posted 2010) [#10]
Only scale as much as you need :P

I'm going to use a technique in my game - split the world into a number of zones, each 500x500 pixels (completely made up number, experiment for best result). Each zone contains a list of all objects in that zone. When you check for collisions, only check for them amongst the list of objects in its current zone (and also each adjacent zone, in case it is on the border). That will significantly speed things up - you won't waste time checking for something completely elsewhere on the map.


abelian_grape(Posted 2010) [#11]
That's a really neat idea Czar. I think I will attempt to implement a similar routine in my code.

abelian_grape


_Skully(Posted 2010) [#12]
Its called cellular division and I use the same technique in TileMax when the tile system is enabled. The tile size is the cell size and all Sprites that are linked to the tiles are collision checked that way.

Unlinked Sprites check against other unlinked Sprites the brute force way.

It works great... you can do this two ways...

1...
First pass through the objects places them in cells (array) based on dividing the x,y positions by the cell size then checks are conducted within an objects cell and to the adjacent cells...

2...
Cell positions are update as the object is updated.. pre-sorted then do the cell adjacent tests.