spacebox/demo/2d_collision/CollisionTest.cpp

174 lines
6.3 KiB
C++

#include "CollisionTest.hpp"
CollisionTest::CollisionTest() : Game()
{
get_delegate().subscribe(&CollisionTest::respond, this);
load_sdl_context();
enemy.set_color_mod({255, 128, 128, 255});
wooper.load();
enemy.load();
wooper.add_box({80, 200});
enemy.add_box({90, 100});
wooper.add_box({300, 10});
enemy.add_box({90, 200});
wooper.add_box({180, 20});
enemy.add_box({180, 50});
enemy.move({50, 50});
Pixels wooper_pixels = Pixels(wooper);
for (int x = 0; x < wooper.get_w(); x++)
{
wooper_pixels.set(Color(128, 255, 64), x, 12);
}
wooper_pixels.apply();
Box box = {{5, 10}, {20, 4}};
Pixels enemy_pixels = Pixels(enemy, box);
for (int x = -1, y = -1; x > -box.width(); x--, y--)
{
enemy_pixels.set(Color(-1.3, 68.9, 800.8), x, y);
}
enemy_pixels.apply();
canvas = SDL_CreateTexture(get_renderer(), SDL_PIXELFORMAT_RGBA4444, SDL_TEXTUREACCESS_STREAMING, 200, 100);
Pixels canvas_pixels = Pixels(get_renderer(), canvas);
for (int x = 0, y = 0; x < 288; x++, y += x)
{
canvas_pixels.set(Color(x, y, x + y), x, y);
}
canvas_pixels.apply();
Box subsection = Box({5, 10}, {60, 20});
Pixels sub_canvas_pixels = Pixels(get_renderer(), canvas, subsection);
for (int x = 0; x < subsection.width(); x++)
{
for (int y = 0; y < subsection.height(); y++)
{
// *canvas_pixels.operator()<std::uint16_t*>(x, y) = 0xfb60;
*canvas_pixels.operator()<std::uint16_t*>(x, y) = Color(255, 200, 100);
}
}
SDL_Color color = {0, 1, 2, 3};
std::cout << std::boolalpha << (Color(255, 255, 255) == Color(255, 255, 255)) << " " <<
(Color(122.1, 853.8, -1.3) == Color(122, 86, 255)) << " " << (Color(1, 2, 3, 4) == ((SDL_Color){1, 2, 3, 4})) << " " <<
(Color(256, 257, 258, 259) != color) << std::endl;
sub_canvas_pixels.apply();
test_crop(
{
Box({-5, -2}, {10, 5}),
Box({window_box().right() - 30, 10}, {100, 1000}),
Box(window_box().se() - glm::vec2(10, 15), {789, 123}),
Box(window_box().sw() - glm::vec2(1, 1), {5, 5})
});
// std::cout << "out of bounds pixel is " << screen_subsection_pixels.get(0, 0) <<
// " out of bounds pixel is " << screen_subsection_pixels.get(-1, 0) <<
// " in bounds pixel is " << screen_subsection_pixels.get(0, -1) <<
// " out of bounds pixel is " << screen_subsection_pixels.get(-1, -1) << std::endl;
// screen_subsection_pixels.set(Color(255, 0, 0), 0, -1);
// screen_subsection_pixels.set(Color(255, 255, 255), 0, 0);
// screen_subsection_pixels.apply();
}
void CollisionTest::test_crop(const std::vector<Box>& boxes)
{
for (const Box& box : boxes)
{
Pixels screen_subsection_pixels = Pixels(get_renderer(), nullptr, box);
std::cout << box << " cropped by screen to " << screen_subsection_pixels.rect << std::endl;
}
}
void CollisionTest::respond(SDL_Event& event)
{
if (get_delegate().compare(event, "up"))
{
wooper.move_weighted({0, -2});
}
else if (get_delegate().compare(event, "left"))
{
wooper.move_weighted({-2, 0});
}
else if (get_delegate().compare(event, "right"))
{
wooper.move_weighted({2, 0});
}
else if (get_delegate().compare(event, "down"))
{
wooper.move_weighted({0, 2});
}
else if (get_delegate().compare(event, "toggle-collide-all"))
{
collide_all = !collide_all;
}
else if (get_delegate().compare(event, "toggle-collide-all-other"))
{
collide_all_other = !collide_all_other;
}
else if (get_delegate().compare(event, "toggle-precise-collision"))
{
precise = !precise;
}
}
void CollisionTest::update()
{
SDL_SetRenderTarget(get_renderer(), NULL);
SDL_SetRenderDrawColor(get_renderer(), 64, 128, 64, 255);
SDL_RenderClear(get_renderer());
wooper.update();
enemy.update();
SDL_Color white = {255, 255, 255, 255}, red = {255, 0, 0, 255}, color;
Box overlap;
SDL_Rect rect;
for (const Box& box : boxes)
{
color = wooper.collide(box, overlap, precise, collide_all) ? red : white;
SDL_SetRenderTarget(get_renderer(), NULL);
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
rect = box;
SDL_RenderDrawRect(get_renderer(), &rect);
rect = overlap;
SDL_SetRenderDrawColor(get_renderer(), 255, 255, 0, 255);
SDL_RenderDrawRect(get_renderer(), &rect);
}
glm::vec2 intersection;
for (const Segment& segment : segments)
{
color = wooper.collide(segment, intersection, collide_all) ? red : white;
glm::vec2 start = segment.start(), end = segment.end();
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
SDL_RenderDrawLine(get_renderer(), start.x, start.y, end.x, end.y);
SDL_SetRenderDrawColor(get_renderer(), 255, 255, 0, 255);
SDL_RenderDrawPoint(get_renderer(), intersection.x, intersection.y);
}
for (const glm::vec2& point : points)
{
color = wooper.collide(point, collide_all) ? red : white;
SDL_SetRenderDrawColor(get_renderer(), color.r, color.g, color.b, color.a);
SDL_RenderDrawPoint(get_renderer(), point.x, point.y);
}
if (wooper.collide(enemy, overlap, precise, collide_all, collide_all_other))
{
SDL_SetRenderTarget(get_renderer(), nullptr);
SDL_SetRenderDrawColor(get_renderer(), 0, 255, 0, 255);
rect = overlap;
SDL_RenderDrawRect(get_renderer(), &rect);
}
Box screen_subsection_box = Box({0, 0}, {30, 60});
screen_subsection_box.sw(window_box().sw());
Pixels screen_subsection_pixels = Pixels(get_renderer(), nullptr, screen_subsection_box);
for (int x = 0; x < screen_subsection_pixels.rect.w; x++)
{
screen_subsection_pixels.set(Color(255, 0, 255), x, 5);
}
screen_subsection_pixels.apply();
SDL_SetRenderTarget(get_renderer(), nullptr);
Box canvas_box = sfw::get_texture_box(canvas);
canvas_box.nw({340, 200});
SDL_RenderCopyF(get_renderer(), canvas, nullptr, &canvas_box);
}
int main()
{
CollisionTest collision_test = CollisionTest();
collision_test.run();
collision_test.quit();
return 0;
}