Thread: simple collision detection problems

  1. #1
    Registered User Mr_Jack's Avatar
    Join Date
    Oct 2003
    Posts
    63

    simple collision detection problems

    I'm coding a simple physics demo for the GBA. This is a 2D demo. One thing to know is that the GBA screen is 240x160 pixels. There is a struct called object that stores data for images that can be collided with. There is a struct called force that keeps track of the amount of force in the x direction and the amount of force in the y direction. Also there is a struct called special_obj that is for the edges of the screen and stuff in the background (if I had one). I don't think I'll really explain the GBA-specific stuff too much, but you should know that the WaitForVsync() function waits until the GBA is done drawing the current frame. Every object is moved each frame based on the values in it's force struct. So the function ApplyAllForce() loops through every object in the array of objects objs and applies force based on each object's force struct. In this demo, there is only one object. Now, the problem is that my collision detection system isn't working at all. I've used it before and it works perfectly. Hmm... I'm sure that's all you need to know. Here's my code:

    Code:
    #include "gba.h"
    #include "dispcnt.h"
    #include "keypad.h"
    #include "sprite.h"
    #include "dma.h"
    
    #include "box.raw.c"
    #include "box.pal.c"
    
    
    struct force
    {
    	s16 x, y;
    };
    
    struct object
    {
    	u8 n, x, y, h, w, m;
    	force v;
    	void move();
    };
    
    struct special_obj
    {
    	u8 x, y, h ,w;
    };
    
    
    inline void WaitForVsync();
    inline void CopyOAM();
    bool MoveOK(object *,s16,s16);
    inline void apply_force(force *,object *);
    inline void return_force(force *,object *);
    void TakeBoxInput();
    void ApplyAllForce();
    
    
    u8 vsyncs = 0;
    u16 keys_lastframe;
    #define OBJSLEN	1
    #define SPECIALSLEN 4
    object objs[OBJSLEN];
    special_obj specials[SPECIALSLEN];
    force gravity;
    force jump;
    
    
    void object::move()
    {
    	if (MoveOK(this, v.x, v.y))
    	{
    		x += v.x >> 4;
    		y += v.y >> 4;
    	}
    }
    
    inline void WaitForVsync()
    {
    	while((volatile u16)REG_VCOUNT != 160){}
    }
    
    inline void CopyOAM()
    {
    	REG_DM3SAD = (u32)sprites;
    	REG_DM3DAD = (u32)OAM;
    	REG_DM3CNT = 256 | DMA_ENABLE | DMA_TIMEING_IMMEDIATE | DMA_32;
    }
    
    bool objsMoveOK(object * client, s16 xmove, s16 ymove)
    {
    	u16 loop;
    	for (loop = 0; loop < OBJSLEN; loop++)
    	{
    		if (objs[loop].n != client->n)
    		{
    			if (client->x + xmove + client->w <= objs[loop].x)
    				continue;
    			if (client->x + xmove >= objs[loop].x + objs[loop].w)
    				continue;
    			if (client->y + ymove + client->h <= objs[loop].y)
    				continue;
    			if (client->y + ymove >= objs[loop].y + objs[loop].h)
    				continue;
    			
    			return false;
    		}
    	}
    	
    	return true;
    }
    
    bool specialsMoveOK(object * client, s16 xmove, s16 ymove)
    {
    	u16 loop;
    	for (loop = 0; loop < SPECIALSLEN; loop++)
    	{
    		if (client->x + xmove + client->w <= specials[loop].x)
    			continue;
    		if (client->x + xmove >= specials[loop].x + specials[loop].w)
    			continue;
    		if (client->y + ymove + client->h <= specials[loop].y)
    			continue;
    		if (client->y + ymove >= specials[loop].y + specials[loop].h)
    			continue;
    		
    		return false;
    	}
    	
    	return true;
    }
    
    bool MoveOK(object * client, s16 xmove, s16 ymove)
    {
    	if (!objsMoveOK(client, xmove, ymove))
    		return false;
    	if (!specialsMoveOK(client, xmove, ymove))
    		return false;
    	
    	return true;
    }
    
    inline void apply_force(force * v, object * obj)
    {
    	obj->v.x += v->x;
    	obj->v.y += v->y;
    }
    
    inline void return_force(force * v, object * obj)
    {
    	obj->v.x -= v->x;
    	obj->v.y -= v->y;
    }
    
    void TakeBoxInput()
    {
    	if ((!(*KEYS & KEY_A)) && (keys_lastframe & KEY_A) && (objs[0].y + objs[0].h == 159))
    		apply_force(&jump, &objs[0]);
    	if (!(*KEYS & KEY_LEFT))
    		objs[0].v.x -= 1;
    	if (!(*KEYS & KEY_RIGHT))
    		objs[0].v.x += 1;
    }
    
    void ApplyAllForce()
    {	
    	u16 loop;
    	for (loop = 0; loop < OBJSLEN; loop++)
    	{
    		apply_force(&gravity, &objs[loop]);
    		
    		if (objs[loop].y + objs[loop].h == 159)
    			return_force(&gravity, &objs[loop]);
    		
    		objs[loop].move();
    	}
    }
    
    int main()
    {
    	gravity.x = 0;
    	gravity.y = 1;
    	jump.x = 0;
    	jump.y = -20;
    	
    	u16 loop;
    	
    	for(loop = 0; loop < 128; loop++)
    	{
    		sprites[loop].attribute0 = 160;
    		sprites[loop].attribute1 = 240;
    	}
    	
    	REG_DISPCNT = MODE_1 | OBJ_ENABLE | OBJ_MAP_1D;
    	
    	REG_DM3SAD = (u32)box_Palette;
    	REG_DM3DAD = (u32)OBJPaletteMem;
    	REG_DM3CNT = 64 | DMA_ENABLE | DMA_TIMEING_IMMEDIATE | DMA_32;
    	
    	REG_DM3SAD = (u32)box_Bitmap;
    	REG_DM3DAD = (u32)&OAMData[0];
    	REG_DM3CNT = 64 | DMA_ENABLE | DMA_TIMEING_IMMEDIATE | DMA_32;
    	
    	//box
    	objs[0].x = 20;
    	objs[0].y = 140;
    	objs[0].h = 16;
    	objs[0].w = 16;
    	objs[0].m = 3;
    	objs[0].v.x = 0;
    	objs[0].v.y = 0;
    	sprites[0].attribute0 = COLOR_256 | SQUARE | objs[0].y;
    	sprites[0].attribute1 = SIZE_16 | objs[0].x;
    	sprites[0].attribute2 = 0;
    	
    	//ground
    	specials[0].x = 0;
    	specials[0].y = 160;
    	specials[0].h = 0;
    	specials[0].w = 240;
    	
    	//ceiling
    	specials[1].x = 0;
    	specials[1].y = 0;
    	specials[1].h = 0;
    	specials[1].w = 240;
    	
    	//left barrier
    	specials[2].x = 0;
    	specials[2].y = 0;
    	specials[2].h = 160;
    	specials[2].w = 0;
    	
    	//right barrier
    	specials[3].x = 240;
    	specials[3].y = 0;
    	specials[3].h = 160;
    	specials[3].w = 0;
    	
    	while (1)
    	{
    		sprites[0].attribute0 = COLOR_256 | SQUARE | objs[0].y;
    		sprites[0].attribute1 = SIZE_16 | objs[0].x;
    		
    		keys_lastframe = *KEYS;
    		WaitForVsync();
    		CopyOAM();
    		vsyncs++;
    		TakeBoxInput();
    		ApplyAllForce();
    	}
    	return 0;
    }
    
    Thanks for your help
    Last edited by Mr_Jack; 03-31-2004 at 06:14 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with AABB Collision Detection.
    By Shamino in forum Game Programming
    Replies: 10
    Last Post: 03-30-2009, 07:00 PM
  2. Collision Detection
    By cboard_member in forum Game Programming
    Replies: 2
    Last Post: 08-06-2005, 12:14 PM
  3. Programming Collision Detection
    By jverkoey in forum C++ Programming
    Replies: 3
    Last Post: 02-06-2003, 09:59 PM
  4. tile collision detection help needed...
    By werdy666 in forum Game Programming
    Replies: 0
    Last Post: 01-01-2003, 02:57 AM
  5. bounding box collision detection
    By DavidP in forum Game Programming
    Replies: 7
    Last Post: 07-07-2002, 11:43 PM