Action ComponentBrainKamikaze::getNextAction_chase(float milliseconds) { if(!targetPlayer || isDead(targetPlayer) || (!canDetectPlayer(*targetPlayer) && getTimeInState()>resumeWanderThreshold)) { nextState = StateWander; } ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(targetPlayer->getComponent("Physics")); if(!component) return Stand; vec3 playerPosition3D = component->getPosition(); vec3 ourPosition3D = getPosition3D(); vec2 playerPosition = playerPosition3D.xy(); vec2 ourPosition = ourPosition3D.xy(); float angle = getAngle(playerPosition, ourPosition); Direction desiredDirection = getDirectionFromAngle(angle); Direction currentFacing = getCurrentFacing(); return getActionFromAngle(angle); }
void MapSceneController::linkRoads(void) { //目前角色移动只有前后方向操作,所以暂时只需要根据z坐标进行实际逻辑实现 auto pPlayer = _pPlayer; auto index = _vpRoadSprites.size(); for (auto it = _vpRoadSprites.begin(); it < _vpRoadSprites.end(); ++it) { auto pos = (*it)->getAABB().getCenter(); pos.set(pos.x, pos.y, pPlayer->getCurSprite()->getPositionZ()); if ((*it)->getAABB().containPoint(pos)) { index = _vpRoadSprites.getIndex((*it)); break; } } if (index >= _vpRoadSprites.size()/2) { auto size = _vpRoadSprites.size(); for (decltype(index) i = 0; i < index; ++i) { auto pSprite = _vpRoadSprites.at(0); pSprite->retain(); pSprite->setPosition3D(pSprite->getPosition3D() + Vec3(0, 0, -(ROAD_SPRITE_MODEL_WIDTH * static_cast<float>(size)))); _vpRoadSprites.eraseObject(pSprite); _vpRoadSprites.pushBack(pSprite); pSprite->release(); } } }
bool ComponentBrainKamikaze::canDetectPlayer(const Actor &player) { ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(player.getComponent("Physics")); if(!component) return false; vec3 playerPosition3D = component->getPosition(); vec2 playerPosition = vec2(playerPosition3D.x, playerPosition3D.y); vec3 ourPosition3D = getPosition3D(); vec2 ourPosition = getPosition2D(); float distance = getDistance(playerPosition, ourPosition); if(distance < maxSightDistance) { // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); } return false; }
bool ComponentBrainShooter::canDetectPlayer(const Actor &player) { ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(player.getComponent("Physics")); if(!component) return false; vec3 playerPosition3D = component->getPosition(); vec2 playerPosition = vec2(playerPosition3D.x, playerPosition3D.y); vec3 ourPosition3D = getPosition3D(); vec2 ourPosition = getPosition2D(); float distance = getDistance(playerPosition, ourPosition); if(distance < maxSightDistance) { float radian_fov = fov * float(M_PI / 180.0); float facingAngle = getAngleFromDirection(getCurrentFacing()); float minFOV = angle_clamp(facingAngle - radian_fov); float maxFOV = angle_clamp(facingAngle + radian_fov); float angleToTarget = getAngle(playerPosition, ourPosition); #if 0 if(isAngleWithinFOV(angleToTarget, minFOV, maxFOV)) { // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); } #else // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); #endif } return false; }
Action ComponentBrainShooter::getNextAction_chase(float milliseconds) { if(!targetPlayer || isDead(targetPlayer) || (!canDetectPlayer(*targetPlayer) && getTimeInState()>resumeWanderThreshold)) { nextState = StateWander; } ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(targetPlayer->getComponent("Physics")); if(!component) return Stand; vec3 playerPosition3D = component->getPosition(); vec3 ourPosition3D = getPosition3D(); vec2 playerPosition = playerPosition3D.xy(); vec2 ourPosition = ourPosition3D.xy(); float angle = getAngle(playerPosition, ourPosition); Direction desiredDirection = getDirectionFromAngle(angle); Direction currentFacing = getCurrentFacing(); if(currentFacing == desiredDirection && getDistance(playerPosition, ourPosition) < shootDistance && rayCast(*targetPlayer, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance)) { getParentBlackBoard().relayMessage(MessagePerformAction(Stand)); return AttackOnce; } else { Action action = getActionFromAngle(angle); return action; } }
cocos2d::Vec3 && NpcController::calcuratePosWillHit(MoveAbleElem * pElemSrc, Player * pElemTar, float fDtToHit) { #ifndef STD_VECTOR_ELEM CC_SAFE_RETAIN(pElemSrc); #endif CC_SAFE_RETAIN(pElemTar); auto pSpriteSrc = pElemSrc->getCurSprite(); auto pSpriteTar = pElemTar->getCurSprite(); auto srcNormalDir = pElemSrc->getMoveDirNormal(); srcNormalDir.normalize(); auto tarNormalDir = pElemTar->getMoveDirNormal(); tarNormalDir.normalize(); srcNormalDir = srcNormalDir * pElemSrc->getMoveSpeed(); tarNormalDir = tarNormalDir * pElemTar->getMoveSpeed(); auto tartDir = tarNormalDir - srcNormalDir; tartDir *= fDtToHit; pSpriteSrc->setPosition3D(pSpriteTar->getPosition3D() + tartDir + Vec3(0,-5,0)); CC_SAFE_RELEASE(pElemTar); #ifndef STD_VECTOR_ELEM CC_SAFE_RELEASE(pElemSrc); #endif return std::move(tartDir); }
Scene* Chapter10_5::createScene() { //cocos2d::Rect visibleRect = Director::getInstance()->getOpenGLView()->getVisibleRect(); Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto winSize = Director::getInstance()->getWinSize(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // create a scene // 'scene' is an autorelease object // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ auto scene = Scene::create(); // add title auto label = LabelTTF::create("camera test", "Arial", 24); label->setPosition(Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2).x, Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height).y - 30); scene->addChild(label, -1); //add the menu item for back to main menu label = LabelTTF::create("MainMenu", "Arial", 24); auto menuItem = MenuItemLabel::create(label); menuItem->setCallback([&](cocos2d::Ref *sender) { Director::getInstance()->replaceScene(Chapter10::createScene()); }); auto menu = Menu::create(menuItem, nullptr); menu->setPosition( Vec2::ZERO ); menuItem->setPosition( Vec2( Vec2(origin.x+visibleSize.width, origin.y+visibleSize.height/2).x - 80, Vec2(origin.x+visibleSize.width/2, origin.y).y + 25) ); scene->addChild(menu, 1); auto layer3D=Layer::create(); scene->addChild(layer3D,2); std::string fileName = "orc.c3b"; auto sprite = Sprite3D::create(fileName); sprite->setScale(5.f); sprite->setRotation3D(Vec3(0,180,0)); sprite->setPosition( Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2).x, Vec2(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2).y ); // play animation auto animation = Animation3D::create(fileName); if (animation) { auto animate = Animate3D::create(animation); animate->setSpeed(1); sprite->runAction(RepeatForever::create(animate)); } //add to scene layer3D->addChild(sprite); // add camera auto camera=Camera::createPerspective(60, (GLfloat)winSize.width/winSize.height, 1, 1000); camera->setCameraFlag(CameraFlag::USER1);// set camera flag camera->setPosition3D(Vec3(0, 0, 230) + sprite->getPosition3D()); camera->lookAt(sprite->getPosition3D(), Vec3(0,1,0)); // create camera action auto action = MoveBy::create(3, Vec2(100, 0)); auto action_back = action->reverse(); auto action1 = MoveBy::create(3, Vec2(0, 100)); auto action_back1 = action1->reverse(); auto seq = Sequence::create( action, action_back, action1, action_back1, nullptr ); // run camera action camera->runAction( RepeatForever::create(seq) ); layer3D->addChild(camera); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // set camera mask // when node's camera-mask & camer-flag result is true, the node is visible for this camera. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ layer3D->setCameraMask(0x2); // return the scene return scene; }
bool CStaticObject::load() { if( m_loaded ) return true; node_ = I_WORLD->sceneManager()->getRootSceneNode()->createChildSceneNode(); node_->setPosition(getPosition3D()); entity_ = I_WORLD->sceneManager()->createEntity(getUniqueName(name_.c_str()),proto_->getMeshName()); entityNode_ = node_->createChildSceneNode(); entityNode_->attachObject(entity_); if( proto_->getScale() != Vector3::ZERO ) { entityNode_->setScale(Vector3(proto_->getScale().x,proto_->getScale().y,proto_->getScale().z)); } else if( proto_->getSize() != Vector3::ZERO ) { Vector3 size = OgreOde::MeshInformer::getSize(entity_->getMesh().get()); Vector3 scale(proto_->getSize().x / size.x, proto_->getSize().y / size.y, proto_->getSize().z / size.z); if( scale.x == 0 ) scale.x = scale.y; if( scale.z == 0 ) scale.z = scale.y; entityNode_->setScale(Vector3(scale.x,scale.y,scale.z)); } /*Caution: If you scale your scene node only to find out that the object(s) attached to it suddenly have increased (or decreased) significantly in intensity when rendered, then you probably did not realize that everything attached to the node is scaled . . . including vertex normals. Since local lighting calculations assume that the normals they are using are normalized (unit-length vectors), those calculations will happily (and unquestioningly) use the scaled normals when shading your polygons. The fix: after you scale a scene node, call setNormaliseNormals() on the affected entities to reset their normals to a “normal” state. Understand that this operation does have a performance cost.*/ entity_->setNormaliseNormals(true); _log(_info,_loc,"'%s' Size = '%s' Scale = '%s' ", name_.c_str(),StringConverter::toString(proto_->getSize()).c_str(), StringConverter::toString(proto_->getScale()).c_str()); Quaternion q; q.FromAngleAxis(getRotation(),Vector3::UNIT_Y); setOrientation(q); // TODO fixme ... maybe replace after m_loaded and use CClientStaticObject::pitch --> CObject::pitch ? Quaternion p; p.FromAngleAxis(getPitch(),Vector3::UNIT_X); setOrientation(getOrientation() * p); Quaternion r; r.FromAngleAxis(getRoll(),Vector3::UNIT_Z); setOrientation(getOrientation() * r); m_loaded = true; // //for( std::vector<CSegment>::iterator it = m_segments.begin(); it != m_segments.end(); ++it ) //{ // Entity* ent = I_WORLD->sceneManager()->createEntity(getUniqueName(""),"cube.mesh"); // SceneNode *node = I_WORLD->sceneManager()->getRootSceneNode()->createChildSceneNode(); // node->attachObject(ent); // Vector2 dir = (*it).p2()-(*it).p1(); // Real len = dir.length(); // dir.normalise(); // Vector2 per = dir.perpendicular(); // node->setPosition(((*it).p1() + dir*(len + 1)/2).x,getPosition().y+1,((*it).p1() + dir*(len+1)/2).y); // Quaternion q; // Vector3 x(dir.x,0,dir.y); // x.normalise(); // Vector3 z(per.x,0,per.y); // z.normalise(); // q.FromAxes(x,Vector3::UNIT_Y,z); // node->setOrientation(q); // node->setScale((Real)len*0.01,(Real)0.01,(Real)0.01); //} return true; };
void GamePaddle::move(Point2D to) { m_transform = translation(Vector3D(to[0], to[1], 0)); _paddle->move(to); _bound->move(m_origin * getPosition3D()); }