void CSceneMgr::Update( void ) { CBullet* pBullet = NULL; FireParameter* pFirePar = NULL; CGraphicsEngine* pEngine = NULL; pEngine = CGraphicsEngine::GetInstance(); if(pEngine->m_pDXInput->ReadKeyboard()){ if(pEngine->m_pDXInput->IsKeyPressed(DIK_UP)){ pEngine->ChangeCameraPosition(0,-1,0); } if(pEngine->m_pDXInput->IsKeyPressed(DIK_DOWN)){ pEngine->ChangeCameraPosition(0,1,0); } if(pEngine->m_pDXInput->IsKeyPressed(DIK_LEFT)){ pEngine->ChangeCameraPosition(0,0,-1); } if(pEngine->m_pDXInput->IsKeyPressed(DIK_RIGHT)){ pEngine->ChangeCameraPosition(0,0,1); } } m_pTank->Updata(); CMessageMgr::Message msgGet; while(CMessageMgr::GetInstance()->GetMessage(CMessageMgr::MSG_FIRE, &msgGet)) { pFirePar = (FireParameter*)msgGet.dwParameterA; pBullet = new CBullet(pFirePar->vPosition, pFirePar->vDirection, pFirePar->fAngle); m_BulletList.push_back(pBullet); delete pFirePar; } BulletList::iterator itDelete; for (BulletList::iterator it = m_BulletList.begin(); it != m_BulletList.end();) { pBullet = *it; pBullet->Update(); if (pBullet->IsDead()) { itDelete = it; ++it; delete pBullet; m_BulletList.erase(itDelete); } else ++it; } }
CBeak::CBeak(int objID, int typeID, double posX, double posY, int width, int height, double posXCollide, double posYCollide, int widthCollide, int heightCollide, bool _isLeft) { m_Id = objID; m_Type = BEAK; m_Status = BeakWait; m_IsLife = true; m_TimeSpent = m_TimeShot = 0; m_CurrentBullet = 0; m_isTurnLeft = _isLeft; m_Sprite = new CSprite(CResourceManager::GetInstance()->GetSprite(IMAGE_ENEMIES), D3DXVECTOR2(180, 267) , 4, 1, D3DXVECTOR2(20, 250), D3DXVECTOR2(0, 0), D3DXVECTOR2(30,0)); m_Size = D3DXVECTOR2(m_Sprite->GetWidthRectSprite(), m_Sprite->GetHeightRectSprite()); m_pos = D3DXVECTOR3(posX - m_Size.x/2, posY + m_Size.y/2, DEPTH_MOTION); m_posOrg = m_pos; m_rangeItem = 3; UpdateRect(); #pragma region create list bullet int vx = -V_BULLET; int vy = 0; int dir = _isLeft ? 1 : -1; for (int i = 0; i < NUM_BULLET; i++) { CBullet *bullet = new CBullet(D3DXVECTOR3(m_pos.x + m_Size.x/2 - dir * m_Size.x/2, m_pos.y - m_Size.y/2, m_pos.z)); switch (i) { case 0: vx = -V_BULLET * dir; vy = V_BULLET * dir; break; case 1: vx = -V_BULLET * 1.7 * dir; vy = V_BULLET*0.3 * dir; break; case 2: vx = -V_BULLET*1.7 *dir; vy = -V_BULLET*0.3 *dir; break; case 3: vx = -V_BULLET *dir; vy = -V_BULLET *dir; break; default: break; } bullet->SetVelloc(D3DXVECTOR2(vx, vy)); m_ListBullet[i] = bullet; } #pragma endregion }
//------------------------------------------------------------------------------ // 生成 //------------------------------------------------------------------------------ // 引数 // pos : 位置 // size : サイズ // rot : 回転 // color : 色 // 戻り値 // CBullet : 生成した弾のポインタ //------------------------------------------------------------------------------ CBullet* CBullet::Create(const VECTOR3& pos,const VECTOR2& size,const VECTOR3& rot,const COLOR& color) { CBullet* Scene = new CBullet(); Scene->_Pos = pos; Scene->_Rot = rot; Scene->_Size = size; Scene->_Color = color; Scene->Init(); return Scene; }
CBullet* CBullet::create() { CBullet* bullet = new CBullet(); if (bullet->initWithFile("bullet.png")) { bullet->autorelease(); bullet->Init(); return bullet; } CC_SAFE_DELETE(bullet); return NULL; }
/* * the cannon fires a plasma bullet if its ready * * @author Cameron MacIntosh */ void CTower::Shoot() { if(m_fPlasmaCoolDown == 0) { m_fPlasmaCoolDown = m_fCooldownLength; CBullet* pBullet = new CBullet; pBullet->Initialise(m_vec3Position + m_vec3Up * 1.0f + m_vec3ShootDir * 0.7f, this, m_vec3ShootDir, m_vec3ShootRight); pBullet->SetFace(m_eFace); pBullet->SetMoveSpeed(24.0f); pBullet->SetDamage(12.0f); m_listBullets.push_back(pBullet); } }
void CObject::CheckHitRect(CBullet &bullet, CBoss &boss) { for(int i = 0;i < BULLET_MAX;i++) { if(bullet.Flag[i]) { if(boss.IsExist && boss.counter > 200) { if(HitCheck(bullet.HitRect[i], boss.HitRect) ) { bullet.Flag[i] = FALSE; bullet.IsRefrect[i] = FALSE; bullet.SetPosition(i); boss.CalcDamage(bullet.Attack, boss.Defence); AddScore(boss.Score); } } } } }
void CObject::CheckHitRect(CBullet &bullet, CEnemy &enemy) { for(int i = 0;i < BULLET_MAX;i++) { if(bullet.Flag[i]) { if(enemy.IsExist) { if(HitCheck(bullet.HitRect[i], enemy.HitRect) ) { bullet.Flag[i] = FALSE; bullet.IsRefrect[i] = FALSE; bullet.SetPosition(i); AddScore(enemy.Score); enemy.CalcDamage(bullet.Attack, enemy.Defence); Se[SE_REFRECT].PlaySoundA(); } } } enemy.Dead(); } }
void keyboard(unsigned char key, int x, int y) { if (key == 'q') { tank1.RotateBarrel(-5); } else if (key == 'e') { tank1.RotateBarrel(5); } else if (key == 'a') { tank1.ChangeBulletPower(1); std::cout << "Bullet power: " << tank1.GetBulletPower() << std::endl; } else if (key == 'd') { tank1.ChangeBulletPower(-1); std::cout << "Bullet power: " << tank1.GetBulletPower() << std::endl; } else if (key == 'z') { bullet.Fire( tank1.GetEndOfBarrelPosition(), tank1.GetBulletPower(), tank1.GetBarrelAngle() ); } }
CBeak::CBeak(int _id, D3DXVECTOR3 _pos, bool _isLeft) { m_Id = _id; m_Type = BEAK; m_Sprite = new CSprite(CResourceManager::GetInstance()->GetSprite(IMAGE_ENEMIES), D3DXVECTOR2(360, 455) , 4, 1, D3DXVECTOR2(40,420), D3DXVECTOR2(0, 0), D3DXVECTOR2(50,0)); m_pos = _pos; m_accel = D3DXVECTOR2(0,0); m_isTurnLeft = _isLeft; m_Status = BeakWait; m_IsLife = true; m_TimeSpent = m_TimeShot = 0; m_CurrentBullet = 0; m_Size = D3DXVECTOR2(m_Sprite->GetWidthRectSprite(), m_Sprite->GetHeightRectSprite()); UpdateRect(); #pragma region create list bullet int vx = -V_BULLET; int vy = 0; int dir = _isLeft ? 1 : -1; for (int i = 0; i < NUM_BULLET; i++) { CBullet *bullet = new CBullet(D3DXVECTOR3(_pos.x + m_Size.x/2 - 10, _pos.y - m_Size.y/2 + 10, _pos.z)); switch (i % (NUM_BULLET/2)) { case 0: vx = -V_BULLET * dir; vy = V_BULLET * dir; break; case 1: vx = -V_BULLET * dir; vy = 0; break; case 2: vx = -V_BULLET *dir; vy = -V_BULLET *dir; break; default: break; } bullet->SetVelloc(D3DXVECTOR2(vx, vy)); m_ListBullet[i] = bullet; } #pragma endregion }
void CSWeapon::OnCollision(float deltaTime, std::vector<CGameObject*>* listObjectCollision) { #pragma region XU_LY_VA_CHAM float normalX = 0; float normalY = 0; float moveX = 0.0f; float moveY = 0.0f; float timeCollision; for (std::vector<CBullet*>::iterator it = CPoolingObject::GetInstance()->m_listBulletOfObject.begin(); it != CPoolingObject::GetInstance()->m_listBulletOfObject.end();) { CBullet* obj = *it; if(obj && obj->GetLayer() == LAYER::PLAYER) { timeCollision = CCollision::GetInstance()->Collision(this, obj, normalX, normalY, moveX, moveY, deltaTime); if ((timeCollision > 0.0f && timeCollision < 1.0f) || timeCollision == 2.0f) { //trên - xuống normalY = 1 //Trái phải normalX = -1 // ==0 ko va chạm theo Y, X CExplosionEffect* eff = CPoolingObject::GetInstance()->GetExplosionEffect(); eff->SetAlive(true); eff->SetPos(this->m_pos); // it = CPoolingObject::GetInstance()->m_listBulletOfObject.erase(it); // CBulletItem* bulletItem = CPoolingObject::GetInstance()->GetBulletItem(); bulletItem->SetAlive(true); bulletItem->SetPos(this->m_pos); bulletItem->m_stateItem = this->m_stateItem; this->m_isALive = false; } else { ++it; } } else { ++it; } } #pragma endregion }
void CScene::OnKeyDown(UINT nChar) { static DWORD nextShot = 0; switch (nChar) { case VK_UP: m_Ship->setAccelerate(true); break; case VK_DOWN: m_Ship->setBrake(true); break; case VK_RIGHT: m_Ship->setTurnRight(true); break; case VK_LEFT: m_Ship->setTurnLeft(true); break; case VK_SPACE: if (m_Ship->isDead() || nextShot > timeGetTime()) break; // Fire bullet from spaceship CBullet *bullet = new CBullet(); D3DXVECTOR3 deltaOrigin; deltaOrigin.x = cos( m_Ship->getRotation().z ) / 5.0f; deltaOrigin.y = sin( m_Ship->getRotation().z ) / 5.0f; deltaOrigin.z = 0.0f; bullet->setOrigin( m_Ship->getOrigin() ); bullet->setDeltaOrigin( deltaOrigin ); // Bullet speed = ship speed + acceleration bullet->setDeathTime( 1000 ); m_Objects.push_back( bullet ); #if USE_SOUND PlaySound( "sniper.wav", NULL, NULL ); #endif nextShot = timeGetTime() + 200; break; } }
void CTank::shoot() { CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSize tileSize = CGameScene::getTileSize(); CCPoint tankPos = getPosition(); CCSize tankSize = m_pTank->getContentSize(); CCPoint bulletPos = tankPos; CCPoint bulletTarget = bulletPos; CBullet *bullet = CBullet::createBullet(this, m_TankDirection); // ÉèÖÃ×Óµ¯³õʼλÖà switch(m_TankDirection) { case MOVE_UP: bulletPos.y += tankSize.height/2; bulletTarget.y = winSize.height - bullet->getContentSize().height/2; break; case MOVE_DOWN: bulletPos.y -= tankSize.height/2; bulletTarget.y = bullet->getContentSize().height/2; break; case MOVE_LEFT: bulletPos.x -= tankSize.width/2; bulletTarget.x = bullet->getContentSize().width/2; break; case MOVE_RIGHT: bulletPos.x += tankSize.width/2; bulletTarget.x = winSize.width - bullet->getContentSize().width/2; break; default: CCAssert(0, "Invalid direction"); break; } bulletPos = CGameScene::correctPoint(bulletPos); bullet->setPosition(bulletPos); m_BulletList->addObject(bullet); float duration = CGameScene::calcDistance(bulletPos, bulletTarget) / m_fBulletSpeed; bullet->getBullet()->runAction(CCSequence::actions( CCMoveTo::actionWithDuration(duration, bulletTarget), CCCallFuncN::actionWithTarget(this, callfuncN_selector(CTank::bulletMoveFinished)), NULL )); CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("material/laser.wav"); }
static void display(void) { // clear the scene glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); tank1.Draw(); tank2.Draw(); bullet.Draw(); glPopMatrix(); glutSwapBuffers(); }
void CArmySprite::fireBullet(float fEscapeTime) { CCNode *m_pTarget = (CCNode*)(getParent()->getChildByTag(PALYER_TYPE)); m_fTime += fEscapeTime; if (m_sCurData.mKind == AK_MISSILEARMY && m_fTime > 1.5f) { BULLET_DATA mData; mData.mAttack = m_sCurData.mAttack * 2; mData.mKind = BK_TARCKROCKET; mData.mMoveSpeed = 200.0f; mData.mDirection = ccpNormalize(ccpSub(m_pTarget->getPosition(), getPosition())); CBullet *pBullet = CBullet::createBullet(ENEMY_BULLET, mData, BK_TARCKROCKET); pBullet->setPosition(ccp(getPositionX(), getPositionY())); getParent()->addChild(pBullet, ABULLET_ZORDER); } if (m_fTime > 0.5f) { if (m_nBulletNum >= 2) { m_fFireCoolTime = 0.0f; m_nBulletNum = 0; } m_fTime = 0.0f; m_nBulletNum ++; BULLET_DATA mData; mData.mAttack = m_sCurData.mAttack; if (m_sCurData.mKind != AK_MISSILEARMY) { mData.mDirection = ccpNormalize(ccpSub(m_pTarget->getPosition(), getPosition())); mData.mKind = BK_ARMY01; mData.mMoveSpeed = 300.0f; CBullet *pBullet = CBullet::createBullet(ENEMY_BULLET, mData, BK_ARMY01); CCPoint mPos = ccpRotateByAngle(ccp(0, -48), ccp(0,0), -CC_DEGREES_TO_RADIANS(m_pTurretSprite->getRotation())); pBullet->setPosition(ccp(getPositionX() + mPos.x, getPositionY() + mPos.y)); getParent()->addChild(pBullet, ABULLET_ZORDER); } } }
void CPlayer::Shoot(CBullets& Bullets) { if(this->CanShoot()) { Mix_PlayChannel(-1, this->NormalShot, 0); if(this->CheckPowerUp(PowerUp::BURST_FIRE)) this->shot_delay = ACCL_SHOT_DELAY; else this->shot_delay = DEF_SHOT_DELAY; CBullet* Bullet = new CBullet( this->Display, this->Timer, (int)this->GetX() + this->GetCollisionBoundaries()->w / 2, (int)this->GetY() + this->GetCollisionBoundaries()->h / 2); Bullet->LoadEntity("Images"FN_SLASH"Sprites"FN_SLASH"Player_Shot.png"); Bullets.push_back(Bullet); this->bullets--; } }
void CObject::CheckHitRect(CBullet &bullet, CChara &chara) { for(int i = 0;i < BULLET_MAX;i++) { if(bullet.Flag[i]) { if(chara.IsExist) { if(HitCheck(bullet.HitRect[i], chara.HitRect) ) { bullet.Flag[i] = FALSE; bullet.SetPosition(i); chara.IsExist = FALSE; } } } } }
void CScene::update(void) { objects_vec testObjects(m_Objects); // make a local copy of vector bool explodeRock, explodeShip; // Crappy collission detection for bullet-rock and ship-rock while ( testObjects.size() > 0 ) { explodeRock = false; explodeShip = false; CGameObject *obj = testObjects[0]; if ((obj->getType() == OBJECT_BULLET || obj == m_Ship) && obj->isDead() == false && obj->isInvulnerable() == false ) { for (objects_vec::iterator it = m_Objects.begin(); it != m_Objects.end(); ++it) { CGameObject *obj2 = *it; if ( obj2->isDead() ) continue; if (obj2->getType() != OBJECT_ROCK) continue; if ( obj->collission(obj2) ) { CRock *rock = (CRock *) obj2; // Cast should be okey if ( rock->isBig() ) { #if USE_SOUND PlaySound( "detpack.wav", NULL, NULL ); #endif explodeRock = true; if (obj->getType() == OBJECT_BULLET) game->addPoints( 100 ); } else { if (obj->getType() == OBJECT_BULLET) game->addPoints( 25 ); } // Remove old rock and object from the scene rock->setDeathTime(-1); obj->setDeathTime(-1); m_NumRocks--; if (obj->getType() == OBJECT_SHIP) { game->loseLive(); explodeShip = true; } } } // Create the small rocks left after the explosion if (explodeRock) { for (int i=0; i < 4 + (rand()&1); i++) { CRock *newRock = new CRock(false); newRock->setOrigin( obj->getOrigin() ); newRock->setDeltaOrigin(D3DXVECTOR3((rand() % 100)/500.0f - 0.05f, (rand() % 100)/500.0f - 0.05f, 0.0f)); newRock->setDeltaRotation(D3DXVECTOR3(0.0f, 0.0f, (rand() % 100)/500.0f - 0.05f)); m_Objects.push_back( newRock ); m_NumRocks++; } } if (explodeShip) { // Some shatters from the ship for (int i=0; i < 4 + (rand()%4); i++) { CSpaceShip *particle = new CSpaceShip(); particle->setOrigin( m_Ship->getOrigin() ); particle->setSize(D3DXVECTOR3(0.02f * (1+rand()%4) / 2.0f, 0.02f * (1+rand()%4) / 2.0f, 0.02f * (rand()%4) / 2.0f)); particle->setDeltaOrigin(D3DXVECTOR3((1+rand() % 100)/500.0f - 0.1f, (1+rand() % 100)/500.0f - 0.1f, 0.0f)); particle->setDeltaRotation(D3DXVECTOR3(0.0f, 0.0f, (1+rand() % 100)/500.0f - 0.025f)); particle->setDecayRotation(1.0f); particle->setDeathTime( 1500 ); m_Objects.push_back( particle ); } // Some bullets for extra effect for (int i=0; i < 4 + (rand()%4); i++) { CBullet *particle = new CBullet(); particle->setOrigin( m_Ship->getOrigin() ); particle->setSize(D3DXVECTOR3(0.02f * (1+rand()%4) / 2.0f, 0.02f * (1+rand()%4) / 2.0f, 0.02f * (1+rand()%4) / 2.0f)); particle->setDeltaOrigin(D3DXVECTOR3((1+rand() % 100)/250.0f - 0.02f, (1+rand() % 100)/250.0f - 0.02f, 0.0f)); //particle->setDeltaRotation(D3DXVECTOR3(0.0f, 0.0f, (rand() % 100)/500.0f - 0.025f)); //particle->setDecayRotation(1.0f); particle->setDeathTime( 500 ); m_Objects.push_back( particle ); } } } testObjects.erase( testObjects.begin() ); } // Call update on objects for (objects_vec::iterator it = m_Objects.begin(); it != m_Objects.end(); ++it) { CGameObject *obj = *it; if ( obj->isDead() ) { // FIXME: // Should remove from list, skip for now continue; } obj->update(); } if (m_NumRocks == 0) game->nextLevel(); }
void MainLogic::MakeBullet(CBaseChar * p_target) { CBullet * temp = NULL; D3DXVECTOR2 t; bool playerBullet = false; if(p_target->m_eCharIndex == Index_Player) { playerBullet = true; } else { playerBullet = false; } switch(p_target->m_eNowWeapon) { case Weapon_Nomal: temp = new CBullet(); temp->init(Index_Nomal); t = p_target->getPos(); t.x += p_target->m_pArm->getPos().x * p_target->m_Siz.x; t.y += p_target->m_pArm->getPos().y; temp->shotbullet(t,p_target->m_vWeaponVector,playerBullet); m_vBullets.push_back(temp); addChild(temp); p_target->m_isFire = false; break; case Weapon_Double: for(int i =0; i<2; i++) { temp = new CBullet(); temp->init(Index_Double); t = p_target->getPos(); t.x += p_target->m_pArm->getPos().x* p_target->m_Siz.x; t.y += p_target->m_pArm->getPos().y; t.y += (20 * i) - 10; temp->shotbullet(t,p_target->m_vWeaponVector,playerBullet); m_vBullets.push_back(temp); addChild(temp); } p_target->m_isFire = false; break; case Weapon_Tripel: for(int i =0; i<3; i++) { temp = new CBullet(); temp->init(Index_Double); t = p_target->getPos(); t.x += p_target->m_pArm->getPos().x* p_target->m_Siz.x; t.y += p_target->m_pArm->getPos().y; t.y += (20 * i) - 20; temp->shotbullet(t,p_target->m_vWeaponVector,playerBullet); m_vBullets.push_back(temp); addChild(temp); } p_target->m_isFire = false; break; case Weapon_Multiple: temp = new CBullet(); temp->init(Index_Multiple); t = p_target->getPos(); t.x += p_target->m_pArm->getPos().x* p_target->m_Siz.x; t.y += p_target->m_pArm->getPos().y; temp->shotbullet(t,p_target->m_vWeaponVector,playerBullet); m_vBullets.push_back(temp); addChild(temp); break; case Weapon_BigMulti: temp = new CBullet(); temp->init(Index_BigMulti); t = p_target->getPos(); t.x += p_target->m_pArm->getPos().x* p_target->m_Siz.x; t.y += p_target->m_pArm->getPos().y; temp->shotbullet(t,p_target->m_vWeaponVector,playerBullet); m_vBullets.push_back(temp); addChild(temp); break; } }
void CEnemyWallShooter::Update(CTimer* gameTime, Megaman* rockman) { //Nếu thời gian phòng thủ đã hết if (_timeDefense <= 0 && _state==ENEMYWALLSHOOTER_STATE::DEFENSE) { _state = ENEMYWALLSHOOTER_STATE::ATTACK; _sprite.SetFrame(1, 3); } #pragma region Trạng thái tấn công if (_state == ENEMYWALLSHOOTER_STATE::ATTACK) { if (_sprite.GetIndex() == 3) { _sprite.SetIndex(3);//Chỉ vẽ sprite có súng dài nhất } _timeDelayFireRemain -= gameTime->GetTime(); if (_timeDelayFireRemain <= 0) { //Tìm vị trí của viên đạn float posY = _position.y; //angleFly: Góc bắn của viên đạn, lấy trục dương Ox làm gốc tọa độ. Đơn vị Radian float posX, angleFly; //Giá trị để cho biết hướng bay của đạn là qua trái (1) hay qua phải (-1). int vectorXOfFLyOfBullet = 1; if (_orientation == ENEMYWALLSHOOTER_ORIENTATION::LEFT) { posX = _position.x - 1 * _sprite.GetFrameWidth() / 2; angleFly = PI / 2.0f + PI / 4.0f; vectorXOfFLyOfBullet = 1; } else { posX = _position.x + 1 * _sprite.GetFrameWidth() / 2; angleFly = 2 * PI + PI / 4.0f; vectorXOfFLyOfBullet = -1; } //Tính toán góc bắn cho viên đạn sắp bắn ra dựa vào số thứ tự viên đạn trước đó. angleFly = angleFly + vectorXOfFLyOfBullet * (_numOfPrevBullet++*(PI / 6.0f));//Cần phải nhân vectorXOfFLyOfBullet là do khi đạn bay sang phải thì góc bắn theo thứ tự phải là trừ dần so với góc đã xác định ban đầu. //Để chắc ăn là đạn không còn trước khi được add vào thì tiến hành clear() trước _lstBullet.clear(); //Thêm đạn vào list Đạn CBullet* bullet = new CEnemyMachineAutoBullet(0, ID_BULLET_WALL_SHOOTER, ResourceManager::GetSprite(ID_SPRITE_BULLET_RED_COLOR), DAME_BULLET_WALL_SHOOTER, 120.f / 1000.0f, D3DXVECTOR2(posX, posY), angleFly); bullet->Initlize(); _lstBullet.push_back(bullet); ResourceManager::PlayASound(ID_EFFECT_ENEMY_FIRE); //Reset thời gian nghỉ còn lại giữa 2 lần bắn _timeDelayFireRemain = TIME_DELAY_FIRE_OF_WALL_SHOOTER_ENEMY; //Nếu viên đạn vừa bắn có _numOfPrevBullet == 4 thì reset về giá trị 0 để lần tới tiếp tục bắn từ viên thứ 1. if (_numOfPrevBullet == 4) { _numOfPrevBullet = 0; _sprite.SetFrame(2, 0); } } if (_sprite.GetIndex() == 0) { _sprite.SetIndex(0); _state = ENEMYWALLSHOOTER_STATE::DEFENSE;//Chuyển về trạng thái phòng thủ _timeDefense = TIME_DEFENSE_OF_WALL_SHOOTER_ENEMY; } } #pragma endregion #pragma region Trạng thái phòng thủ if (_state == ENEMYWALLSHOOTER_STATE::DEFENSE) { _timeDefense -= gameTime->GetTime(); } #pragma endregion _isHitDame = false; this->UpdateBox(); _sprite.SetAllowAnimate(100); _sprite.Update(gameTime); }
void gameLogic(int value) { bullet.Fly(gravityAcceleration, gameLogicUpdateIntervalInMs); glutTimerFunc(gameLogicUpdateIntervalInMs, gameLogic, value); }
void CBulletManager::SimulateBullet(CBullet& oBullet, float dt) { Vector vecOriginal = oBullet.m_vecOrigin; Assert(oBullet.m_hShooter.Get()); if (!oBullet.m_hShooter) return; bool bHasTraveledBefore = false; if (oBullet.m_flDistanceTraveled > 0) bHasTraveledBefore = true; // initialize these before the penetration loop, we'll need them to make our tracer after Vector vecTracerSrc = oBullet.m_vecOrigin; trace_t tr; // main enter bullet trace float flRange = dt; if (flRange < 0) flRange = 8000; bool bFullPenetrationDistance = false; Vector vecEnd = oBullet.m_vecOrigin + oBullet.m_vecDirection * flRange; int i; for (i = oBullet.m_iPenetrations; i < da_bullet_penetrations.GetInt(); i++) { CTraceFilterSimpleList tf(COLLISION_GROUP_NONE); tf.AddEntityToIgnore(oBullet.m_hShooter); for (int j = 0; j < oBullet.m_ahObjectsHit.Count(); j++) tf.AddEntityToIgnore(oBullet.m_ahObjectsHit[j]); UTIL_TraceLine( oBullet.m_vecOrigin, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &tf, &tr ); if (da_bullet_debug.GetBool()) { #ifdef CLIENT_DLL DebugDrawLine(oBullet.m_vecOrigin + Vector(0, 0, 1), tr.endpos + Vector(0, 0, 1), 0, 255, 255, true, dt<0?10:0.1); #else DebugDrawLine(oBullet.m_vecOrigin + Vector(0, 0, 1), tr.endpos + Vector(0, 0, 1), 255, 255, 0, true, dt<0?10:0.1); #endif } Vector vecTraceEnd = tr.endpos; bool bBSPModel = tr.DidHitWorld(); if (tr.allsolid) { oBullet.m_flDistanceTraveled += (oBullet.m_vecOrigin - vecEnd).Length(); oBullet.m_vecOrigin = vecEnd; break; // We're inside something. Do nothing. } if ( sv_showimpacts.GetBool() && tr.fraction < 1.0f ) { #ifdef CLIENT_DLL // draw red client impact markers debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, sv_showimpacts.GetFloat() ); if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) { C_BasePlayer *player = ToBasePlayer( tr.m_pEnt ); player->DrawClientHitboxes( sv_showimpacts.GetFloat(), true ); } #else // draw blue server impact markers NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, sv_showimpacts.GetFloat() ); if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) { CBasePlayer *player = ToBasePlayer( tr.m_pEnt ); player->DrawServerHitboxes( sv_showimpacts.GetFloat(), true ); } #endif } Assert(oBullet.m_iBulletType > 0); int iDamageType = DMG_BULLET | DMG_NEVERGIB | GetAmmoDef()->DamageType(oBullet.m_iBulletType); if (i == 0) iDamageType |= DMG_DIRECT; if (tr.startsolid) { trace_t tr2; UTIL_TraceLine( tr.endpos - oBullet.m_vecDirection, oBullet.m_vecOrigin, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr2 ); // let's have a bullet exit effect if we penetrated a solid surface if (oBullet.m_bDoEffects && tr2.m_pEnt && tr2.m_pEnt->IsBSPModel()) UTIL_ImpactTrace( &tr2, iDamageType ); // ignore the entity we just hit for the next trace to avoid weird impact behaviors oBullet.m_ahObjectsHit.AddToTail(tr2.m_pEnt); } if ( tr.fraction == 1.0f ) { oBullet.m_flDistanceTraveled += (oBullet.m_vecOrigin - vecEnd).Length(); oBullet.m_vecOrigin = vecEnd; break; // we didn't hit anything, stop tracing shoot } weapontype_t eWeaponType = WT_NONE; CSDKWeaponInfo *pWeaponInfo = CSDKWeaponInfo::GetWeaponInfo(oBullet.m_eWeaponID); Assert(pWeaponInfo); if (pWeaponInfo) eWeaponType = pWeaponInfo->m_eWeaponType; float flDamageMultiplier = 1; float flMaxRange = 3000; // Power formula works like so: // pow( x, distance/y ) // The damage will be at 1 when the distance is 0 units, and at // x% when the distance is y units, with a gradual decay approaching zero switch (eWeaponType) { case WT_RIFLE: flDamageMultiplier = 0.75f; flMaxRange = 3000; break; case WT_SHOTGUN: flDamageMultiplier = 0.40f; flMaxRange = 500; break; case WT_SMG: flDamageMultiplier = 0.50f; flMaxRange = 1000; break; case WT_PISTOL: default: flDamageMultiplier = 0.55f; flMaxRange = 1500; break; } flMaxRange *= oBullet.m_hShooter->m_Shared.ModifySkillValue(1, 0.5f, SKILL_MARKSMAN); //calculate the damage based on the distance the bullet travelled. oBullet.m_flDistanceTraveled += tr.fraction * flRange; float flCurrentDistance = oBullet.m_flDistanceTraveled; // First 500 units, no decrease in damage. if (eWeaponType == WT_SHOTGUN) flCurrentDistance -= 350; else flCurrentDistance -= 500; if (flCurrentDistance < 0) flCurrentDistance = 0; if (flCurrentDistance > flMaxRange) flCurrentDistance = flMaxRange; float flDistanceMultiplier = pow(flDamageMultiplier, (flCurrentDistance / flMaxRange)); if( oBullet.m_bDoEffects ) { // See if the bullet ended up underwater + started out of the water if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) ) { CBaseEntity* pIgnore; if (oBullet.m_ahObjectsHit.Count()) pIgnore = oBullet.m_ahObjectsHit.Tail(); else pIgnore = oBullet.m_hShooter; trace_t waterTrace; UTIL_TraceLine( oBullet.m_vecOrigin, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), pIgnore, COLLISION_GROUP_NONE, &waterTrace ); if( waterTrace.allsolid != 1 ) { CEffectData data; data.m_vOrigin = waterTrace.endpos; data.m_vNormal = waterTrace.plane.normal; data.m_flScale = random->RandomFloat( 8, 12 ); if ( waterTrace.contents & CONTENTS_SLIME ) data.m_fFlags |= FX_WATER_IN_SLIME; DispatchEffect( "gunshotsplash", data ); } } else { //Do Regular hit effects // Don't decal nodraw surfaces if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) ) { CBaseEntity *pEntity = tr.m_pEnt; //Tony; only while using teams do we check for friendly fire. if ( DAGameRules()->IsTeamplay() && pEntity && pEntity->IsPlayer() && (pEntity->GetBaseAnimating() && !pEntity->GetBaseAnimating()->IsRagdoll()) ) { if ( pEntity->GetTeamNumber() != oBullet.m_hShooter->GetTeamNumber() ) UTIL_ImpactTrace( &tr, iDamageType ); } //Tony; non player, just go nuts, else UTIL_ImpactTrace( &tr, iDamageType ); } } } // bDoEffects // add damage to entity that we hit #ifdef GAME_DLL float flBulletDamage = oBullet.m_iBulletDamage * flDistanceMultiplier / (i+1); // Each iteration the bullet drops in strength if (oBullet.m_hShooter->IsStyleSkillActive(SKILL_MARKSMAN)) flBulletDamage = oBullet.m_iBulletDamage * flDistanceMultiplier / (i/2+1); // Each iteration the bullet drops in strength but not nearly as much. ClearMultiDamage(); CTakeDamageInfo info( oBullet.m_hShooter, oBullet.m_hShooter, oBullet.m_hWeapon, flBulletDamage, iDamageType ); CalculateBulletDamageForce( &info, oBullet.m_iBulletType, oBullet.m_vecDirection, tr.endpos ); tr.m_pEnt->DispatchTraceAttack( info, oBullet.m_vecDirection, &tr ); oBullet.m_hShooter->TraceAttackToTriggers( info, tr.startpos, tr.endpos, oBullet.m_vecDirection ); ApplyMultiDamage(); #else flDistanceMultiplier = flDistanceMultiplier; // Silence warning. #endif if (tr.m_pEnt && !FStrEq(tr.m_pEnt->GetClassname(), "worldspawn")) oBullet.m_ahObjectsHit.AddToTail(tr.m_pEnt); float flPenetrationDistance; switch (eWeaponType) { case WT_RIFLE: flPenetrationDistance = 25; break; case WT_SHOTGUN: flPenetrationDistance = 5; break; case WT_SMG: flPenetrationDistance = 15; break; case WT_PISTOL: default: flPenetrationDistance = 15; break; } flPenetrationDistance = oBullet.m_hShooter->m_Shared.ModifySkillValue(flPenetrationDistance, 1, SKILL_MARKSMAN); Vector vecBackwards = tr.endpos + oBullet.m_vecDirection * flPenetrationDistance; if (tr.m_pEnt->IsBSPModel()) UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr ); else UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_HITBOX, NULL, COLLISION_GROUP_NONE, &tr ); if (tr.startsolid) { bFullPenetrationDistance = true; break; } // Set up the next trace. One unit in the direction of fire so that we firmly embed // ourselves in whatever solid was hit, to make sure we don't hit it again on next trace. if (dt < 0 && bBSPModel) { UTIL_TraceLine( vecTraceEnd + oBullet.m_vecDirection, vecTraceEnd + oBullet.m_vecDirection * flPenetrationDistance, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr ); if (tr.startsolid) oBullet.m_vecOrigin = tr.startpos + oBullet.m_vecDirection; else oBullet.m_vecOrigin = vecTraceEnd + oBullet.m_vecDirection; } else oBullet.m_vecOrigin = vecTraceEnd + oBullet.m_vecDirection; } oBullet.m_iPenetrations = i; // the bullet's done penetrating, let's spawn our particle system if (oBullet.m_bDoEffects && dt < 0) oBullet.m_hShooter->MakeTracer( oBullet.m_vecOrigin, tr, TRACER_TYPE_DEFAULT, !bHasTraveledBefore ); #ifdef CLIENT_DLL if (oBullet.m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE) ClientLeafSystem()->RenderableChanged( oBullet.m_hRenderHandle ); #endif if (bFullPenetrationDistance || oBullet.m_iPenetrations >= da_bullet_penetrations.GetInt()) oBullet.Deactivate(); if (dt < 0) oBullet.Deactivate(); if (!bHasTraveledBefore && oBullet.m_flCurrAlpha == 0 && oBullet.m_flGoalAlpha == 0) oBullet.m_bActive = false; if (da_bullet_debug.GetBool()) { #ifdef CLIENT_DLL DebugDrawLine(vecOriginal, oBullet.m_vecOrigin, 0, 0, 255, true, dt<0?10:0.1); #else DebugDrawLine(vecOriginal, oBullet.m_vecOrigin, 255, 0, 0, true, dt<0?10:0.1); #endif } }
void CSoldier::OnCollision(float deltaTime, std::vector<CGameObject*>* listObjectCollision) { float normalX = 0; float normalY = 0; float moveX = 0.0f; float moveY = 0.0f; float timeCollision; for (std::vector<CBullet*>::iterator it = CPoolingObject::GetInstance()->m_listBulletOfObject.begin(); it != CPoolingObject::GetInstance()->m_listBulletOfObject.end();) { CBullet* obj = *it; timeCollision = CCollision::GetInstance()->Collision(obj, this, normalX, normalY, moveX, moveY, deltaTime); if((timeCollision > 0.0f && timeCollision < 1.0f) || timeCollision == 2.0f) { if(obj->IsAlive() && obj->GetLayer() == LAYER::PLAYER) { // Gan trang thai die cho doi tuong this->m_stateCurrent = SOLDIER_STATE::S_IS_DIE; // Xoa vien dan ra khoi d.s it = CPoolingObject::GetInstance()->m_listBulletOfObject.erase(it); //Load sound die ManageAudio::GetInstance()->playSound(TypeAudio::ENEMY_DEAD_SFX); // Tang diem cua contra len CContra::GetInstance()->IncreateScore(500); } else ++it; } else { ++it; } } if (this->m_stateCurrent != SOLDIER_STATE::S_IS_DIE) { //Kiem tra va cham voi ground bool checkColWithGround = false; // xet va cham vs ground for (std::vector<CGameObject*>::iterator it = listObjectCollision->begin(); it != listObjectCollision->end(); it++) { CGameObject* obj = *it; //Lay thoi gian va cham //Neu doi tuong la ground va dang va cham if(((obj->GetIDType() == 15 && obj->GetID() == 1) || (obj->GetIDType() == 15 && obj->GetID() == 8) || (obj->GetIDType() == 16 && obj->GetID() == 1)) && !checkColWithGround) { timeCollision = CCollision::GetInstance()->Collision(this, obj, normalX, normalY, moveX, moveY, deltaTime); if((timeCollision > 0.0f && timeCollision < 1.0f) || timeCollision == 2.0f) { if(normalY > 0) { checkColWithGround = true; if (this->m_stateCurrent == SOLDIER_STATE::S_IS_JUMP) { if (this->m_vy < -200.0f) { this->m_stateCurrent = SOLDIER_STATE::S_IS_JOGGING; if( timeCollision == 2.0f) { //this->m_isJumping = false; this->m_pos.y += moveY; this->m_vy = 0; this->m_a = 0; } } } else { this->m_stateCurrent = SOLDIER_STATE::S_IS_JOGGING; if( timeCollision == 2.0f) { //this->m_isJumping = false; this->m_pos.y += moveY; this->m_vy = 0; this->m_a = 0; } } } } } } if(!checkColWithGround) { this->m_a = -700.0f; if (this->m_jump) { if(this->m_vy == 0.0f) this->m_vy = this->m_vyDefault; this->m_stateCurrent = SOLDIER_STATE::S_IS_JUMP; } else { // Soldier quay dau nguoc lai. this->m_left = !this->m_left; this->m_countRepeat ++; if (m_countRepeat > 2) { this->m_countRepeat = 0; this->m_jump = true; } // Xet gia tri tiep theo la nhay. //this->m_jump = true; } } } }
/// /// @todo 적절한 메세지를 서버에 날려라.. <= 현재는 서버에서 명령을 하달받음.. 그러니 날릴 필요없지.. /// 현재 실제 액션은 각 스킬 클래스 자체에서.. bool CSkillManager::ActionSkill( short nSkillIdx, CObjCHAR* pSrc, CObjCHAR* pTarget, D3DXVECTOR3 PosTo, bool bTargetPos ) { /// 행위 방식에 따라서... int iSkillActionType = GetSkillActionType( nSkillIdx ); switch( iSkillActionType ) { case SKILL_BASE_ACTION: ///< 기본 명령( 앉기, 서기, 줍기... ) break; case SKILL_CREATE_WINDOW: break; case SKILL_ACTION_IMMEDIATE: break; case SKILL_ACTION_FIRE_BULLET: { int iBulletIDX = SKILL_BULLET_NO( nSkillIdx ); if ( pTarget && iBulletIDX ) { CBullet* pBullet = g_pBltMGR->Add_BULLET( pSrc, pTarget, iBulletIDX, true, SKILL_BULLET_LINKED_POINT( nSkillIdx ) ); if( pBullet ) pBullet->SetSkillIDX( nSkillIdx ); /// 타격사운드 출력 } } break; /// 지역공격 마법 case SKILL_ACTION_AREA_TARGET: { if( bTargetPos ) { int iBulletIDX = SKILL_BULLET_NO( nSkillIdx ); if ( iBulletIDX ) { short nEffectFileIDX = EFFECT_BULLET_NORMAL( iBulletIDX ); /// 지역공격마법은 총알을 쏘는게 아니라 타겟에 이펙트를 붙인다. CEffect *pHitEFT = g_pEffectLIST->Add_EffectWithIDX( nEffectFileIDX, true ); if ( pHitEFT ) { /*if( pTarget ) { pHitEFT->LinkNODE ( pTarget->GetZMODEL() ); pHitEFT->UnlinkVisibleWorld (); }else*/ { pHitEFT->SetPOSITION( PosTo ); } pHitEFT->InsertToScene (); } } } } break; ///< 자신에게 발동.( 캐스팅 유 ) case SKILL_ACTION_SELF_BOUND_DURATION: case SKILL_ACTION_SELF_BOUND: case SKILL_ACTION_SELF_STATE_DURATION: case SKILL_ACTION_SELF_DAMAGE: { /// Self 스킬의 경우에는 총알효과, 타격효과를 모두 나한테 붙여준다. /// 총알 효과.. int iShotEffectIDX = SKILL_BULLET_NO( nSkillIdx ); int iEffectIDX = EFFECT_BULLET_NORMAL( iShotEffectIDX ); CEffect *pEffect = g_pEffectLIST->Add_EffectWithIDX( iEffectIDX, true ); if( pEffect ) { pSrc->LinkDummy( pEffect->GetZNODE(), SKILL_BULLET_LINKED_POINT( nSkillIdx) ); pEffect->SetParentCHAR( pSrc ); pSrc->AddExternalEffect( pEffect ); pEffect->InsertToScene (); } /// 타격 효과.. int iHitEffectIDX = SKILL_HIT_EFFECT( nSkillIdx ); pEffect = g_pEffectLIST->Add_EffectWithIDX( iHitEffectIDX, true ); if( pEffect ) { pSrc->LinkDummy( pEffect->GetZNODE(), SKILL_HIT_EFFECT_LINKED_POINT( nSkillIdx) ); pEffect->SetParentCHAR( pSrc ); pSrc->AddExternalEffect( pEffect ); pEffect->InsertToScene (); } } break; ///< 자신에게 발동.( 캐스팅 유 ) case SKILL_ACTION_TARGET_BOUND_DURATION: case SKILL_ACTION_TARGET_BOUND: case SKILL_ACTION_TARGET_STATE_DURATION: case SKILL_ACTION_RESURRECTION: { int iBulletIDX = SKILL_BULLET_NO( nSkillIdx ); if ( pTarget && iBulletIDX ) { CBullet* pBullet = g_pBltMGR->Add_BULLET( pSrc, pTarget, iBulletIDX, true, SKILL_BULLET_LINKED_POINT( nSkillIdx ), D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), false, true, nSkillIdx ); if( pBullet ) pBullet->SetSkillIDX( nSkillIdx ); /// 타격사운드 출력 } /*int iShotEffectIDX = SKILL_BULLET_NO( nSkillIdx ); int iEffectIDX = EFFECT_HITTED_NORMAL( iShotEffectIDX ); CEffect *pEffect = g_pEffectLIST->Add_EffectWithIDX( iEffectIDX, true ); if( pEffect ) { pSrc->LinkDummy( pEffect->GetZNODE(), SKILL_BULLET_LINKED_POINT( nSkillIdx) ); pEffect->SetParentCHAR( pSrc ); pSrc->AddExternalEffect( pEffect ); pEffect->InsertToScene (); }*/ } break; } return true; }
void CGameScene::PushBullet(float x, float y) { CBullet *p = new CBullet(); p->SetPosition(x, y); m_pBulletScene->PushScene(p); }