2018-08-09 11:35:52 +02:00
|
|
|
//
|
|
|
|
// Created by Wouter Groeneveld on 09/08/18.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <libgba-sprite-engine/sprites/sprite_builder.h>
|
|
|
|
#include <libgba-sprite-engine/gba_engine.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <libgba-sprite-engine/background/text_stream.h>
|
|
|
|
#include "food_scene.h"
|
|
|
|
#include "avatar.h"
|
|
|
|
#include "bullet.h"
|
|
|
|
|
|
|
|
#define AVATAR_ROTATION_DIFF 300
|
|
|
|
#define MAX_AMOUNT_OF_BULLETS 40
|
2018-08-09 12:35:05 +02:00
|
|
|
#define BULLET_COOLDOWN_START 20
|
2018-08-09 11:35:52 +02:00
|
|
|
|
2018-08-09 12:35:05 +02:00
|
|
|
FoodScene::FoodScene(const std::shared_ptr<GBAEngine> &engine) : Scene(engine), bulletCooldown(BULLET_COOLDOWN_START) {}
|
2018-08-09 11:35:52 +02:00
|
|
|
|
|
|
|
std::vector<Background *> FoodScene::backgrounds() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Sprite *> FoodScene::sprites() {
|
2018-08-09 12:35:05 +02:00
|
|
|
std::vector<Sprite*> sprites;
|
|
|
|
// TODO order is important for affine transformations because of affinity - those always last!
|
|
|
|
// some kind of affine bug depending on the order of sprites added in OAM
|
2018-08-09 11:35:52 +02:00
|
|
|
for(auto& b : bullets) {
|
2018-08-09 12:35:05 +02:00
|
|
|
sprites.push_back(b.get());
|
2018-08-09 11:35:52 +02:00
|
|
|
}
|
2018-08-09 12:35:05 +02:00
|
|
|
sprites.push_back(someBullet.get());
|
|
|
|
sprites.push_back(avatar.get());
|
2018-08-09 11:35:52 +02:00
|
|
|
|
|
|
|
return sprites;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FoodScene::removeBulletsOffScreen() {
|
|
|
|
bullets.erase(
|
|
|
|
std::remove_if(bullets.begin(), bullets.end(), [](std::unique_ptr<Sprite> &s) { return s->isOffScreen(); }),
|
|
|
|
bullets.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
void FoodScene::tick(u16 keys) {
|
|
|
|
avatar->animateToFrame(0);
|
2018-08-09 12:35:05 +02:00
|
|
|
bool bulletAdded, allowedToShoot;
|
|
|
|
|
|
|
|
if(bulletCooldown > 0) {
|
|
|
|
bulletCooldown--;
|
|
|
|
} else if(bulletCooldown == 0) {
|
|
|
|
allowedToShoot = true;
|
|
|
|
}
|
2018-08-09 11:35:52 +02:00
|
|
|
|
2018-08-09 12:35:05 +02:00
|
|
|
removeBulletsOffScreen();
|
2018-08-09 11:35:52 +02:00
|
|
|
TextStream::instance().setText(std::to_string(bullets.size()) + std::string(" bullets"), 1, 1);
|
2018-08-09 12:35:05 +02:00
|
|
|
TextStream::instance().setText(std::to_string(bulletCooldown) + std::string(" cooldown"), 2, 1);
|
2018-08-09 11:35:52 +02:00
|
|
|
|
|
|
|
if(keys & KEY_LEFT) {
|
|
|
|
avatarRotation -= AVATAR_ROTATION_DIFF;
|
|
|
|
} else if(keys & KEY_RIGHT) {
|
|
|
|
avatarRotation += AVATAR_ROTATION_DIFF;
|
|
|
|
}
|
2018-08-09 12:35:05 +02:00
|
|
|
if((keys & KEY_A) && allowedToShoot) {
|
|
|
|
avatar->animateToFrame(1);
|
|
|
|
|
2018-08-09 11:35:52 +02:00
|
|
|
if(bullets.size() < MAX_AMOUNT_OF_BULLETS) {
|
2018-08-09 12:35:05 +02:00
|
|
|
bulletCooldown = BULLET_COOLDOWN_START;
|
2018-08-09 11:35:52 +02:00
|
|
|
bullets.push_back(createBullet());
|
2018-08-09 12:35:05 +02:00
|
|
|
bulletAdded = true;
|
2018-08-09 11:35:52 +02:00
|
|
|
|
2018-08-09 12:35:05 +02:00
|
|
|
auto &b = bullets.at(bullets.size() - 1);
|
2018-08-09 11:35:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
avatar->rotate(avatarRotation);
|
2018-08-09 12:35:05 +02:00
|
|
|
|
|
|
|
if(bulletAdded) {
|
|
|
|
engine->updateSpritesInScene();
|
|
|
|
}
|
2018-08-09 11:35:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<Sprite> FoodScene::createBullet() {
|
2018-08-09 12:35:05 +02:00
|
|
|
return spriteBuilder->withVelocity(1, 1)
|
2018-08-09 11:35:52 +02:00
|
|
|
.withLocation(avatar->getX(), avatar->getY())
|
2018-08-09 12:35:05 +02:00
|
|
|
.buildWithDataOf(*someBullet.get());
|
2018-08-09 11:35:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void FoodScene::load() {
|
|
|
|
foregroundPalette = std::unique_ptr<ForegroundPaletteManager>(new ForegroundPaletteManager(avatar_palette, sizeof(avatar_palette)));
|
|
|
|
backgroundPalette = std::unique_ptr<BackgroundPaletteManager>(new BackgroundPaletteManager());
|
|
|
|
|
|
|
|
spriteBuilder = std::unique_ptr<SpriteBuilder<Sprite>>(new SpriteBuilder<Sprite>);
|
|
|
|
SpriteBuilder<AffineSprite> affineBuilder;
|
|
|
|
|
|
|
|
// Doom avatar copyright iD Software
|
|
|
|
avatar = affineBuilder.withData(avatar_data, sizeof(avatar_data))
|
|
|
|
.withSize(SIZE_64_64)
|
|
|
|
.withAnimated(2, 3)
|
|
|
|
.withLocation(GBA_SCREEN_WIDTH / 2 - 32, GBA_SCREEN_HEIGHT / 2 - 32)
|
|
|
|
.buildPtr();
|
|
|
|
avatar->stopAnimating();
|
|
|
|
avatarRotation = 0;
|
|
|
|
|
2018-08-09 12:35:05 +02:00
|
|
|
someBullet = spriteBuilder->withData(bullet_data, sizeof(bullet_data))
|
|
|
|
.withSize(SIZE_16_16)
|
|
|
|
.withLocation(GBA_SCREEN_WIDTH + 20, GBA_SCREEN_HEIGHT + 20)
|
|
|
|
.buildPtr();
|
2018-08-09 11:35:52 +02:00
|
|
|
}
|