Broken implementation of collision code.
I'm trying to get it working.
This commit is contained in:
parent
37f7964388
commit
94080546e5
5 changed files with 154 additions and 25 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 546bd7e270b486aa8b7e898a0e3008baa84ef6d8
|
||||
Subproject commit 50ebba1c3157196d142bc06ebf2d290c7702b084
|
|
@ -21,7 +21,6 @@
|
|||
#include "inputbag.hpp"
|
||||
#include "gameactions.hpp"
|
||||
#include "worldgrid.hpp"
|
||||
#include "grid_raytrace.hpp"
|
||||
#include "drawing_queue.hpp"
|
||||
#include "worldviewport.hpp"
|
||||
#include "texture.hpp"
|
||||
|
@ -72,29 +71,13 @@ namespace curry {
|
|||
|
||||
WorldGrid& world = this->world();
|
||||
|
||||
const vec2us character_tile = pixel_to_world_tile(world, position());
|
||||
vec2us stop_at = pixel_to_world_tile(world, old_pos);
|
||||
auto is_walkable = [&world,&stop_at](vec2us idx) {
|
||||
const bool walkable = world.tile_property(world.tile(idx)).walkable;
|
||||
if (walkable)
|
||||
stop_at = idx;
|
||||
else
|
||||
std::cout << "found non-walkable tile at " << idx << '\n';
|
||||
return walkable;
|
||||
};
|
||||
|
||||
for_each_voxel_under_segment(old_pos, this->position(), width_height(), world, is_walkable, false);
|
||||
|
||||
if (character_tile != stop_at) {
|
||||
vec2f blocked_pos = world_tile_to_pixel(world, stop_at);
|
||||
vec2f new_pos = position();
|
||||
if (character_tile.x() != stop_at.x())
|
||||
new_pos.x() = blocked_pos.x();
|
||||
if (character_tile.y() != stop_at.y())
|
||||
new_pos.y() = blocked_pos.y();
|
||||
|
||||
this->set_position(new_pos);
|
||||
}
|
||||
const vec2f new_pos = m_collider.try_reach_tile(
|
||||
texture()->width_height() / world.tile_size(),
|
||||
old_pos,
|
||||
position(),
|
||||
world
|
||||
);
|
||||
this->set_position(new_pos);
|
||||
}
|
||||
|
||||
void Character::set_speed (float parSpeed) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "rect.hpp"
|
||||
#include "world_moveable.hpp"
|
||||
#include "drawable.hpp"
|
||||
#include "collider.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
|
@ -47,6 +48,7 @@ namespace curry {
|
|||
virtual void on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) override;
|
||||
|
||||
cloonel::InputBag* m_input_bag;
|
||||
Collider m_collider;
|
||||
float m_speed;
|
||||
};
|
||||
} //namespace curry
|
||||
|
|
101
src/gamelib/collider.cpp
Normal file
101
src/gamelib/collider.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "collider.hpp"
|
||||
#include "grid_raytrace.hpp"
|
||||
#include "worldgrid.hpp"
|
||||
#include "vectorwrapper/sequence_range.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
vec2us collision_borders (const vec2us& parObjSize, const vec2f& parDirection) {
|
||||
assert(parObjSize > 0);
|
||||
const uint16_t horz_offs = (parDirection.x() > 0.0f ? static_cast<uint16_t>(parObjSize.x() - 1) : 0);
|
||||
const uint16_t vert_offs = (parDirection.y() > 0.0f ? static_cast<uint16_t>(parObjSize.y() - 1) : 0);
|
||||
return vec2us(horz_offs, vert_offs);
|
||||
}
|
||||
|
||||
vec2us check_tiles_count (const vec2us& parObjSize, const vec2f& parDirection) {
|
||||
assert(parObjSize > 0);
|
||||
const uint16_t horz = (parDirection.y() != 0.0f ? parObjSize.x() : 0);
|
||||
const uint16_t vert = (parDirection.x() != 0.0f ? parObjSize.y() : 0);
|
||||
return vec2us(horz, vert);
|
||||
}
|
||||
|
||||
vec2f make_pixel_side_offset (
|
||||
const vec2us& parTileSize,
|
||||
const vec2us& parSideOffset,
|
||||
const vec2f& parDirection
|
||||
) {
|
||||
const vec2f tile_size = vector_cast<vec2f>(parTileSize);
|
||||
vec2f tile_start = tile_size * vector_cast<vec2f>(parSideOffset);
|
||||
if (parDirection.x() > 0.0f)
|
||||
tile_start.x() += tile_size.x() - 1.0f;
|
||||
if (parDirection.y() > 0.0f)
|
||||
tile_start.y() += tile_size.y() - 1.0f;
|
||||
return tile_start;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
vec2f Collider::try_reach_tile (
|
||||
const vec2us& parObjectSize,
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
const WorldGrid& parWorld
|
||||
) {
|
||||
const vec2f direction = parTo - parFrom;
|
||||
std::cout << "direction: " << direction << ' ';
|
||||
if (direction == 0.0f)
|
||||
return parTo;
|
||||
|
||||
const vec2us side_offset = collision_borders(parObjectSize, direction);
|
||||
const vec2us length = check_tiles_count(parObjectSize, direction);
|
||||
std::cout << "side_offset: " << side_offset << " length: " << length << '\n';
|
||||
const vec2us dest_tile = pixel_to_world_tile(parWorld, parTo);
|
||||
vec2us stop_at = pixel_to_world_tile(parWorld, parFrom);
|
||||
vec2f tile_relative_offs = parTo - world_tile_to_pixel(parWorld, dest_tile);
|
||||
assert(tile_relative_offs < vector_cast<vec2f>(parWorld.tile_size()));
|
||||
|
||||
auto forward_callback = [=,&parWorld,&stop_at,&tile_relative_offs](vec2us tile) {
|
||||
for (auto curr_pos : vwr::increasing_sequence_range<vec2us>(tile, tile + parObjectSize)) {
|
||||
const bool walkable = parWorld.tile_property(parWorld.tile(curr_pos)).walkable;
|
||||
if (not walkable) {
|
||||
tile_relative_offs = vec2f(0.0f);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
stop_at = tile - side_offset;
|
||||
return true;
|
||||
};
|
||||
|
||||
const vec2f pix_side_offset =
|
||||
make_pixel_side_offset(parWorld.tile_size(), side_offset, direction);
|
||||
for_each_voxel_under_segment(
|
||||
parFrom + pix_side_offset,
|
||||
parTo + pix_side_offset,
|
||||
parObjectSize,
|
||||
parWorld,
|
||||
forward_callback,
|
||||
false
|
||||
);
|
||||
|
||||
return world_tile_to_pixel(parWorld, stop_at) + tile_relative_offs - pix_side_offset;
|
||||
}
|
||||
} //namespace curry
|
43
src/gamelib/collider.hpp
Normal file
43
src/gamelib/collider.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "rect.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace curry {
|
||||
class WorldGrid;
|
||||
|
||||
class Collider {
|
||||
public:
|
||||
Collider() = default;
|
||||
~Collider() = default;
|
||||
|
||||
vec2f try_reach_tile (
|
||||
const vec2us& parObjectSize,
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
const WorldGrid& parWorld
|
||||
);
|
||||
|
||||
private:
|
||||
};
|
||||
} //namespace curry
|
Loading…
Reference in a new issue