class GridCell { int [] m_ShadowBits; int m_NumBits; boolean m_InSight; void Initialize() { m_NumBits = 0; m_ShadowBits = new int[BITS_PER_GRID_CELL]; int i; for( i = 0; i < BITS_PER_GRID_CELL; ++i ) { m_ShadowBits[i] = -1; } } void Clear() { m_NumBits = 0; int i; for( i = 0; i < BITS_PER_GRID_CELL; ++i ) { m_ShadowBits[i] = -1; } } boolean AddShadowBitToCell( int Index ) { int i; for( i = 0; i < BITS_PER_GRID_CELL; ++i ) { if( m_ShadowBits[i] == -1 || m_ShadowBits[i] == Index ) { if( m_ShadowBits[i] == -1 ) { ++m_NumBits; } m_ShadowBits[i] = Index; return true; } } return false; } void CalculateForcesOnEachBit() { int i, j; for( i = 0; i < BITS_PER_GRID_CELL; ++i ) { if( m_ShadowBits[i] == -1 ) { continue; } for( j = i + 1; j < BITS_PER_GRID_CELL; ++j ) { if( m_ShadowBits[j] == -1 ) { continue; } //compute distance squared Vector2D i_to_j = new Vector2D(); i_to_j.x = SHADOW_BITS[ m_ShadowBits[j] ].m_Position.x - SHADOW_BITS[ m_ShadowBits[i] ].m_Position.x; i_to_j.y = SHADOW_BITS[ m_ShadowBits[j] ].m_Position.y - SHADOW_BITS[ m_ShadowBits[i] ].m_Position.y; float distance = i_to_j.MagnitudeSquared(); if( distance < MAX_AFFECT_DIST ) { if( distance == 0.f ) { i_to_j.x = 1.f; } else { i_to_j.Normalize(); } float distRatio = (MAX_AFFECT_DIST - distance) / MAX_AFFECT_DIST; distRatio *= distRatio; float baseForce = 0.5f + (distRatio * 1.f); i_to_j.Multiply( baseForce ); SHADOW_BITS[ m_ShadowBits[i] ].AddToForces( -i_to_j.x, -i_to_j.y ); SHADOW_BITS[ m_ShadowBits[j] ].AddToForces( i_to_j.x, i_to_j.y ); } } } } }; class Grid { int m_ExtentX; int m_ExtentY; int m_NumCellsX; int m_NumCellsY; int m_NumCellsTotal; int m_CellWidth; int m_CellHeight; GridCell [] m_Cells; void Initialize() { m_ExtentX = SCREEN_WIDTH; m_ExtentY = SCREEN_HEIGHT; m_NumCellsX = 18; m_NumCellsY = 18; m_NumCellsTotal = m_NumCellsX * m_NumCellsY; m_CellWidth = m_ExtentX / m_NumCellsX; m_CellHeight = m_ExtentY / m_NumCellsY; m_Cells = new GridCell[m_NumCellsTotal]; int i; for( i = 0; i < m_NumCellsTotal; ++i ) { m_Cells[i] = new GridCell(); m_Cells[i].Initialize(); } //if( EDITOR_MODE == false ) { LoadShadowBits(); } } void LoadShadowBits() { //read in data byte [] data = new byte[NUM_SHADOW_BITS * 8 + 4]; data = loadBytes("level"); int parseIndex = 0; int x1 = data[parseIndex++]; if( x1 < 0 ) {x1 += 256;} int x2 = data[parseIndex++]; if( x2 < 0 ) {x2 += 256;} int x3 = data[parseIndex++]; if( x3 < 0 ) {x3 += 256;} int x4 = data[parseIndex++]; if( x4 < 0 ) {x4 += 256;} int numShadowBits = x1 + (x2<<8) + (x3<<16) + (x4<<24); int i; for( i = 0; i < numShadowBits; ++i ) { x1 = data[parseIndex++]; if( x1 < 0 ) {x1 += 256;} x2 = data[parseIndex++]; if( x2 < 0 ) {x2 += 256;} x3 = data[parseIndex++]; if( x3 < 0 ) {x3 += 256;} x4 = data[parseIndex++]; if( x4 < 0 ) {x4 += 256;} SHADOW_BITS[i].m_Position.x = (float)(x1 + (x2<<8) + (x3<<16) + (x4<<24)); x1 = data[parseIndex++]; if( x1 < 0 ) {x1 += 256;} x2 = data[parseIndex++]; if( x2 < 0 ) {x2 += 256;} x3 = data[parseIndex++]; if( x3 < 0 ) {x3 += 256;} x4 = data[parseIndex++]; if( x4 < 0 ) {x4 += 256;} SHADOW_BITS[i].m_Position.y = (float)(x1 + (x2<<8) + (x3<<16) + (x4<<24)); } } void SaveShadowBits() { //compose data byte [] data = new byte[NUM_SHADOW_BITS * 8 + 4]; data[0] = (byte)(NUM_SHADOW_BITS); data[1] = (byte)(NUM_SHADOW_BITS >> 8); data[2] = (byte)(NUM_SHADOW_BITS >> 16); data[3] = (byte)(NUM_SHADOW_BITS >> 24); int i = 0, currentIndex = 4; for( i = 0; i < NUM_SHADOW_BITS; ++i ) { //x data[currentIndex++] = (byte)((int)SHADOW_BITS[i].m_Position.x); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.x) >> 8); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.x) >> 16); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.x) >> 24); //y data[currentIndex++] = (byte)((int)SHADOW_BITS[i].m_Position.y); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.y) >> 8); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.y) >> 16); data[currentIndex++] = (byte)(((int)SHADOW_BITS[i].m_Position.y) >> 24); } //save out data saveBytes("level", data); } void Draw() { int i, j; for( i = 0; i < m_NumCellsX; ++i ) { for( j = 0; j < m_NumCellsY; ++j ) { /* switch( m_Cells[ j * m_NumCellsX + i ].m_NumBits ) { case 0: noFill(); break; case 1: fill(0, 0, 255); break; case 2: fill(0, 255, 0); break; case 3: fill(255, 0, 255); break; case 4: fill(0, 255, 255); break; } */ if( m_Cells[ j * m_NumCellsX + i ].m_InSight ) { fill(0,255,0); } else { noFill(); } stroke(255, 0, 0); rect( i * m_CellWidth, j * m_CellHeight, m_CellWidth, m_CellHeight ); m_Cells[j * m_NumCellsX + i].m_InSight = false; } } } void AddBitsToGrid() { int i; for( i = 0; i < m_NumCellsTotal; ++i ) { m_Cells[i].Clear(); } for( i = 0; i < NUM_SHADOW_BITS; ++i ) { int TLCellIndexX = (int)((SHADOW_BITS[i].m_Position.x - SHADOW_BITS[i].m_HalfWidth) / m_CellWidth); int TLCellIndexY = (int)((SHADOW_BITS[i].m_Position.y - SHADOW_BITS[i].m_HalfHeight) / m_CellWidth); TLCellIndexX = CapInt( TLCellIndexX, 0, m_NumCellsX - 1 ); TLCellIndexY = CapInt( TLCellIndexY, 0, m_NumCellsY - 1 ); int TLCellIndex = TLCellIndexY * m_NumCellsX + TLCellIndexX; int TRCellIndexX = (int)((SHADOW_BITS[i].m_Position.x + SHADOW_BITS[i].m_HalfWidth) / m_CellWidth); int TRCellIndexY = (int)((SHADOW_BITS[i].m_Position.y - SHADOW_BITS[i].m_HalfHeight) / m_CellWidth); TRCellIndexX = CapInt( TRCellIndexX, 0, m_NumCellsX - 1 ); TRCellIndexY = CapInt( TRCellIndexY, 0, m_NumCellsY - 1 ); int TRCellIndex = TRCellIndexY * m_NumCellsX + TRCellIndexX; int BLCellIndexX = (int)((SHADOW_BITS[i].m_Position.x - SHADOW_BITS[i].m_HalfWidth) / m_CellWidth); int BLCellIndexY = (int)((SHADOW_BITS[i].m_Position.y + SHADOW_BITS[i].m_HalfHeight) / m_CellWidth); BLCellIndexX = CapInt( BLCellIndexX, 0, m_NumCellsX - 1 ); BLCellIndexY = CapInt( BLCellIndexY, 0, m_NumCellsY - 1 ); int BLCellIndex = BLCellIndexY * m_NumCellsX + BLCellIndexX; int BRCellIndexX = (int)((SHADOW_BITS[i].m_Position.x + SHADOW_BITS[i].m_HalfWidth) / m_CellWidth); int BRCellIndexY = (int)((SHADOW_BITS[i].m_Position.y + SHADOW_BITS[i].m_HalfHeight) / m_CellWidth); BRCellIndexX = CapInt( BRCellIndexX, 0, m_NumCellsX - 1 ); BRCellIndexY = CapInt( BRCellIndexY, 0, m_NumCellsY - 1 ); int BRCellIndex = BRCellIndexY * m_NumCellsX + BRCellIndexX; m_Cells[TLCellIndex].AddShadowBitToCell( SHADOW_BITS[i].m_UniqueID ); m_Cells[TRCellIndex].AddShadowBitToCell( SHADOW_BITS[i].m_UniqueID ); m_Cells[BLCellIndex].AddShadowBitToCell( SHADOW_BITS[i].m_UniqueID ); m_Cells[BRCellIndex].AddShadowBitToCell( SHADOW_BITS[i].m_UniqueID ); } } void ComputeForcesOnBits() { int i, j; for( i = 0; i < m_NumCellsX; ++i ) { for( j = 0; j < m_NumCellsY; ++j ) { m_Cells[j * m_NumCellsX + i].CalculateForcesOnEachBit(); } } } };