能帮到你的话,就给个赞吧 😘
peaBullet.h
#pragma once
#include "bullet.h"
#include "animation.h"
#include "util.h"
extern IMAGE imgPea;
extern Atlas atlasPeaBreak;
class PeaBullet :public Bullet {
public:
PeaBullet();
public:
//碰撞
void onCollide() override; //处理碰撞
public:
void update(int time) override;
void render() override;
private:
//渲染
Animation animationBreak; // 破碎动画
};
peaBullet.cpp
#include "peaBullet.h"
PeaBullet::PeaBullet(){
size.x = 64, size.y = 64;
damage = 10;
animationBreak.setAtlas(&atlasPeaBreak);
animationBreak.setInterval(100);
animationBreak.setIsLoop(false);
animationBreak.setCallback([&] {
isCanRemove = true;
});
}
//重写父类方法,但依旧需要执行父类逻辑
void PeaBullet::onCollide(){
Bullet::onCollide();
//随机播放音乐
switch (rand() % 3){
case 0:
mciSendString(_T("play peaBreak1 from 0"), nullptr, 0, nullptr);
break;
case 1:
mciSendString(_T("play peaBreak1 from 0"), nullptr, 0, nullptr);
break;
case 2:
mciSendString(_T("play peaBreak1 from 2"), nullptr, 0, nullptr);
break;
default:
break;
}
}
void PeaBullet::update(int time){
position += velocity * time;
if (!isValid)
animationBreak.update(time);
if (checkIsExceedScreen())
isCanRemove = true;
}
void PeaBullet::render(){
if (isValid)
putImageAlpha(position.x, position.y, &imgPea);
else
animationBreak.render(position.x, position.y);
}
sunBullet.h
#pragma once
#include "bullet.h"
#include "animation.h"
#include "camera.h"
extern Atlas atlasSun;
extern Atlas atlasSunExplode;
class SunBullet : public Bullet{
public:
void update(int time) override;
void render() override;
public:
SunBullet();
public:
void onCollide();
private:
//运动
const float gravity = 1e-3f;
//渲染
Animation animationIdle; //默认动画
Animation animationExplode; //爆炸动画
Vector2 explodeRenderOffset; //爆炸动画的偏移
};
sunBullet.cpp
#include "sunBullet.h"
void SunBullet::update(int time){
if (isValid) {
velocity.y += gravity * time;
position += velocity * time;
}
if (!isValid)
animationExplode.update(time);
else
animationIdle.update(time);
if (checkIsExceedScreen())
isCanRemove = true;
}
void SunBullet::render(){
if (isValid)
animationIdle.render(position.x, position.y);
else
animationExplode.render(position.x + explodeRenderOffset.x, position.y + explodeRenderOffset.y);
}
SunBullet::SunBullet(){
size.x = 96, size.y = 96;
damage = 20;
animationIdle.setAtlas(&atlasSun);
animationIdle.setInterval(50);
animationExplode.setAtlas(&atlasSunExplode);
animationExplode.setInterval(50);
animationExplode.setIsLoop(false);
animationExplode.setCallback([&] {
isCanRemove = true;
});
auto frameIdle = animationIdle.getFrame();
auto frameExplode = animationExplode.getFrame();
//爆炸动画偏移
explodeRenderOffset.x = (frameIdle->getwidth() - frameExplode->getwidth()) / 2.0;
explodeRenderOffset.y = (frameIdle->getheight() - frameExplode->getheight()) / 2.0;
}
void SunBullet::onCollide(){
Bullet::onCollide();
Camera::getCamera().shake(5, 250);
mciSendString(_T("play sunExplode from 0"), nullptr, 0, nullptr);
}
sunBulletEx.h
#pragma once
#include "bullet.h"
#include "animation.h"
#include "camera.h"
extern Atlas atlasSunEx;
extern Atlas atlasSunExExplode;
class SunBulletEx : public Bullet {
public:
void update(int time) override;
void render() override;
public:
SunBulletEx();
public:
//碰撞
void onCollide();
bool checkCollision(const Vector2& position, const Vector2& size) override;
private:
//渲染
Animation animationIdle; //默认动画
Animation animationExplode; //爆炸动画
Vector2 explodeRenderOffset; //爆炸动画的偏移
};
sunBulletEx.cpp
#include "sunBulletEx.h"
void SunBulletEx::update(int time){
if (isValid)
position += velocity * time;
if (!isValid)
animationExplode.update(time);
else
animationIdle.update(time);
if (checkIsExceedScreen())
isCanRemove = true;
}
void SunBulletEx::render(){
if (isValid)
animationIdle.render(position.x, position.y);
else
animationExplode.render(position.x + explodeRenderOffset.x, position.y + explodeRenderOffset.y);
}
SunBulletEx::SunBulletEx(){
size.x =288, size.y = 288;
damage = 20;
animationIdle.setAtlas(&atlasSunEx);
animationIdle.setInterval(50);
animationExplode.setAtlas(&atlasSunExExplode);
animationExplode.setInterval(50);
animationExplode.setIsLoop(false);
animationExplode.setCallback([&] {
isCanRemove = true;
});
auto frameIdle = animationIdle.getFrame();
auto frameExplode = animationExplode.getFrame();
//爆炸动画偏移
explodeRenderOffset.x = (frameIdle->getwidth() - frameExplode->getwidth()) / 2.0;
explodeRenderOffset.y = (frameIdle->getheight() - frameExplode->getheight()) / 2.0;
}
void SunBulletEx::onCollide(){
Bullet::onCollide();
Camera::getCamera().shake(20, 350);
mciSendString(_T("play sunExplodeEx from 0"), nullptr, 0, nullptr);
}
bool SunBulletEx::checkCollision(const Vector2& position, const Vector2& size){
auto xLeft = this->position.x;
auto xRight = this->position.x + this->size.x;
auto yTop = this->position.y;
auto yDown = this->position.y + this->size.y;
bool isCollideX = max(xRight, position.x + size.x) - min(xLeft, position.x) <= this->size.x + size.x;
bool isCollideY = max(yDown, position.y + size.y) - min(yTop, position.y) <= this->size.y + size.y;
return isCollideX && isCollideY;
}