diff --git a/doc/013.png b/doc/013.png new file mode 100644 index 0000000..98263a4 Binary files /dev/null and b/doc/013.png differ diff --git a/framebuffer.cpp b/framebuffer.cpp index 860679d..d5715e4 100644 --- a/framebuffer.cpp +++ b/framebuffer.cpp @@ -27,4 +27,3 @@ void FrameBuffer::clear(const uint32_t color) { img = std::vector(w*h, color); } - diff --git a/monsters.png b/monsters.png index 637e371..ee99b3a 100644 Binary files a/monsters.png and b/monsters.png differ diff --git a/sprite.h b/sprite.h new file mode 100644 index 0000000..8dcc710 --- /dev/null +++ b/sprite.h @@ -0,0 +1,12 @@ +#ifndef SPRITE_H +#define SPRITE_H + +#include + +struct Sprite { + float x, y; + size_t tex_id; +}; + +#endif // SPRITE_H + diff --git a/textures.h b/textures.h index a833bcb..2f5533a 100644 --- a/textures.h +++ b/textures.h @@ -7,7 +7,7 @@ struct Texture { std::vector img; // textures storage container Texture(const std::string filename); - uint32_t &get(const size_t i, const size_t j, const size_t idx); // get the pixel (i,j) from the textrue idx + uint32_t &get(const size_t i, const size_t j, const size_t idx); // get the pixel (i,j) from the texture idx std::vector get_scaled_column(const size_t texture_id, const size_t tex_coord, const size_t column_height); // retrieve one column (tex_coord) from the texture texture_id and scale it to the destination size }; diff --git a/tinyraycaster.cpp b/tinyraycaster.cpp index d5ff79f..bc00c75 100644 --- a/tinyraycaster.cpp +++ b/tinyraycaster.cpp @@ -10,22 +10,29 @@ #include "map.h" #include "utils.h" #include "player.h" +#include "sprite.h" #include "framebuffer.h" #include "textures.h" -int wall_x_texcoord(const float x, const float y, Texture &tex_walls) { - float hitx = x - floor(x+.5); // hitx and hity contain (signed) fractional parts of x and y, - float hity = y - floor(y+.5); // they vary between -0.5 and +0.5, and one of them is supposed to be very close to 0 - int tex = hitx*tex_walls.size; - if (std::abs(hity)>std::abs(hitx)) // we need to determine whether we hit a "vertical" or a "horizontal" wall (w.r.t the map) - tex = hity*tex_walls.size; +int wall_x_texcoord(const float hitx, const float hity, Texture &tex_walls) { + float x = hitx - floor(hitx+.5); // x and y contain (signed) fractional parts of hitx and hity, + float y = hity - floor(hity+.5); // they vary between -0.5 and +0.5, and one of them is supposed to be very close to 0 + int tex = x*tex_walls.size; + if (std::abs(y)>std::abs(x)) // we need to determine whether we hit a "vertical" or a "horizontal" wall (w.r.t the map) + tex = y*tex_walls.size; if (tex<0) // do not forget x_texcoord can be negative, fix that tex += tex_walls.size; assert(tex>=0 && tex<(int)tex_walls.size); return tex; } -void render(FrameBuffer &fb, Map &map, Player &player, Texture &tex_walls) { +void map_show_sprite(Sprite &sprite, FrameBuffer &fb, Map &map) { + const size_t rect_w = fb.w/(map.w*2); // size of one map cell on the screen + const size_t rect_h = fb.h/map.h; + fb.draw_rectangle(sprite.x*rect_w-3, sprite.y*rect_h-3, 6, 6, pack_color(255, 0, 0)); +} + +void render(FrameBuffer &fb, Map &map, Player &player, std::vector &sprites, Texture &tex_walls, Texture &tex_monst) { fb.clear(pack_color(255, 255, 255)); // clear the screen const size_t rect_w = fb.w/(map.w*2); // size of one map cell on the screen @@ -52,7 +59,8 @@ void render(FrameBuffer &fb, Map &map, Player &player, Texture &tex_walls) { size_t texid = map.get(x, y); // our ray touches a wall, so draw the vertical column to create an illusion of 3D assert(texid column = tex_walls.get_scaled_column(texid, x_texcoord, column_height); int pix_x = i + fb.w/2; // we are drawing at the right half of the screen, thus +fb.w/2 @@ -65,6 +73,10 @@ void render(FrameBuffer &fb, Map &map, Player &player, Texture &tex_walls) { break; } // ray marching loop } // field of view ray sweeping + + for (size_t i=0; i sprites{ {1.834, 8.765, 0}, {5.323, 5.365, 1}, {4.123, 10.265, 1} }; - for (size_t frame=0; frame<360; frame++) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(5) << frame << ".ppm"; - player.a += 2*M_PI/360; - - render(fb, map, player, tex_walls); - drop_ppm_image(ss.str(), fb.img, fb.w, fb.h); - } + render(fb, map, player, sprites, tex_walls, tex_monst); + drop_ppm_image("./out.ppm", fb.img, fb.w, fb.h); return 0; }