Skip to content

Commit

Permalink
more edits to snake, enemies, also some optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
evanbowman committed Feb 3, 2020
1 parent 12f930a commit 4475754
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 112 deletions.
12 changes: 8 additions & 4 deletions source/entity/details/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ void Item::on_collision(Platform& pf, Game&, Player&)
void Item::update(Platform&, Game&, Microseconds dt)
{
timer_ += dt;
// Yikes! This is probably expensive...
const Float offset = 3 * float(sine(4 * 3.14 * 0.001f * timer_ + 180)) /
std::numeric_limits<s16>::max();
sprite_.set_position({position_.x, position_.y + offset});

if (visible()) {
// Yikes! This is probably expensive...
const Float offset = 3 * float(sine(4 * 3.14 * 0.001f * timer_ + 180)) /
std::numeric_limits<s16>::max();
sprite_.set_position({position_.x, position_.y + offset});

}
}
14 changes: 7 additions & 7 deletions source/entity/enemies/dasher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,21 @@ void Dasher::update(Platform& pf, Game& game, Microseconds dt)

switch (state_) {
case State::inactive: {
if (manhattan_length(game.player().get_position(), position_) <
std::min(screen_size.x, screen_size.y)) {
state_ = State::idle;
if (visible()) {
timer_ = 0;
if (manhattan_length(game.player().get_position(), position_) <
std::min(screen_size.x, screen_size.y)) {
state_ = State::idle;
}
}
timer_ = 0;
break;
}

case State::idle:
if (timer_ >= milliseconds(200)) {
timer_ -= milliseconds(200);

if (manhattan_length(game.player().get_position(), position_) <
std::min(screen_size.x, screen_size.y)
and random_choice<2>()) {
if (random_choice<2>()) {
state_ = State::shoot_begin;
sprite_.set_texture_index(TextureMap::dasher_weapon1);
} else {
Expand Down
32 changes: 28 additions & 4 deletions source/entity/enemies/snake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@



static constexpr const Float x_move_rate = 0.000028f;
static constexpr const Float x_move_rate = 0.000046f;

// Tiles are wider than they are tall. If we move with the same vertical rate as
// our horizontal rate, the snake segments will end up spaced out when the snake
Expand All @@ -21,7 +21,8 @@ static constexpr const Float y_move_rate = x_move_rate * (12.f / 16.f);


SnakeNode::SnakeNode(SnakeNode* parent) :
parent_(parent)
parent_(parent),
hitbox_{&position_, {16, 16}, {8, 8}}
{
}

Expand Down Expand Up @@ -63,14 +64,14 @@ SnakeHead::SnakeHead(const Vec2<Float>& pos, Game& game)
sprite_.set_position(pos);
sprite_.set_size(Sprite::Size::w16_h32);
sprite_.set_origin({8, 16});
sprite_.set_texture_index(TextureMap::snake_body);
sprite_.set_texture_index(TextureMap::snake_head_profile);

shadow_.set_texture_index(TextureMap::drop_shadow);
shadow_.set_size(Sprite::Size::w16_h32);
shadow_.set_origin({8, -11});
shadow_.set_alpha(Sprite::Alpha::translucent);

game.enemies().spawn<SnakeBody>(pos, this, game, 3);
game.enemies().spawn<SnakeBody>(pos, this, game, 5);
}


Expand All @@ -85,6 +86,8 @@ void SnakeHead::update(Platform& pfrm, Game& game, Microseconds dt)

const auto& player_pos = game.player().get_position();

const auto player_tile = to_quarter_tile_coord(player_pos.cast<s32>());

if (abs(position_.x - player_pos.x) > 80) {
if (position_.x < player_pos.x) {
dir_ = Dir::right;
Expand All @@ -97,6 +100,18 @@ void SnakeHead::update(Platform& pfrm, Game& game, Microseconds dt)
} else if (position_.y > player_pos.y) {
dir_ = Dir::up;
}
} else if (player_tile.x == tile_coord().x) {
if (tile_coord().y < player_tile.y) {
dir_ = Dir::down;
} else {
dir_ = Dir::up;
}
} else if (player_tile.y == tile_coord().y) {
if (tile_coord().x < player_tile.x) {
dir_ = Dir::right;
} else {
dir_ = Dir::left;
}
} else {
if (random_choice<5>() == 0) {
dir_ = static_cast<Dir>(random_choice<4>());
Expand All @@ -119,18 +134,26 @@ void SnakeHead::update(Platform& pfrm, Game& game, Microseconds dt)

switch (dir_) {
case Dir::up:
sprite_.set_texture_index(TextureMap::snake_head_up);
sprite_.set_flip({0, 0});
position_.y -= y_move_rate * dt;
break;

case Dir::down:
sprite_.set_texture_index(TextureMap::snake_head_down);
sprite_.set_flip({0, 0});
position_.y += y_move_rate * dt;
break;

case Dir::left:
sprite_.set_texture_index(TextureMap::snake_head_profile);
sprite_.set_flip({1, 0});
position_.x -= x_move_rate * dt;
break;

case Dir::right:
sprite_.set_texture_index(TextureMap::snake_head_profile);
sprite_.set_flip({0, 0});
position_.x += x_move_rate * dt;
break;
}
Expand Down Expand Up @@ -226,4 +249,5 @@ void SnakeBody::update(Platform& pfrm, Game& game, Microseconds dt)
SnakeTail::SnakeTail(const Vec2<Float>& pos, SnakeNode* parent, Game& game) :
SnakeBody(pos, parent, game, 0)
{
// sprite_.set_texture_index(TextureMap::snake_tail);
}
17 changes: 17 additions & 0 deletions source/entity/enemies/snake.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#pragma once

// NOTE: The snake enemy takes up a lot of resources, we can only realistically
// spawn one per level.



#include "entity/entity.hpp"
#include "tileMap.hpp"
#include "collision.hpp"


class Player;



Expand All @@ -17,9 +24,15 @@ class SnakeNode : public Entity {

const Vec2<TIdx>& tile_coord() const;

const HitBox& hitbox() const
{
return hitbox_;
}

private:
SnakeNode* parent_;
Vec2<TIdx> tile_coord_;
HitBox hitbox_;
};


Expand All @@ -30,6 +43,8 @@ class SnakeHead : public SnakeNode {

void update(Platform& pfrm, Game& game, Microseconds dt);

void on_collision(Platform& pf, Game& game, Player&) {}

const Sprite& get_shadow() const
{
return shadow_;
Expand All @@ -51,6 +66,8 @@ class SnakeBody : public SnakeNode {

void update(Platform& pfrm, Game& game, Microseconds dt);

void on_collision(Platform& pf, Game& game, Player&) {}

const Sprite& get_shadow() const
{
return shadow_;
Expand Down
8 changes: 5 additions & 3 deletions source/entity/enemies/turret.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ void Turret::update(Platform& pfrm, Game& game, Microseconds dt)
const auto& screen_size = pfrm.screen().size();
switch (state_) {
case State::closed:
if (manhattan_length(player_pos, position_) <
std::min(screen_size.x, screen_size.y) / 2) {
state_ = State::opening;
if (visible()) {
if (manhattan_length(player_pos, position_) <
std::min(screen_size.x, screen_size.y) / 2) {
state_ = State::opening;
}
}
break;

Expand Down
13 changes: 13 additions & 0 deletions source/entity/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ class Entity {
static constexpr bool multiface_sprite = false;


bool visible() const { return visible_; }

// This is VERY BAD CODE. Basically, the rendering loop already determines
// which objects are visible within the window when drawing sprites. To save
// CPU cycles, we are marking an object visible during a rendering pass, so
// that the game logic skip updates for certain Entities outside the window.
void mark_visible(bool visible)
{
visible_ = visible;
}


protected:
void debit_health(Health amount)
{
Expand All @@ -61,6 +73,7 @@ class Entity {

private:
Health health_;
bool visible_ = false;
};


Expand Down
12 changes: 12 additions & 0 deletions source/entity/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ void Player::on_collision(Platform& pf, Game& game, OrbShot&)
}


void Player::on_collision(Platform& pf, Game& game, SnakeHead&)
{
Player::injured(pf, Health(1));
}


void Player::on_collision(Platform& pf, Game& game, SnakeBody&)
{
Player::injured(pf, Health(1));
}


void Player::on_collision(Platform& pf, Game& game, Critter&)
{
Player::injured(pf, Health(1));
Expand Down
5 changes: 4 additions & 1 deletion source/entity/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ class Turret;
class Probe;
class Item;
class OrbShot;

class SnakeHead;
class SnakeBody;

class Player : public Entity {
public:
Player();

void on_collision(Platform& pf, Game& game, SnakeHead&);
void on_collision(Platform& pf, Game& game, SnakeBody&);
void on_collision(Platform& pf, Game& game, OrbShot&);
void on_collision(Platform& pf, Game& game, Critter&);
void on_collision(Platform& pf, Game& game, Dasher&);
Expand Down
49 changes: 33 additions & 16 deletions source/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,52 +49,69 @@ HOT void Game::render(Platform& pfrm)
{
Buffer<const Sprite*, Platform::Screen::sprite_limit> display_buffer;

display_buffer.push_back(&player_.get_sprite());

auto show_sprite = [&](const Sprite& spr) {
if (within_view_frustum(pfrm.screen(), spr.get_position())) {
display_buffer.push_back(&spr);
auto show_sprite = [&](Entity& e) {
if (within_view_frustum(pfrm.screen(), e.get_sprite().get_position())) {
display_buffer.push_back(&e.get_sprite());
e.mark_visible(true);
} else {
e.mark_visible(false);
}
};

auto show_sprites = [&](auto& entity_buf) {
for (auto it = entity_buf.begin(); it not_eq entity_buf.end(); ++it) {
show_sprite((*it)->get_sprite());
show_sprite(**it);
}
};

// Draw the effects first. Effects are not subject to z-ordering like
// overworld objects, therefore, faster to draw.
effects_.transform(show_sprites);
for (auto spr : display_buffer) {
pfrm.screen().draw(*spr);
}
display_buffer.clear();

display_buffer.push_back(&player_.get_sprite());

Buffer<const Sprite*, 30> shadows_buffer;

enemies_.transform([&](auto& entity_buf) {
for (auto& entity : entity_buf) {
if constexpr (std::remove_reference<decltype(
*entity)>::type::multiface_sprite) {
const auto sprs = entity->get_sprites();
if (within_view_frustum(pfrm.screen(), sprs[0]->get_position())) {
if (within_view_frustum(pfrm.screen(), entity->get_position())) {

entity->mark_visible(true);

if constexpr (std::remove_reference<decltype(
*entity)>::type::multiface_sprite) {

const auto sprs = entity->get_sprites();

for (const auto& spr : sprs) {
display_buffer.push_back(spr);
}

shadows_buffer.push_back(&entity->get_shadow());
}
} else {
const auto& spr = entity->get_sprite();
if (within_view_frustum(pfrm.screen(), spr.get_position())) {

} else {
const auto& spr = entity->get_sprite();
display_buffer.push_back(&spr);
shadows_buffer.push_back(&entity->get_shadow());
}
} else {
entity->mark_visible(false);
}
}
});
details_.transform(show_sprites);
effects_.transform(show_sprites);

std::sort(display_buffer.begin(),
display_buffer.end(),
[](const auto& l, const auto& r) {
return l->get_position().y > r->get_position().y;
});

show_sprite(transporter_.get_sprite());
show_sprite(transporter_);

display_buffer.push_back(&player_.get_shadow());

Expand Down
2 changes: 1 addition & 1 deletion source/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class Game {
return tiles_;
}

using EnemyGroup = EntityGroup<10,
using EnemyGroup = EntityGroup<20,
Turret,
Dasher,
Probe,
Expand Down
2 changes: 1 addition & 1 deletion source/graphics/bgr_spritesheet.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// + 1024 tiles Metatiled by 2x4 not compressed
// Total size: 512 + 32768 = 33280
//
// Time-stamp: 2020-02-01, 16:31:26
// Time-stamp: 2020-02-02, 21:20:30
// Exported by Cearn's GBA Image Transmogrifier, v
// ( http://www.coranac.com/projects/#grit )
//
Expand Down
Loading

0 comments on commit 4475754

Please sign in to comment.