diff --git a/Faceball2030/assets/enemies/bullet.mtl b/Faceball2030/assets/enemies/bullet.mtl new file mode 100644 index 0000000..26644d3 --- /dev/null +++ b/Faceball2030/assets/enemies/bullet.mtl @@ -0,0 +1,11 @@ +# Exported from Wings 3D 2.2.9 +newmtl sphere1_auv +Ns 19.999999999999996 +d 1.0 +illum 2 +Kd 1.0 1.0 1.0 +Ka 0.0 0.0 0.0 +Ks 0.19 0.19 0.19 +Ke 0.0 0.0 0.0 +map_Kd sphere1_auv.png + diff --git a/Faceball2030/assets/enemies/bullet.png b/Faceball2030/assets/enemies/bullet.png new file mode 100644 index 0000000..80784ff Binary files /dev/null and b/Faceball2030/assets/enemies/bullet.png differ diff --git a/Faceball2030/assets/enemies/bullet.wings b/Faceball2030/assets/enemies/bullet.wings new file mode 100644 index 0000000..b0ed736 Binary files /dev/null and b/Faceball2030/assets/enemies/bullet.wings differ diff --git a/Faceball2030/main.cpp b/Faceball2030/main.cpp index bbe4588..02967c4 100644 --- a/Faceball2030/main.cpp +++ b/Faceball2030/main.cpp @@ -75,7 +75,7 @@ void FaceBall::LoadLevel(int level) } } } - objects.push_back({ mapMesh }); + objects.push_back({ mapMesh,{0,0},0,0 }); } bool FaceBall::CheckCollision(vec3d movementVector,vf2d pos,float radius){ @@ -85,8 +85,8 @@ bool FaceBall::CheckCollision(vec3d movementVector,vf2d pos,float radius){ for (int x = -1; x <= 1; x++) { int offsetX = (int)pos.x + x; int offsetY = (int)pos.y + y; - if (offsetX >= 0 && offsetX < MAP_SIZE.x && offsetY >= 0 && offsetY < MAP_SIZE.y) { - MapSquare tile = map[offsetY][offsetX]; + if (offsetX >= 0 && offsetX < game->MAP_SIZE.x && offsetY >= 0 && offsetY < game->MAP_SIZE.y) { + MapSquare tile = game->map[offsetY][offsetX]; if (tile.wallN != NULL) { utils::geom2d::linewall{ {(float)offsetX,(float)offsetY},{(float)offsetX+1,(float)offsetY} }; if (((int)(newPos.pos.x-radius)==offsetX|| @@ -456,6 +456,106 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& } } +void FaceBall::RenderMesh(mat4x4&matView,std::vector&vecTrianglesToRaster, Object&o) { + for (auto& tri : o.mesh.tris) { + Triangle triProjected, triTransformed, triViewed; + mat4x4 localMat = Matrix_MakeIdentity(); + mat4x4 rotMat = Matrix_MakeRotationY(o.rot); + localMat = Matrix_MultiplyMatrix(localMat, rotMat); + mat4x4 matTrans = Matrix_MakeTranslation(o.pos.x-o.radius, o.pos.y-o.radius, o.pos.z - o.radius); + localMat = Matrix_MultiplyMatrix(localMat, matTrans); + + triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]); + triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]); + triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]); + triTransformed.uv[0] = tri.uv[0]; + triTransformed.uv[1] = tri.uv[1]; + triTransformed.uv[2] = tri.uv[2]; + triTransformed.col = tri.col; + + vec3d normal, line1, line2; + line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); + line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]); + + normal = Vector_CrossProduct(line1, line2); + normal = Vector_Normalise(normal); + + vec3d vCameraRay = Vector_Sub(triTransformed.p[0], freeRoam ? freeRoamCamera : player.GetPos()); + + if (Vector_DotProduct(normal, vCameraRay) < 0) { + vec3d light_dir = Vector_Mul(vLookDir, -1); + light_dir = Vector_Normalise(light_dir); + + float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal)); + + triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]); + triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]); + triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]); + triViewed.uv[0] = triTransformed.uv[0]; + triViewed.uv[1] = triTransformed.uv[1]; + triViewed.uv[2] = triTransformed.uv[2]; + triViewed.col = Pixel(triTransformed.col.r * dp * dp, triTransformed.col.g * dp * dp, triTransformed.col.b * dp * dp); + float dist = std::sqrtf(std::powf((freeRoam ? freeRoamCamera : player.GetPos()).x - tri.p[0].x, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).y - tri.p[0].y, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).z - tri.p[0].z, 2)); + float colorMult = dist > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist + PI / 2); + triViewed.col = Pixel(triViewed.col.r * colorMult, triViewed.col.g * colorMult, triViewed.col.b * colorMult); + //triViewed.col = triTransformed.col; + + int nClippedTriangles = 0; + Triangle clipped[2]; + nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]); + + for (int n = 0; n < nClippedTriangles; n++) { + // Project triangles from 3D --> 2D + triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]); + triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]); + triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]); + triProjected.col = clipped[n].col; + triProjected.uv[0] = clipped[n].uv[0]; + triProjected.uv[1] = clipped[n].uv[1]; + triProjected.uv[2] = clipped[n].uv[2]; + triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w; + triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w; + triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w; + + triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w; + triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w; + triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w; + + triProjected.uv[0].w = 1.0f / triProjected.p[0].w; + triProjected.uv[1].w = 1.0f / triProjected.p[1].w; + triProjected.uv[2].w = 1.0f / triProjected.p[2].w; + + + triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w); + triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w); + triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w); + + triProjected.p[0].x *= -1.0f; + triProjected.p[1].x *= -1.0f; + triProjected.p[2].x *= -1.0f; + triProjected.p[0].y *= -1.0f; + triProjected.p[1].y *= -1.0f; + triProjected.p[2].y *= -1.0f; + + // Scale into view + vec3d vOffsetView = { 1,1,0 }; + triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView); + triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView); + triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView); + triProjected.p[0].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[0].y *= 0.5f * (float)ScreenHeight(); + triProjected.p[1].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[1].y *= 0.5f * (float)ScreenHeight(); + triProjected.p[2].x *= 0.5f * (float)ScreenWidth(); + triProjected.p[2].y *= 0.5f * (float)ScreenHeight(); + triProjected.tex = o.mesh.texture; + + vecTrianglesToRaster.push_back(triProjected); + } + } + } +} + void FaceBall::RenderWorld() { // Set up rotation matrices mat4x4 matRotZ, matRotX, matWorld; @@ -470,115 +570,21 @@ void FaceBall::RenderWorld() { vec3d vUp = { 0,1,0 }; vec3d vTarget = { 0,sinf(pitch),cosf(pitch) }; - mat4x4 matCameraRot = Matrix_MakeRotationY(fYaw); + mat4x4 matCameraRot = Matrix_MakeRotationY(fYaw-PI/2); vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget); - vTarget = Vector_Add(freeRoam?freeRoamCamera:player.GetPos(), vLookDir); - mat4x4 matCamera = Matrix_PointAt(freeRoam?freeRoamCamera:player.GetPos(), vTarget, vUp); + vec3d playerCenter = { player.GetPos().x, player.GetPos().y, player.GetPos().z }; + vTarget = Vector_Add(freeRoam ? freeRoamCamera : playerCenter, vLookDir); + mat4x4 matCamera = Matrix_PointAt(freeRoam?freeRoamCamera: playerCenter, vTarget, vUp); mat4x4 matView = Matrix_QuickInverse(matCamera); std::vectorvecTrianglesToRaster; // Draw Triangles for (auto& obj : objects) { - for (auto& tri : obj.mesh.tris) { - Triangle triProjected, triTransformed, triViewed; - //mat4x4 matTrans = Matrix_MakeTranslation(-mesh.size.x/2, 0, -mesh.size.x/2); - mat4x4 localMat = Matrix_MakeIdentity(); - //localMat = Matrix_MultiplyMatrix(localMat, matTrans); - mat4x4 rotMat = Matrix_MakeRotationY(obj.rot); - localMat = Matrix_MultiplyMatrix(localMat, rotMat); - mat4x4 matTrans = Matrix_MakeTranslation(obj.pos.x, 0, obj.pos.y); - localMat = Matrix_MultiplyMatrix(localMat, matTrans); - - triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]); - triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]); - triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]); - triTransformed.uv[0] = tri.uv[0]; - triTransformed.uv[1] = tri.uv[1]; - triTransformed.uv[2] = tri.uv[2]; - triTransformed.col = tri.col; - - vec3d normal, line1, line2; - line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); - line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]); - - normal = Vector_CrossProduct(line1, line2); - normal = Vector_Normalise(normal); - - vec3d vCameraRay = Vector_Sub(triTransformed.p[0], freeRoam?freeRoamCamera:player.GetPos()); - - if (Vector_DotProduct(normal, vCameraRay) < 0) { - vec3d light_dir = Vector_Mul(vLookDir, -1); - light_dir = Vector_Normalise(light_dir); - - float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal)); - - triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]); - triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]); - triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]); - triViewed.uv[0] = triTransformed.uv[0]; - triViewed.uv[1] = triTransformed.uv[1]; - triViewed.uv[2] = triTransformed.uv[2]; - triViewed.col = Pixel(triTransformed.col.r * dp * dp, triTransformed.col.g * dp * dp, triTransformed.col.b * dp * dp); - float dist = std::sqrtf(std::powf((freeRoam ? freeRoamCamera : player.GetPos()).x - tri.p[0].x, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).y - tri.p[0].y, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).z - tri.p[0].z, 2)); - float colorMult = dist>5*PI/3?0:std::sinf(0.3 * dist + PI / 2); - triViewed.col = Pixel(triViewed.col.r * colorMult, triViewed.col.g * colorMult, triViewed.col.b * colorMult); - //triViewed.col = triTransformed.col; - - int nClippedTriangles = 0; - Triangle clipped[2]; - nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]); - - for (int n = 0; n < nClippedTriangles; n++) { - // Project triangles from 3D --> 2D - triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]); - triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]); - triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]); - triProjected.col = clipped[n].col; - triProjected.uv[0] = clipped[n].uv[0]; - triProjected.uv[1] = clipped[n].uv[1]; - triProjected.uv[2] = clipped[n].uv[2]; - triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w; - triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w; - triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w; - - triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w; - triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w; - triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w; - - triProjected.uv[0].w = 1.0f / triProjected.p[0].w; - triProjected.uv[1].w = 1.0f / triProjected.p[1].w; - triProjected.uv[2].w = 1.0f / triProjected.p[2].w; - - - triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w); - triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w); - triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w); - - triProjected.p[0].x *= -1.0f; - triProjected.p[1].x *= -1.0f; - triProjected.p[2].x *= -1.0f; - triProjected.p[0].y *= -1.0f; - triProjected.p[1].y *= -1.0f; - triProjected.p[2].y *= -1.0f; - - // Scale into view - vec3d vOffsetView = { 1,1,0 }; - triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView); - triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView); - triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView); - triProjected.p[0].x *= 0.5f * (float)ScreenWidth(); - triProjected.p[0].y *= 0.5f * (float)ScreenHeight(); - triProjected.p[1].x *= 0.5f * (float)ScreenWidth(); - triProjected.p[1].y *= 0.5f * (float)ScreenHeight(); - triProjected.p[2].x *= 0.5f * (float)ScreenWidth(); - triProjected.p[2].y *= 0.5f * (float)ScreenHeight(); - triProjected.tex = obj.mesh.texture; - - vecTrianglesToRaster.push_back(triProjected); - } - } - } + RenderMesh(matView,vecTrianglesToRaster,obj); + } + for (auto& bullet : bullets) { + RenderMesh(matView, vecTrianglesToRaster, bullet); } //std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;}); @@ -668,6 +674,9 @@ void FaceBall::HandleKeys(float fElapsedTime) { } else { pitch = 0; + if (GetMouse(0).bPressed) { + bullets.push_back({ bullet,{player.GetPos().x + player.GetRadius(),player.GetPos().y, player.GetPos().z + player.GetRadius()},fYaw,0.25f,{shotSpd * std::cosf(fYaw),shotSpd * std::sinf(fYaw)} }); + } } if (GetKey(W).bHeld) { if (freeRoam) { @@ -748,10 +757,12 @@ bool FaceBall::OnUserCreate() arrow = new Decal(new Sprite("assets/arrow.png")); enemy_ShootMe_tex = new Decal(new Sprite("assets/enemies/ShootMe.png")); YAZAWA = new Decal(new Sprite("assets/yazawa.png")); + bullet_tex = new Decal(new Sprite("assets/enemies/bullet.png")); InitializeEnemyData(); Mesh testEnemy("assets/enemies/ShootMe.obj", enemy_ShootMe_tex); + bullet = { "assets/enemies/bullet.obj",bullet_tex }; mapMesh.texture = YAZAWA; LoadLevel(1); @@ -759,8 +770,28 @@ bool FaceBall::OnUserCreate() return true; } +bool Bullet::Update(float fElapsedTime) { + if (!FaceBall::CheckCollision({ spd.x,0,spd.y }, {pos.x,pos.z}, radius)) { + pos.x += spd.x*fElapsedTime; + pos.z += spd.y*fElapsedTime; + } + else { + return false; + } + return true; +} + bool FaceBall::OnUserUpdate(float fElapsedTime) { + for (std::vector::iterator it = bullets.begin(); it != bullets.end(); ++it) { + Bullet& b = *it; + if (!b.Update(fElapsedTime)) { + it=bullets.erase(it); + if (it == bullets.end()) { + break; + } + } + } switch (mode) { case GAME: { HandleKeys(fElapsedTime); diff --git a/Faceball2030/main.h b/Faceball2030/main.h index fb6a417..fc02bb9 100644 --- a/Faceball2030/main.h +++ b/Faceball2030/main.h @@ -139,8 +139,14 @@ private: struct Object { Mesh mesh; - vf2d pos = { 0,0 }; + vec3d pos = { 0,0 }; float rot = 0; + float radius = 0.2f; +}; + +struct Bullet : Object{ + vf2d spd = { 0,0 }; + bool Update(float fElapsedTime); }; struct EnemyData { @@ -171,13 +177,14 @@ class FaceBall : public PixelGameEngine EnemyData GetData(EnemyID id); Decal* circle,*arrow,*YAZAWA; private: - Mesh mapMesh; + Mesh mapMesh,enemy_ShootMe,bullet; - Decal* dot, * enemy_ShootMe_tex; - vi2d MAP_SIZE = { 10,10 }; + Decal* dot, * enemy_ShootMe_tex,*bullet_tex; + vi2d MAP_SIZE; std::vector>map; std::mapenemyData; std::vectorobjects; + std::vectorbullets; GAMEMODE mode=GAMEMODE::GAME; Editor editor; int level=1; @@ -195,6 +202,8 @@ class FaceBall : public PixelGameEngine Player player = { {3.7,0.3,0.7}, {{0.5,0.5},0.2} }; vec3d freeRoamCamera = { 1,0.5,1 }; + float shotSpd = 1.5f; + vec3d Matrix_MultiplyVector(mat4x4& m, vec3d& i); mat4x4 Matrix_MakeIdentity(); mat4x4 Matrix_MakeRotationX(float fAngleRad); @@ -223,5 +232,7 @@ class FaceBall : public PixelGameEngine void OnTextEntryComplete(const std::string& sText) override; void InitializeEnemyData(); void LoadLevel(int level); - bool CheckCollision(vec3d movementVector,vf2d pos,float radius); + void RenderMesh(mat4x4&matView, std::vector&vecTrianglesToRaster,Object&o); + public: + static bool CheckCollision(vec3d movementVector,vf2d pos,float radius); }; \ No newline at end of file