- depth buffer implementat
- localització de sprites en pantalla
This commit is contained in:
80
main.cpp
80
main.cpp
@@ -4,7 +4,8 @@
|
|||||||
#include "jdebug.h"
|
#include "jdebug.h"
|
||||||
|
|
||||||
#define M_PI 3.14159265358979323846
|
#define M_PI 3.14159265358979323846
|
||||||
#define DEG_TO_RAD M_PI/180.0f
|
#define DEG_TO_RAD (M_PI/180.0f)
|
||||||
|
#define RAD_TO_DEG (180.0f/M_PI)
|
||||||
|
|
||||||
struct vec2 { float x, y; };
|
struct vec2 { float x, y; };
|
||||||
struct wall { Uint16 v1, v2; vec2 normal; float u1, u2; int portal; };
|
struct wall { Uint16 v1, v2; vec2 normal; float u1, u2; int portal; };
|
||||||
@@ -22,6 +23,7 @@ SDL_Texture *sdl_texture;
|
|||||||
Uint32 *palette;
|
Uint32 *palette;
|
||||||
Uint8 *gif;
|
Uint8 *gif;
|
||||||
Uint8 screen[320*240];
|
Uint8 screen[320*240];
|
||||||
|
float depth_buffer[320*240];
|
||||||
|
|
||||||
std::vector<sector> sectors;
|
std::vector<sector> sectors;
|
||||||
int current_sector;
|
int current_sector;
|
||||||
@@ -94,6 +96,13 @@ void putp(int x, int y, Uint8 color)
|
|||||||
screen[x+y*320]=color;
|
screen[x+y*320]=color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void putpd(int x, int y, Uint8 color, float depth)
|
||||||
|
{
|
||||||
|
if (x<0 || y<0 || x>=320 || y>=240) return;
|
||||||
|
screen[x+y*320]=color;
|
||||||
|
depth_buffer[x+y*320]=depth;
|
||||||
|
}
|
||||||
|
|
||||||
void line(int x1, int y1, int x2, int y2, Uint8 color)
|
void line(int x1, int y1, int x2, int y2, Uint8 color)
|
||||||
{
|
{
|
||||||
float dx = float(x2-x1);
|
float dx = float(x2-x1);
|
||||||
@@ -205,7 +214,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
vec2 normal = { SDL_cosf(angle*DEG_TO_RAD), SDL_sinf(angle*DEG_TO_RAD) };
|
vec2 normal = { SDL_cosf(angle*DEG_TO_RAD), SDL_sinf(angle*DEG_TO_RAD) };
|
||||||
vec2 result, tmp_result;
|
vec2 result, tmp_result;
|
||||||
wall *w = nullptr;
|
wall *w = nullptr;
|
||||||
float dist=100000.0f;
|
float stright_dist=100000.0f;
|
||||||
|
|
||||||
for (auto &wall : s.walls)
|
for (auto &wall : s.walls)
|
||||||
{
|
{
|
||||||
@@ -213,8 +222,8 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
if (get_line_intersection(position, infi, s.verts[wall.v1], s.verts[wall.v2], &tmp_result))
|
if (get_line_intersection(position, infi, s.verts[wall.v1], s.verts[wall.v2], &tmp_result))
|
||||||
{
|
{
|
||||||
const float d = distance(position, tmp_result);// * SDL_cosf(a_inc*DEG_TO_RAD);
|
const float d = distance(position, tmp_result);// * SDL_cosf(a_inc*DEG_TO_RAD);
|
||||||
if (d<dist) {
|
if (d<stright_dist) {
|
||||||
dist = d;
|
stright_dist = d;
|
||||||
result = tmp_result;
|
result = tmp_result;
|
||||||
w = &wall;
|
w = &wall;
|
||||||
}
|
}
|
||||||
@@ -226,7 +235,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
const float sector_height = s.ceiling_height - s.floor_height;
|
const float sector_height = s.ceiling_height - s.floor_height;
|
||||||
|
|
||||||
map::putp(result.x, result.y, 6);
|
map::putp(result.x, result.y, 6);
|
||||||
dist *= SDL_cosf(a_inc*DEG_TO_RAD);
|
float dist = stright_dist * SDL_cosf(a_inc*DEG_TO_RAD);
|
||||||
const vec2 AB = {s.verts[w->v2].x-s.verts[w->v1].x, s.verts[w->v2].y-s.verts[w->v1].y};
|
const vec2 AB = {s.verts[w->v2].x-s.verts[w->v1].x, s.verts[w->v2].y-s.verts[w->v1].y};
|
||||||
const vec2 AP = {result.x-s.verts[w->v1].x, result.y-s.verts[w->v1].y};
|
const vec2 AP = {result.x-s.verts[w->v1].x, result.y-s.verts[w->v1].y};
|
||||||
float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = (v-int(v))*tex_height;
|
float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = (v-int(v))*tex_height;
|
||||||
@@ -249,7 +258,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
|
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
|
||||||
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) - position.x)) % tex_height;
|
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) - position.x)) % tex_height;
|
||||||
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) - position.y)) % tex_height;
|
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) - position.y)) % tex_height;
|
||||||
putp(screen_column, y, gif[tx+ty*tex_height]);
|
putpd(screen_column, y, gif[tx+ty*tex_height], straight_dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -258,7 +267,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
// Pinta la pared
|
// Pinta la pared
|
||||||
for (int i=0; i<wall_height; ++i) {
|
for (int i=0; i<wall_height; ++i) {
|
||||||
if (wall_start+i>=end) break;
|
if (wall_start+i>=end) break;
|
||||||
putp(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]);
|
putpd(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
|
||||||
cpix += dpix;
|
cpix += dpix;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -272,7 +281,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
// Pinta la pared
|
// Pinta la pared
|
||||||
for (int i=0; i<upper_wall_height; ++i) {
|
for (int i=0; i<upper_wall_height; ++i) {
|
||||||
if (wall_start+i>=end) break;
|
if (wall_start+i>=end) break;
|
||||||
putp(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]);
|
putpd(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
|
||||||
cpix += dpix;
|
cpix += dpix;
|
||||||
}
|
}
|
||||||
wall_start += upper_wall_height;
|
wall_start += upper_wall_height;
|
||||||
@@ -293,7 +302,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
// Pinta la pared
|
// Pinta la pared
|
||||||
for (int i=0; i<lower_wall_height; ++i) {
|
for (int i=0; i<lower_wall_height; ++i) {
|
||||||
if (wall_end+i>=end) break;
|
if (wall_end+i>=end) break;
|
||||||
putp(screen_column, wall_end+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]);
|
putpd(screen_column, wall_end+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
|
||||||
cpix += dpix;
|
cpix += dpix;
|
||||||
}
|
}
|
||||||
//wall_start += upper_wall_height;
|
//wall_start += upper_wall_height;
|
||||||
@@ -309,7 +318,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
|
|||||||
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
|
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
|
||||||
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) + position.x)) % tex_height;
|
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) + position.x)) % tex_height;
|
||||||
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % tex_height;
|
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % tex_height;
|
||||||
putp(screen_column, y, gif[tx+ty*tex_height]);
|
putpd(screen_column, y, gif[tx+ty*tex_height], straight_dist);
|
||||||
}
|
}
|
||||||
//line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5);
|
//line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5);
|
||||||
}
|
}
|
||||||
@@ -360,6 +369,34 @@ bool tryMove(float angle, float speed)
|
|||||||
return moved;
|
return moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float is_enemy_in_fov(double Ax, double Ay, double orientation_deg,
|
||||||
|
double Bx, double By) {
|
||||||
|
// Convert orientation angle to radians
|
||||||
|
double orientation_rad = orientation_deg * DEG_TO_RAD;
|
||||||
|
|
||||||
|
// Compute view direction vector from angle
|
||||||
|
double view_dx = SDL_cosf(orientation_rad);
|
||||||
|
double view_dy = SDL_sinf(orientation_rad);
|
||||||
|
|
||||||
|
// Vector from A to B
|
||||||
|
double to_enemy_dx = Bx - Ax;
|
||||||
|
double to_enemy_dy = By - Ay;
|
||||||
|
|
||||||
|
// Normalize both vectors
|
||||||
|
double len = SDL_sqrtf(to_enemy_dx * to_enemy_dx + to_enemy_dy * to_enemy_dy);
|
||||||
|
if (len == 0) return 0.0; // Same position
|
||||||
|
|
||||||
|
to_enemy_dx /= len;
|
||||||
|
to_enemy_dy /= len;
|
||||||
|
|
||||||
|
// Compute signed angle using atan2 of perp-dot and dot
|
||||||
|
double dot = view_dx * to_enemy_dx + view_dy * to_enemy_dy;
|
||||||
|
double cross = view_dx * to_enemy_dy - view_dy * to_enemy_dx;
|
||||||
|
|
||||||
|
float angle_rad = SDL_atan2f(cross, dot);
|
||||||
|
return angle_rad * RAD_TO_DEG; // Signed angle in degrees
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
@@ -460,7 +497,7 @@ int main(int argc, char *argv[])
|
|||||||
sector &s = sectors[current_sector];
|
sector &s = sectors[current_sector];
|
||||||
|
|
||||||
// Clear screen
|
// Clear screen
|
||||||
SDL_memset4(screen, 0x00000000, (320*240)>>2);
|
//SDL_memset4(screen, 0x00000000, (320*240)>>2);
|
||||||
|
|
||||||
int screen_column = 0;
|
int screen_column = 0;
|
||||||
for (float a_inc=-32.0f; a_inc<=32.0f; a_inc+=0.2f)
|
for (float a_inc=-32.0f; a_inc<=32.0f; a_inc+=0.2f)
|
||||||
@@ -474,6 +511,27 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
screen_column++;
|
screen_column++;
|
||||||
}
|
}
|
||||||
|
debug::print("angle:");debug::print(orientation);debug::newline();
|
||||||
|
|
||||||
|
vec2 enemy = {256.0f, 256.0f};
|
||||||
|
map::putp(enemy.x, enemy.y, 9);
|
||||||
|
|
||||||
|
float angle_to_enemy = is_enemy_in_fov(position.x, position.y, orientation, enemy.x, enemy.y);
|
||||||
|
if (SDL_fabsf(angle_to_enemy) <= 32.0f)
|
||||||
|
{
|
||||||
|
debug::print("enemy in fov: "); debug::print(angle_to_enemy); debug::newline();
|
||||||
|
int column = int((angle_to_enemy+32.0f)/0.2f);
|
||||||
|
line(column, 0, column, 239, 0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
float angle = SDL_atan2f(enemy.y-position.y, enemy.x-position.x)*RAD_TO_DEG;
|
||||||
|
if (SDL_abs(angle) <= 32.0f)
|
||||||
|
{
|
||||||
|
const float d = distance(position, enemy);// * SDL_cosf(a_inc*DEG_TO_RAD);
|
||||||
|
debug::print("enemy angle:");debug::print(angle);debug::newline();
|
||||||
|
debug::print("enemy dist:");debug::print(d);debug::newline();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Draw map walls
|
// Draw map walls
|
||||||
int sec = 0;
|
int sec = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user