SeeSaw::SeeSaw(PlatformerScene* scenePtr, const float32 x, const float32 y) : PhysicsObject(x, y) { b2Vec2 vertices[3]; vertices[0].Set(16, 32); vertices[1].Set(0, 64); vertices[2].Set(64, 64); scenePtr->CreateTriangleGameObject(this, "res/textures/seesawrock.png", x, y, vertices, b2_staticBody); body->SetFixedRotation(true); GameObject* beam = new Log(scenePtr, x, y); // Store the joint so it can be destroyed. b2RevoluteJointDef jointDef; jointDef.bodyA = body; jointDef.bodyB = beam->GetBody(); jointDef.collideConnected = false; joint = scenePtr->CreateRevoluteJoint(jointDef); }
void Minimap::Render(IDirect3DDevice9* pd3dDevice) { if (!m_Ok) { // Only render if initialization succeeded. return; } // Find where the player is and which direction she is looking. GameObject* goPlayer = g_database.Find(g_objectIDPlayer); D3DXVECTOR3 const playerPos = goPlayer->GetBody().GetPos(); D3DXVECTOR3 const playerDir = goPlayer->GetBody().GetDir(); // Calculate the player position in minimap space. // World space has one unit per square of the map, and is 25x25. // Texture space is 0..1 for any texture. // Minimap space is just texture space in the minimap texture. // So we divide by 25 to world space to get minimap space. // // We also need to invert the Z coordinate because texture coordinates grow downwards. float const px = playerPos.x / float(m_WorldFile.GetWidth()); float const py = 1.0f - playerPos.z / float(m_WorldFile.GetHeight()); // Figure out the vectors that point forward and right in minimap space. // // From a position in the center of the minimap, we reach the edge with a displacement of 0.5, // so we'll divide by 2 (playerDir is a normalized vector, so the coordinates are [-1,1]). // Also, we don't want to show the entire minimap, so we divide another 2 on top of that. float const ZoomFactor = 4.0f; // Combined divisors. float const forwardX = playerDir.x / ZoomFactor; float const forwardY = -playerDir.z / ZoomFactor; float const rightX = -forwardY; // 90 degree rotation. float const rightY = forwardX; // For the NPC, position will be enough. GameObject* goNPC = g_database.FindByName("NPC1"); D3DXVECTOR3 const npcPos = goNPC->GetBody().GetPos(); // Find the dimensions of the viewport, // so we can render the minimap in the correct location. D3DVIEWPORT9 viewport = { 0 }; pd3dDevice->GetViewport(&viewport); float const minimapX1 = float(viewport.X) + float(viewport.Width) * ( 1.0f / 32.0f); float const minimapX2 = minimapX1 + float(viewport.Width) * ( 1.0f / 8.0f); float const minimapY2 = float(viewport.Y) + float(viewport.Height) * (23.0f / 24.0f); float const minimapY1 = minimapY2 - float(viewport.Height) * ( 1.0f / 6.0f); float const minimapCenterX = (minimapX1 + minimapX2) / 2.0f; float const minimapCenterY = (minimapY1 + minimapY2) / 2.0f; float const minimapHalfSizeX = (minimapX2 - minimapX1) / 2.0f; //float(viewport.Width) * ( 1.0f / 16.0f); float const minimapHalfSizeY = (minimapY2 - minimapY1) / 2.0f; //float(viewport.Height) * ( 1.0f / 12.0f); // Save all of D3D's state. m_pMinimapSaveStateBlock->Capture(); // Set some initial states that we'll want. pd3dDevice->SetVertexShader(NULL); pd3dDevice->SetPixelShader(NULL); pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); { // First, render the minimap itself. We'll use three simultaneous textures: // 0 = minimap // 1 = alpha mask // 2 = beautifying frame // // The pixel pipeline formula will be: // // color = lerp(minimap.rgb, frame.rgb, frame.a) // alpha = lerp(mask.a, 1, frame.a) pd3dDevice->SetTexture (0, m_pMinimapTexture); pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); pd3dDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); pd3dDevice->SetSamplerState (0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); pd3dDevice->SetTexture (1, m_pMinimapMask); pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); pd3dDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); pd3dDevice->SetTextureStageState(1, D3DTSS_RESULTARG, D3DTA_CURRENT); pd3dDevice->SetSamplerState (1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (1, D3DSAMP_MIPFILTER, D3DTEXF_POINT); pd3dDevice->SetTexture (2, m_pMinimapFrame); pd3dDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); pd3dDevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT); pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_BLENDTEXTUREALPHA); pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CONSTANT); pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_CURRENT); pd3dDevice->SetTextureStageState(2, D3DTSS_CONSTANT, 0xFFFFFFFF); // opaque white pd3dDevice->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 1); pd3dDevice->SetTextureStageState(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); pd3dDevice->SetTextureStageState(2, D3DTSS_RESULTARG, D3DTA_CURRENT); pd3dDevice->SetSamplerState (2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (2, D3DSAMP_MIPFILTER, D3DTEXF_POINT); pd3dDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); pd3dDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); // Set up the vertices. // We use two sets of texture coordinates: // // 0 = These coordinates rotate as the player rotates. Applied to the minimap. // 1 = Static coordinates to map a full texture. Applied to the mask and the frame. struct MinimapVertex { float x, y, z, rhw; float mapU, mapV; float maskU, maskV; enum { FVF = D3DFVF_XYZRHW | D3DFVF_TEX2 }; }; pd3dDevice->SetFVF(MinimapVertex::FVF); // Note that we can use the direction vector (forwardX, forwardY) // and the right vector to find the four texture coordinates directly: // // coord0 = p + forward - right // coord1 = p + forward + right // coord2 = p - forward - right // coord3 = p - forward + right // MinimapVertex const vertices[4] = { { minimapX1, minimapY1, 0, 1, px + forwardX - rightX, py + forwardY - rightY, 0, 0 }, { minimapX2, minimapY1, 0, 1, px + forwardX + rightX, py + forwardY + rightY, 1, 0 }, { minimapX1, minimapY2, 0, 1, px - forwardX - rightX, py - forwardY - rightY, 0, 1 }, { minimapX2, minimapY2, 0, 1, px - forwardX + rightX, py - forwardY + rightY, 1, 1 }, }; pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(vertices[0])); } // Now draw the players. { pd3dDevice->SetTexture (0, m_pMinimapMask); pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); pd3dDevice->SetTextureStageState(0, D3DTSS_RESULTARG, D3DTA_CURRENT); pd3dDevice->SetSamplerState (0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); pd3dDevice->SetSamplerState (0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); pd3dDevice->SetSamplerState (0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); struct DotVertex { float x, y, z, rhw; DWORD color; float u, v; enum { FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 }; }; pd3dDevice->SetFVF(DotVertex::FVF); // The player's position is fixed (the center of the minimap). DotVertex const vertices[4] = { { minimapCenterX-3, minimapCenterY-3, 0, 1, 0xFF00FF00, 0, 0 }, { minimapCenterX+3, minimapCenterY-3, 0, 1, 0xFF00FF00, 1, 0 }, { minimapCenterX-3, minimapCenterY+3, 0, 1, 0xFF00FF00, 0, 1 }, { minimapCenterX+3, minimapCenterY+3, 0, 1, 0xFF00FF00, 1, 1 }, }; pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(vertices[0])); // Now draw the NPC. // First calculate the minimap-space direction vector, and skip // if the NPC is outside of the minimap. float const dx = (npcPos.x - playerPos.x) * (ZoomFactor / float(m_WorldFile.GetWidth())); float const dy = -(npcPos.z - playerPos.z) * (ZoomFactor / float(m_WorldFile.GetHeight())); float const MinimapEffectiveRadius = 0.9f; // Because the mask doesn't reach the edge of the texture. if (sqrtf(dx*dx + dy*dy) < MinimapEffectiveRadius) { // Normally a 2D rotation matrix looks like this: // // ( cos(a) sin(a) ) // ( -sin(a) cos(a) ) // // But the right-direction vector already contains (cos(a), sin(a)) // So we use it directly (no need to calculate angles). // // We need to multiply ZoomFactor because the right vector has it divided (it's not normalized). float const x = (+ dx * rightX + dy * rightY) * ZoomFactor * minimapHalfSizeX; float const y = (- dx * rightY + dy * rightX) * ZoomFactor * minimapHalfSizeY; DotVertex const verticesNPC[4] = { { minimapCenterX-3 + x, minimapCenterY-3 + y, 0, 1, 0xFFFF0000, 0, 0 }, { minimapCenterX+3 + x, minimapCenterY-3 + y, 0, 1, 0xFFFF0000, 1, 0 }, { minimapCenterX-3 + x, minimapCenterY+3 + y, 0, 1, 0xFFFF0000, 0, 1 }, { minimapCenterX+3 + x, minimapCenterY+3 + y, 0, 1, 0xFFFF0000, 1, 1 }, }; pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verticesNPC, sizeof(verticesNPC[0])); } } m_pMinimapSaveStateBlock->Apply(); }
bool Example::States( State_Machine_Event event, MSG_Object * msg, int state, int substate ) { BeginStateMachine //Global message response section OnMsg( MSG_Reset ) ResetStateMachine(); OnMsg( MSG_MouseClick ) m_owner->GetMovement().SetTarget( msg->GetVector3Data() ); /////////////////////////////////////////////////////////////// DeclareState( STATE_Initialize ) OnEnter m_owner->GetMovement().SetIdleSpeed(); ChangeStateDelayed( 1.0f, STATE_Idle ); //m_owner->GetTiny().SetDiffuse(1.0f, 0.0f, 0.0f); //Color Tiny (Example) /////////////////////////////////////////////////////////////// DeclareState( STATE_PickPlayerToChase ) OnEnter m_owner->GetMovement().SetWalkSpeed(); m_curTarget = GetFarthestAgent(); if( m_curTarget == 0 ) { ChangeState( STATE_MoveToRandomTarget ); } SendMsgToStateMachineNow( MSG_SetTargetPosition ); OnMsg( MSG_SetTargetPosition ) GameObject* go = g_database.Find( m_curTarget ); if( go ) { D3DXVECTOR3 target = go->GetBody().GetPos(); m_owner->GetMovement().SetTarget( target ); } SendMsgToState( MSG_SetTargetPosition ); OnMsg( MSG_Arrived ) ChangeState( STATE_Idle ); /////////////////////////////////////////////////////////////// DeclareState( STATE_Idle ) OnEnter m_owner->GetMovement().SetIdleSpeed(); if( rand()%2 == 0 ) { ChangeStateDelayed( RandDelay( 1.0f, 2.0f ), STATE_MoveToRandomTarget ); } else { ChangeStateDelayed( RandDelay( 1.0f, 2.0f ), STATE_PickPlayerToChase ); } /////////////////////////////////////////////////////////////// DeclareState( STATE_MoveToRandomTarget ) OnEnter m_owner->GetMovement().SetJogSpeed(); D3DXVECTOR3 target( 0, 0, 0 ); target.x = (float) ( rand() % 256 ) / 256.f; target.z = (float) ( rand() % 256 ) / 256.f; m_owner->GetMovement().SetTarget( target ); OnMsg( MSG_Arrived ) ChangeState( STATE_Idle ); EndStateMachine }