|
|
|
@ -1,5 +1,6 @@ |
|
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
|
#include "pixelGameEngine.h" |
|
|
|
|
#include "geometry2d.h" |
|
|
|
|
#include <strstream> |
|
|
|
|
#include <algorithm> |
|
|
|
|
#include "main.h" |
|
|
|
@ -23,6 +24,113 @@ void FaceBall::InitializeEnemyData() { |
|
|
|
|
enemyData[AREA_MAP] = { "Map",GREEN }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::LoadLevel(int level) |
|
|
|
|
{ |
|
|
|
|
this->level = level; |
|
|
|
|
std::vector<std::vector<Tile>>mapData = editor.LoadLevel(level); |
|
|
|
|
MAP_SIZE = { (int)mapData[0].size(),(int)mapData.size() }; |
|
|
|
|
map.clear(); |
|
|
|
|
mapMesh.tris.clear(); |
|
|
|
|
objects.clear(); |
|
|
|
|
for (int y = 0; y < MAP_SIZE.y; y++) { |
|
|
|
|
std::vector<MapSquare>row; |
|
|
|
|
for (int x = 0; x < MAP_SIZE.x; x++) { |
|
|
|
|
row.push_back({}); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},BLUE }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y + 1}},{{0,0},{1,0},{0,1}},BLUE }); |
|
|
|
|
} |
|
|
|
|
map.push_back(row); |
|
|
|
|
} |
|
|
|
|
for (int y = 0; y < MAP_SIZE.y; y++) { |
|
|
|
|
for (int x = 0; x < MAP_SIZE.x; x++) { |
|
|
|
|
int wallData = 0; |
|
|
|
|
if (mapData[y][x].wallN) { |
|
|
|
|
wallData |= NORTH; |
|
|
|
|
} |
|
|
|
|
if (mapData[y][x].wallE) { |
|
|
|
|
wallData |= EAST; |
|
|
|
|
} |
|
|
|
|
if (mapData[y][x].wallS) { |
|
|
|
|
wallData |= SOUTH; |
|
|
|
|
} |
|
|
|
|
if (mapData[y][x].wallW) { |
|
|
|
|
wallData |= WEST; |
|
|
|
|
} |
|
|
|
|
AddWall(wallData, { x,y }); |
|
|
|
|
if (map[y][x].wallN != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x + 1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallS != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x,0,(float)y + 1},{(float)x,1,(float)y + 1}},{{0,0},{1,0},{0,1}},DARK_RED }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x + 1,0,(float)y + 1},{(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},DARK_RED }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallW != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y + 1}, {(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},MAGENTA }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{0,0},{1,0},{0,1}},MAGENTA }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallE != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x + 1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x + 1,1,(float)y},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
objects.push_back({ mapMesh }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool FaceBall::CheckCollision(vec3d movementVector){ |
|
|
|
|
utils::geom2d::circle<float>newPos{ {player.GetPos().x + movementVector.x,player.GetPos().z + movementVector.z},player.GetRadius() }; |
|
|
|
|
bool collisionOccured = false; |
|
|
|
|
for (int y = -1; y <= 1; y++) { |
|
|
|
|
for (int x = -1; x <= 1; x++) { |
|
|
|
|
int offsetX = (int)player.GetPos().x + x; |
|
|
|
|
int offsetY = (int)player.GetPos().z + y; |
|
|
|
|
if (offsetX >= 0 && offsetX < MAP_SIZE.x && offsetY >= 0 && offsetY < MAP_SIZE.y) { |
|
|
|
|
MapSquare tile = map[offsetY][offsetX]; |
|
|
|
|
if (tile.wallN != NULL) { |
|
|
|
|
utils::geom2d::line<float>wall{ {(float)offsetX,(float)offsetY},{(float)offsetX+1,(float)offsetY} }; |
|
|
|
|
if (((int)(newPos.pos.x-player.GetRadius())==offsetX|| |
|
|
|
|
(int)(newPos.pos.x + player.GetRadius()) == offsetX) |
|
|
|
|
&& |
|
|
|
|
newPos.pos.y > wall.start.y && wall.start.y > newPos.pos.y - player.GetRadius()) { |
|
|
|
|
collisionOccured = true; |
|
|
|
|
goto breakOutOfCollisionLoop; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (tile.wallE != NULL) { |
|
|
|
|
utils::geom2d::line<float>wall{ {(float)offsetX+1,(float)offsetY},{(float)offsetX + 1,(float)offsetY+1} }; |
|
|
|
|
if (((int)(newPos.pos.y - player.GetRadius()) == offsetY || |
|
|
|
|
(int)(newPos.pos.y + player.GetRadius()) == offsetY) |
|
|
|
|
&& newPos.pos.x<wall.start.x && wall.start.x < newPos.pos.x + player.GetRadius()) { |
|
|
|
|
collisionOccured = true; |
|
|
|
|
goto breakOutOfCollisionLoop; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (tile.wallS != NULL) { |
|
|
|
|
utils::geom2d::line<float>wall{ {(float)offsetX,(float)offsetY+1},{(float)offsetX + 1,(float)offsetY+1} }; |
|
|
|
|
if (((int)(newPos.pos.x - player.GetRadius()) == offsetX || |
|
|
|
|
(int)(newPos.pos.x + player.GetRadius()) == offsetX) |
|
|
|
|
&& newPos.pos.y < wall.start.y && wall.start.y < newPos.pos.y + player.GetRadius()) { |
|
|
|
|
collisionOccured = true; |
|
|
|
|
goto breakOutOfCollisionLoop; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (tile.wallW != NULL) { |
|
|
|
|
utils::geom2d::line<float>wall{ {(float)offsetX,(float)offsetY},{(float)offsetX,(float)offsetY + 1} }; |
|
|
|
|
if (((int)(newPos.pos.y - player.GetRadius()) == offsetY || |
|
|
|
|
(int)(newPos.pos.y + player.GetRadius()) == offsetY) |
|
|
|
|
&& newPos.pos.x > wall.start.x && wall.start.x > newPos.pos.x - player.GetRadius()) { |
|
|
|
|
collisionOccured = true; |
|
|
|
|
goto breakOutOfCollisionLoop; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
breakOutOfCollisionLoop: |
|
|
|
|
return collisionOccured; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EnemyData FaceBall::GetData(EnemyID id) |
|
|
|
|
{ |
|
|
|
|
return enemyData[id]; |
|
|
|
@ -364,8 +472,8 @@ void FaceBall::RenderWorld() { |
|
|
|
|
vec3d vTarget = { 0,sinf(pitch),cosf(pitch) }; |
|
|
|
|
mat4x4 matCameraRot = Matrix_MakeRotationY(fYaw); |
|
|
|
|
vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget); |
|
|
|
|
vTarget = Vector_Add(vCamera, vLookDir); |
|
|
|
|
mat4x4 matCamera = Matrix_PointAt(vCamera, vTarget, vUp); |
|
|
|
|
vTarget = Vector_Add(player.GetPos(), vLookDir); |
|
|
|
|
mat4x4 matCamera = Matrix_PointAt(player.GetPos(), vTarget, vUp); |
|
|
|
|
mat4x4 matView = Matrix_QuickInverse(matCamera); |
|
|
|
|
|
|
|
|
|
std::vector<Triangle>vecTrianglesToRaster; |
|
|
|
@ -397,7 +505,7 @@ void FaceBall::RenderWorld() { |
|
|
|
|
normal = Vector_CrossProduct(line1, line2); |
|
|
|
|
normal = Vector_Normalise(normal); |
|
|
|
|
|
|
|
|
|
vec3d vCameraRay = Vector_Sub(triTransformed.p[0], vCamera); |
|
|
|
|
vec3d vCameraRay = Vector_Sub(triTransformed.p[0], player.GetPos()); |
|
|
|
|
|
|
|
|
|
if (Vector_DotProduct(normal, vCameraRay) < 0) { |
|
|
|
|
vec3d light_dir = Vector_Mul(vLookDir, -1); |
|
|
|
@ -545,23 +653,38 @@ void FaceBall::RenderWorld() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::HandleKeys(float fElapsedTime) { |
|
|
|
|
vec3d vForward = Vector_Mul(vLookDir, 2 * fElapsedTime); |
|
|
|
|
vec3d vForward = Vector_Mul(vLookDir, std::min(player.GetRadius()-0.00001f,2*fElapsedTime)); |
|
|
|
|
if (freeRoam) { |
|
|
|
|
if (GetKey(olc::DOWN).bHeld) { |
|
|
|
|
if (GetKey(DOWN).bHeld) { |
|
|
|
|
pitch -= 1 * fElapsedTime; |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::UP).bHeld) { |
|
|
|
|
if (GetKey(UP).bHeld) { |
|
|
|
|
pitch += 1 * fElapsedTime; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
pitch = 0; |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::W).bHeld) { |
|
|
|
|
vCamera = Vector_Add(vCamera, vForward); |
|
|
|
|
if (GetKey(W).bHeld) { |
|
|
|
|
if (!CheckCollision({ vForward.x,0,0 })) { |
|
|
|
|
vec3d xMovement{ vForward.x,0,0 }; |
|
|
|
|
player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); |
|
|
|
|
} |
|
|
|
|
if (!CheckCollision({0,0,vForward.z})) { |
|
|
|
|
vec3d zMovement{ 0,0,vForward.z }; |
|
|
|
|
player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::S).bHeld) { |
|
|
|
|
vCamera = Vector_Sub(vCamera, vForward); |
|
|
|
|
if (GetKey(S).bHeld) { |
|
|
|
|
vec3d vReverse = { -vForward.x,-vForward.y,-vForward.z }; |
|
|
|
|
if (!CheckCollision({ vReverse.x,0,0 })) { |
|
|
|
|
vec3d xMovement{ vReverse.x,0,0 }; |
|
|
|
|
player.UpdatePos(Vector_Add(player.GetPos(), xMovement)); |
|
|
|
|
} |
|
|
|
|
if (!CheckCollision({ 0,0,vReverse.z })) { |
|
|
|
|
vec3d zMovement{ 0,0,vReverse.z }; |
|
|
|
|
player.UpdatePos(Vector_Add(player.GetPos(), zMovement)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::A).bHeld) { |
|
|
|
|
fYaw -= 2 * fElapsedTime; |
|
|
|
@ -574,7 +697,7 @@ void FaceBall::HandleKeys(float fElapsedTime) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FaceBall::AddWall(Direction dir, vi2d gridSquare) { |
|
|
|
|
void FaceBall::AddWall(int dir, vi2d gridSquare) { |
|
|
|
|
if (dir & NORTH) { |
|
|
|
|
map[gridSquare.y][gridSquare.x].wallN = dot; |
|
|
|
|
if (gridSquare.y > 0) { |
|
|
|
@ -615,99 +738,8 @@ bool FaceBall::OnUserCreate() |
|
|
|
|
|
|
|
|
|
Mesh testEnemy("assets/enemies/ShootMe.obj", enemy_ShootMe_tex); |
|
|
|
|
mapMesh.texture = dot; |
|
|
|
|
for (int i = 0; i < 75; i++) { |
|
|
|
|
Object newEnemy({ testEnemy,{ float(rand() % 20),float(rand() % 20) }, (rand() % 1000) / 1000.f * 2 * PI }); |
|
|
|
|
objects.push_back(newEnemy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int y = 0; y < MAP_SIZE.y; y++) { |
|
|
|
|
std::vector<MapSquare>row; |
|
|
|
|
for (int x = 0; x < MAP_SIZE.x; x++) { |
|
|
|
|
row.push_back({}); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},BLUE }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y},{(float)x,0,(float)y + 1},{(float)x + 1,0,(float)y + 1}},{{0,0},{1,0},{0,1}},BLUE }); |
|
|
|
|
} |
|
|
|
|
map.push_back(row); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int y = 0; y < MAP_SIZE.y; y++) { |
|
|
|
|
for (int x = 0; x < MAP_SIZE.x; x++) { |
|
|
|
|
switch (rand() % 16) { |
|
|
|
|
case 0: {//No Wall.
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
case 1: {//North Wall.
|
|
|
|
|
AddWall(NORTH, { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 2: {//East Wall.
|
|
|
|
|
AddWall(EAST, { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 3: {//South Wall.
|
|
|
|
|
AddWall(SOUTH, { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 4: {//West Wall.
|
|
|
|
|
AddWall(WEST, { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 5: {//NE Wall.
|
|
|
|
|
AddWall(Direction(NORTH | EAST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 6: { |
|
|
|
|
AddWall(Direction(NORTH | WEST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 7: { |
|
|
|
|
AddWall(Direction(SOUTH | EAST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 8: { |
|
|
|
|
AddWall(Direction(SOUTH | WEST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 9: { |
|
|
|
|
AddWall(Direction(NORTH | SOUTH), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 10: { |
|
|
|
|
AddWall(Direction(EAST | WEST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 11: { |
|
|
|
|
AddWall(Direction(NORTH | WEST | EAST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 12: { |
|
|
|
|
AddWall(Direction(NORTH | WEST | SOUTH), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 13: { |
|
|
|
|
AddWall(Direction(WEST | SOUTH | EAST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 14: { |
|
|
|
|
AddWall(Direction(SOUTH | EAST | NORTH), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
case 15: { |
|
|
|
|
AddWall(Direction(SOUTH | EAST | NORTH | WEST), { x,y }); |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
AddWall(Direction(SOUTH | EAST | NORTH | WEST), { 0,0 }); |
|
|
|
|
|
|
|
|
|
for (int y = 0; y < MAP_SIZE.y; y++) { |
|
|
|
|
for (int x = 0; x < MAP_SIZE.x; x++) { |
|
|
|
|
if (map[y][x].wallN != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x + 1,0,(float)y},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},YELLOW }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallS != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x,0,(float)y + 1},{(float)x,1,(float)y + 1}},{{0,0},{1,0},{0,1}},DARK_RED }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,1,(float)y + 1},{(float)x + 1,0,(float)y + 1},{(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},DARK_RED }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallW != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,1,(float)y},{(float)x,1,(float)y + 1}, {(float)x,0,(float)y + 1}},{{0,0},{1,0},{0,1}},MAGENTA }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x,0,(float)y},{(float)x,1,(float)y}, {(float)x,0,(float)y + 1}}, {{0,0},{1,0},{0,1}},MAGENTA }); |
|
|
|
|
} |
|
|
|
|
if (map[y][x].wallE != NULL) { |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1},{(float)x + 1,1,(float)y + 1},{(float)x + 1,1,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); |
|
|
|
|
mapMesh.tris.push_back({ {{(float)x + 1,0,(float)y + 1} ,{(float)x + 1,1,(float)y},{(float)x + 1,0,(float)y}},{{0,0},{1,0},{0,1}},CYAN }); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//objects.push_back(mapMesh);
|
|
|
|
|
LoadLevel(1); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -716,9 +748,6 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) |
|
|
|
|
{ |
|
|
|
|
switch (mode) { |
|
|
|
|
case GAME: { |
|
|
|
|
for (Object& o : objects) { |
|
|
|
|
o.rot += PI / 8 * fElapsedTime; |
|
|
|
|
} |
|
|
|
|
HandleKeys(fElapsedTime); |
|
|
|
|
RenderWorld(); |
|
|
|
|
}break; |
|
|
|
@ -728,6 +757,9 @@ bool FaceBall::OnUserUpdate(float fElapsedTime) |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::F5).bPressed) { |
|
|
|
|
mode = (GAMEMODE)!(mode&1); |
|
|
|
|
if (mode == GAMEMODE::GAME) { |
|
|
|
|
LoadLevel(level); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|