前面我们的攻击手段比较单一,虽然已经分出了 EnemyT1 / EnemyT2 / EnemyT3, 但里面还是基本一样的。这回,我们尝试实现一些新的攻击方法,实现一些新的算法。
1、前面我们小飞机EnemyT1 的攻击方式是垂直向下发射子弹。
那么大飞机EnemyT2的攻击手段就更高级一些,我们让它能够瞄准玩家射击。
大飞机EnemyT2发射子弹是EnemyT2类的私有方法,想要让他能够瞄准玩家,就要知道玩家在哪里。还记得前面我们做的数据仓库么。这回用上了。
我们修改EnemyT2的createBulletObject函数:
void EnemyT2::createBulletObject(PlaneObject_t *target) {
BulletObject_t *but1 = new BulletObject_t();
but1->x = baseInfo.x - PlaneXYScale;
but1->y = baseInfo.y + PlaneXYScale * 2;
but1->visiable = 1;
int sum = abs(target->x - but1->x) + abs(target->y - but1->y);
but1->speedX = 300 * (target->x - but1->x) / sum;
but1->speedY = 300 * (target->y - but1->y) / sum;
getRainbowColor(&but1->color, 200);
ListPushBack(enemyBulletList, (LTDataType) but1);
}
uint8_t EnemyT2::tick(uint32_t t) {
。。。
if (fireTimer.tick(t)) {
if (((PlaneObject_t*) DataBulk::GetInstance()->data1)->visiable)
createBulletObject((PlaneObject_t*) DataBulk::GetInstance()->data1);
if (((PlaneObject_t*) DataBulk::GetInstance()->data2)->visiable)
createBulletObject((PlaneObject_t*) DataBulk::GetInstance()->data2);
}
。。。
}
注意确定子弹方向的算法:
int sum = abs(target->x - but1->x) + abs(target->y - but1->y);
but1->speedX = 300 * (target->x - but1->x) / sum;
but1->speedY = 300 * (target->y - but1->y) / sum;300是子弹速度。
简单通过相似三角形来确定方向和速度,不是很精确,但也足够用了。如果要精确的话,需要用三角函数算分速度,太复杂,没必要。
2、Boss肯定要更强大,我们要让他同时向多个方向发射散弹,同时发射一颗能追踪的导弹。
先给他发射散弹:
void EnemyT3::createBulletObject(int speedX) {
PlaneObject_t *but1 = new PlaneObject_t();
but1->x = baseInfo.x - PlaneXYScale * 2;
but1->y = baseInfo.y + PlaneXYScale;
but1->speedX = speedX;
but1->speedY = 300 - abs(speedX);
but1->visiable = 1;
but1->color = 0xe01000;
ListPushBack(enemyBulletList, (LTDataType) but1);
}
uint8_t EnemyT3::tick(uint32_t t) {
animationStoryBoard->tick(t);
if (fireTimer.tick(t)) {
createBulletObject(-120);
createBulletObject(-70);
createBulletObject(-30);
createBulletObject(0);
createBulletObject(30);
createBulletObject(70);
createBulletObject(120);
}
for (ListNode *node = animationList->next; node != animationList; node =
node->next) {
if (((Animation*) node->data)->isValid) {
((Animation*) node->data)->tick(t);
}
}
return 0;
}
追踪导弹不是直线运动,所以要单独一个链表 enemyRocketList,单独的