CollideImage problem

BlitzMax Forums/BlitzMax Programming/CollideImage problem

AnthonyB(Posted 2010) [#1]
Hey there,

I have a very annoying problem with CollideImage().

I haven't really had the need to use it before, but I'm making a mario clone, for practice, and for a game like that, one important feature is pixel perfect collision code.

Now, I think I understand how to use CollideImage() and ResetCollisions(), and I get it working with test programs of a few tens of lines of code, but not with the actual game.

Just to make sure I understand these two functions correctly; I use ResetCollisions() at the start of the loop, cleaning all layers (which is what I want, since we move the camera, etc, most frames). Then I draw everything, and in the render loop, I also add the CollideImage() call for said tile / sprite, writing them to the first collision layer, and reading from all collision layers.

Psuedo code:



This works when I write a sample program, but when I put inside my game it doesn't.

My main loop looks like this:



The only real difference between my game and the sample program I wrote is that my game uses SetOrigin() to move the camera. But the same origin is always used when a call to CollideImage() is done, and when I render my frame. Also, to make sure SetOrigin() doesn't break CollideImage(), I tried adding an origin the same way, in the sample code.

No other methods or functions does a call to either ResetCollisions(), SetOrigin() or CollideImage() than those that should, and they do it like they do in the sample code.

Honestly, I really don't understand why this doesn't work. Does anyone have any ideas?

I could attach the project, but the project is kind of big, going on for a few thousand lines of code, and it's divided into 22 files, etc, so it would take a while just to get into the project, and therefore I won't do that unless someone specifically asks for it.

Any help at all will be greatly appreciated!

Regards,
Anthony


Xerra(Posted 2010) [#2]
Maybe I'm reading this wrong but I've been using ImagesCollide(...)
This is a function dropped straight out of something I've been tinkering with and it's a bit messy but you can probably work out how it works easilly enough.

	Function Collide() ' Check for bullet collision with an alien
		Local Sound:TChannel
		For Local Enemy:TEnemy = EachIn EnemyList
			For Local Shot:TPlayerShot = EachIn PlayerShotList
				If ImagesCollide(PlayerShotImage,Shot.X,Shot.Y,0,EnemyImage,Enemy.X,Enemy.Y,0)
					EnemyList.Remove(Enemy)
					PlayerShotList.Remove(Shot)
					Sound = PlaySound (EnemyDieSound) ' Enemy Die Sound
				EndIf
			Next
		Next 
	End Function
	 



AnthonyB(Posted 2010) [#3]
Xerra, that would work for enemies, but when the player collides with tiles, since there will most likely be at least 100 tiles per map. It will probably be very very slow if we go through all of these tiles each frame. And even if I would only check for collisions on the visible tiles (I actually only draw the visible tiles, so that shouldn't be a problem to accomplish), there is still a potential of there being about 1900 tiles on the screen at any given point of time (since all tiles are 16x16 in size, and the screen resolution is 800x600). Doing that 1900 times each frame will KILL the frame rate. So I need a collision layer instead, and it needs to be pixel perfect, so I cannot only use a tilebased collision layer.


Xerra(Posted 2010) [#4]
Yeah i kind of thought I waded in too quick with that response. In my example it's checking a max of 32 bad guys and potentialy seven shots. Time for some caffeine so I read a bit slower next time :)


Jesse(Posted 2010) [#5]
The only way I can help you is if I have the actual code and do some tests. Tf you want to email me your code, I can look at it and try to figure out what you are doing wrong. I don't guarantee anything as I don't have a lot of time to mess with it.


AnthonyB(Posted 2010) [#6]

I don't guarantee anything as I don't have a lot of time to mess with it.


Yeah, that's what I thought, so that's why I haven't attached it, since it's quite a big project.

The ImagesCollide() approach works for now. At least now I can test the game properly. But without a proper collision detection function, it won't work. I need sloped tiles, and thus I need pixel perfect collision detection.

I just thought of something though. I could use ImagesCollide() if I only check the 8 tiles that surround the player, at any given point in time. This would make it fast enough, since it would only need to check a maximum of 8 tiles for each player / enemy on the screen.

Would that be a very slow solution? Or could it work even on lowend computers? I have a quad core with 3.0 ghz on each core, so it's hard for me to determine how fast things are going, since I have no other computer to test it on at the moment.


Jesse(Posted 2010) [#7]
I just thought of something though. I could use ImagesCollide() if I only check the 8 tiles that surround the player, at any given point in time.

I would consider that a given. I doubt you would have to check all 8 tiles at a given time either. for example on a side scroler with gravity; when walking I would only check the one below, the one in front, and the one in front below in the direction of walk etc... also for imagesCollide the larger the tiles are the longer it takes to check sense I believe it does a per pixel sweep on on top of that you would have to do a movement sweep if your object moves more than one pixel at a time to make sure you don't go past the collision point.
I tried ImagesCollide with a shooter I was doing and when I checked collision for sprites about 128x128 and about 8 16x16 sprites, speed did take very noticeable hit on my 3 years old dual core 2ghz laptop with Intel Graphics.
to solve this problem some games use hardcoded behavior for certain tiles pertaining to slopes. there are tutorials in the internet that illustrate that(or at least there were. years sense I last searched this subject).

[edit]
here is one tutorial:
http://jnrdev.72dpiarmy.com/en/jnrdev2/


AnthonyB(Posted 2010) [#8]
@Jesse: Okay. Thanks for the answer! I will search for that. I thought they just came up with some nifty way of doing it automatically. Didn't know they actually did hardcode it.