diff --git a/PhysSandbox/main.cpp b/PhysSandbox/main.cpp new file mode 100644 index 0000000..c4ad91b --- /dev/null +++ b/PhysSandbox/main.cpp @@ -0,0 +1,420 @@ +#include +#include +#include + +#define BlockSize 30 + +struct Block{ +private: + float sizeSCL = 1; + float sidemoves = 0; + + bool isStationary = true, onBottom = false; + +public: + // Variables + enum Types {Sand, Water}; + + float x,y; + int id; + Types blockType; + + // Constructors + Block(){ + x=0;y=0; + } + Block(float x, float y, int id, Types blockType){ + this->x = x; this->y = y; + this->id = id; this->blockType=blockType; + } + + // Functions + void Draw(){ + // just for use + float sizeHALF = sizeSCL / 2; + + // GL Begin + glBegin(GL_QUADS); + + // Making the CUBE + + // Left + switch(blockType){ + case Sand: + glColor3f(0.5f,0.5f,0); + break; + case Water: + glColor3f(0,0,0.5f); + } + glVertex3f((x-sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, sizeHALF/BlockSize); + glVertex3f((x-sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, -sizeHALF/BlockSize); + glVertex3f((x-sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, -sizeHALF/BlockSize); + glVertex3f((x-sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, sizeHALF/BlockSize); + + // Left + glVertex3f((x+sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, -sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, -sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, sizeHALF/BlockSize); + + // Top + glVertex3f((x-sizeHALF)/BlockSize,(y+sizeHALF)/BlockSize,-sizeHALF/BlockSize); + glVertex3f((x-sizeHALF)/BlockSize,(y+sizeHALF)/BlockSize,sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize,(y+sizeHALF)/BlockSize,sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize,(y+sizeHALF)/BlockSize,-sizeHALF/BlockSize); + + // Front + switch(blockType){ + case Sand: + glColor3f(0.5f,0.5f,0); + break; + case Water: + glColor4f(0,0,0.5f, 0.5f); + } + + glVertex3f((x-sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, sizeHALF/BlockSize); + glVertex3f((x+sizeHALF)/BlockSize, (y-sizeHALF)/BlockSize, sizeHALF/BlockSize); + switch(blockType){ + case Sand: + glColor3f(1.0f,1.0f,0); + break; + case Water: + glColor4f(0,0,1.0f, 0.5f); + } + glVertex3f((x+sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, sizeHALF/BlockSize); + glVertex3f((x-sizeHALF)/BlockSize, (y+sizeHALF)/BlockSize, sizeHALF/BlockSize); + + glEnd(); + } + + void Move(std::vector blocks){ + float sizeHALF = sizeSCL / 2; + + bool NotonBottom = (y - 1)/BlockSize > -1; + onBottom = !NotonBottom; + + if(onBottom) {isStationary = true;} + + // If we're above the ground + if(NotonBottom){ + // Getting all sands + bool canMove = false; + bool canMoveDLeft = false, canMoveDRight = false; + bool canMoveLeft=false, canMoveRight=false; + + int bhits=0, dlhits=0, drhits=0; + int rhits=0, lhits=0; + + for(int i = 0; i < blocks.size(); i++){ + // For the L&R movement + // Down Moving Stops + if(!(blockType == Sand && blocks[i].blockType == Water)){ + if(y - sizeHALF == blocks[i].y + sizeHALF && x == blocks[i].x){ + bhits++; + } + // Can't move down left + if(x - sizeHALF == blocks[i].x + sizeHALF && y - sizeHALF == blocks[i].y + sizeHALF){ + dlhits++; + } + // Can't move down right + if(x + sizeHALF == blocks[i].x - sizeHALF && y - sizeHALF == blocks[i].y + sizeHALF){ + drhits++; + } + // Can't move left + if(x - sizeHALF == blocks[i].x + sizeHALF && y == blocks[i].y){ + lhits++; + } + // Can't move right + if(x + sizeHALF == blocks[i].x - sizeHALF && y == blocks[i].y){ + rhits++; + } + // Sand in water + if(blockType == Water && blocks[i].blockType == Sand){ + if(x == blocks[i].x && y == blocks[i].y){ + y += 2; + sidemoves = 0; + } + } + } + + // Move Up Because OVERLAPPING! + if(x == blocks[i].x && y == blocks[i].y && id != blocks[i].id){ + //y+=1; + } + } + + canMove = bhits == 0; + canMoveDLeft = dlhits == 0; + canMoveDRight = drhits == 0; + + if(blockType == Water){ + canMoveLeft = lhits == 0; + canMoveRight = rhits == 0; + } + + isStationary = true; + + if(canMove){ + y -= 1.f; + isStationary = false; + sidemoves = 0; + } + else{ + if(canMoveDLeft){ + y -= 1.f; + x -= 1.f; + isStationary = false; + sidemoves = 0; + } + else if(canMoveDRight){ + y -= 1.f; + x += 1.f; + isStationary = false; + sidemoves = 0; + } + + if(canMoveLeft && -sidemoves <= 0){ + x -= 1.f; + isStationary = false; + sidemoves++; + } + else if(canMoveRight && -sidemoves <= 0){ + x += 1.f; + isStationary = false; + sidemoves++; + } + } + + } + } +}; + +std::vectorblocks; +int selectedItem = 0; + +float backgroundRot = 0; + +float looky = 0; +float lookx = 0; + +void RecieveMouse(int button, int state, int x, int y){ + if(button == 0){ + int blockX, blockY; + + blockX = (x - 400) / (BlockSize>>1); + blockY = (-y + 300) / (BlockSize>>1); + + Block::Types bType = Block::Sand; + + switch(selectedItem){ + case 0: + bType = Block::Sand; + blocks.push_back(Block(blockX, blockY + 2, blocks.size(), Block::Sand )); + blocks.push_back(Block(blockX, blockY, blocks.size(), Block::Sand )); + blocks.push_back(Block(blockX, blockY - 2, blocks.size(), Block::Sand )); + break; + case 1: + bType = Block::Water; + blocks.push_back(Block(blockX, blockY + 2, blocks.size(), Block::Water )); + break; + } + + std::cout << "Mouse Position = " << blockX << ", " << blockY << "\n"; + } +} + +void KeyboardRecieved(unsigned char key, int x, int y){ + std::cout << "Key Pressed: " << key << "\n"; + + if(key == '1'){ + selectedItem = 0; + } + else if(key == '2'){ + selectedItem = 1; + } + + float turnspeed = 0.5f; + + if(key == 'w'){ + looky += turnspeed; + } + else if(key == 's'){ + looky -= turnspeed; + } + else{ + + } + + if(key == 'd'){ + lookx += turnspeed; + } + else if(key == 'a'){ + lookx -= turnspeed; + } + else{ + + } +} + +void Display(){ + // Clearing + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + + // new Object + glLoadIdentity(); + glTranslatef(0, 0, -3.0f); + + // Looking + gluLookAt(0, 0, 0, (GLdouble)lookx, 0, -3.0f, 0, 1, 0); + + // Drawing sand + for(int i = 0; i < blocks.size(); i++){ + blocks[i].Draw(); + } + + // Drawing the used item text + std::string itemText; + switch(selectedItem){ + case 0: + itemText = "Sand"; + break; + case 1: + itemText = "Water"; + } + + glColor3f(1,1,1); + glRasterPos2f(-0.75f, 0.75f); + + for(int i = 0; i < itemText.size(); i++){ + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, itemText[i]); + } + + glLoadIdentity(); + + // Looking + gluLookAt(0, 0, 0, (GLdouble)lookx, 0, -6.0f, 0, 1, 0); + + glTranslatef(0.0f, -0.2f, -3.0f); + glRotatef(backgroundRot, 0, 1, 0); + + glBegin(GL_TRIANGLES); + + float size = 0.05f; + + // Front + glColor3f(1,1,0); + glVertex3f(0,size,0); + + glColor3f(0,0,0); + glVertex3f(size,-size,size); + + glColor3f(0,0,0); + glVertex3f(-size,-size,size); + + // Left + glColor3f(1,1,0); + glVertex3f(0,size,0); + + glColor3f(0,0,0); + glVertex3f(-size,-size,-size); + + glColor3f(0,0,0); + glVertex3f(-size,-size,size); + + // Back + glColor3f(1,1,0); + glVertex3f(0,size,0); + + glColor3f(0,0,0); + glVertex3f(size,-size,-size); + + glColor3f(0,0,0); + glVertex3f(-size,-size,-size); + + // Right + glColor3f(1,1,0); + glVertex3f(0,size,0); + + glColor3f(0,0,0); + glVertex3f(size,-size,-size); + + glColor3f(0,0,0); + glVertex3f(size,-size,size); + + glEnd(); + + // Passing + glutSwapBuffers(); +} + +void ReShape(GLsizei width, GLsizei height){ + // Fixing thing + if(height == 0) height = 1; + // Making Aspect + GLfloat aspect = (GLfloat)width / (GLfloat)height; + // Setting the viewport + glViewport(0, 0, width, height); + // Matrixing + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + // Perception + gluPerspective(45.0f, aspect, 0.1f, 100.0f); +} + +void timer(int){ + glutPostRedisplay(); + glutTimerFunc(1000/60, timer, 0); + + // Code here + for(int i = 0; i < blocks.size(); i++){ + blocks[i].Move(blocks); + } + + // Background + backgroundRot += 0.8f; + + if(backgroundRot > 360) backgroundRot -= 360; + if(backgroundRot < 0 ) backgroundRot += 360; +} + +void Start(){ + // GL Init + glClearColor(0, 0, 0, 1); + glClearDepth(1.0f); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + glShadeModel(GL_SMOOTH); + + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +} + +// Application +int main(int argc, char** argv){ + + // Initilizing GLUT + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); + + // Window + glutInitWindowPosition(50, 50); + glutInitWindowSize(800, 600); + glutCreateWindow("Physics Sandbox"); + + // Making extras + glutDisplayFunc(Display); + glutReshapeFunc(ReShape); + glutMouseFunc(RecieveMouse); + glutKeyboardFunc(KeyboardRecieved); + glutTimerFunc(0, timer, 0); + + Start(); + + // Game Loop + glutMainLoop(); + + // Exit + return 0; +} diff --git a/README.md b/README.md index 738f48c..e4fe80c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ # Physics-Sandbox -A 2D physics simulator for MacOS \ No newline at end of file +This was made for Mac, With C++, Using GLUT ( OpenGL Utility Toolkit ) +It was Extreamly helpful using OpenGL to create 2d and 3d graphics. + +# Downloading the source + +### If you're not on a mac +* Download Any IDE +* Copy the main.cpp from the repo +* Compile using any prefered librarries + +### If you're using a mac +* Clone the repo: +- *git clone https://github.com/Maddox-Werts/Physics-Sandbox.git* +* Open the ***.xcodeproj*** file. + +I belive that's it if you're using a mac, +Just open Main.cpp, click run and BAM! +If it's not working, try going into the add frameworks +page, add a framework for OpenGL and GLUT and you're done!