Advertisement
bekovski

p11v2

Jan 22nd, 2018
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.71 KB | None | 0 0
  1. #include <Kore/pch.h>
  2.  
  3. #include <Kore/IO/FileReader.h>
  4. #include <Kore/Math/Core.h>
  5. #include <Kore/System.h>
  6. #include <Kore/Input/Keyboard.h>
  7. #include <Kore/Graphics4/Graphics.h>
  8. #include <Kore/Graphics4/PipelineState.h>
  9. #include <Kore/Math/Quaternion.h>
  10. #include <Kore/Threads/Thread.h>
  11. #include <Kore/Threads/Mutex.h>
  12. #include <Kore/Network/Socket.h>
  13. #include <Kore/Log.h>
  14. #include "ObjLoader.h"
  15. #include "Memory.h"
  16.  
  17. #include "MeshObject.h"
  18.  
  19. #ifdef MASTER
  20. #define SRC_PORT 9898
  21. #define DEST_PORT 9897
  22. #define CLIENT_NAME "Master"
  23. #else
  24. #define SRC_PORT 9897
  25. #define DEST_PORT 9898
  26. #define CLIENT_NAME "Slave"
  27. #endif
  28.  
  29. #define DEST_IP1 127
  30. #define DEST_IP2 0
  31. #define DEST_IP3 0
  32. #define DEST_IP4 1
  33.  
  34. using namespace Kore;
  35.  
  36. enum MessageType {
  37.     Hello,
  38.     NpcPos,
  39.     Player1Pos,
  40.     Player2Pos
  41. };
  42.  
  43. class Ball : public MeshObject {
  44. public:
  45.     Ball(float x, float y, float z, const Graphics4::VertexStructure& structure, float scale = 1.0f) : MeshObject("ball.obj", "unshaded.png", structure, scale), x(x), y(y), z(z), dir(0, 0, 0) {
  46.         rotation = Quaternion(vec3(0, 0, 1), 0);
  47.     }
  48.    
  49.     void update(float tdif) override {
  50.         vec3 dir = this->dir;
  51.         if (dir.getLength() != 0) dir.setLength(dir.getLength() * tdif * 60.0f);
  52.         x += dir.x();
  53.         if (x > 1) {
  54.             x = 1;
  55.         }
  56.         if (x < -1) {
  57.             x = -1;
  58.         }
  59.         y += dir.y();
  60.         if (y < -4) {
  61.             y = 4;
  62.         }
  63.         if (y > 4) {
  64.             y = -4;
  65.         }
  66.         z += dir.z();
  67.         if (dir.getLength() != 0) {
  68.             float Horizontal = dir.dot(vec3(1, 0, 0));
  69.             float Vertical = dir.dot(vec3(0, 1, 0));
  70.            
  71.             rotation = rotation.rotated(Quaternion(vec3(-1, 0, 0), Vertical * 3.0f));
  72.             rotation = rotation.rotated(Quaternion(vec3(0, 1, 0), Horizontal * 3.0f));
  73.         }
  74.         M = mat4::Translation(x, y, z) * rotation.matrix();
  75.     }
  76.    
  77.     vec3 dir;
  78.     Quaternion rotation;
  79.     float x, y, z;
  80. };
  81.  
  82. namespace {
  83.     void updateBall();
  84.     void sendPlayerInput(MessageType, bool, bool, bool, bool);
  85.    
  86.     const int width = 512;
  87.     const int height = 512;
  88.    
  89.     double startTime;
  90.     Graphics4::Shader* vertexShader;
  91.     Graphics4::Shader* fragmentShader;
  92.     Graphics4::PipelineState* pipeline;
  93.    
  94.     // null terminated array of MeshObject pointers
  95.     MeshObject* objects[] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
  96.  
  97.     // 0: master-ball, 1: slave-ball, 2: npc-ball
  98.     Ball* balls[] = { nullptr, nullptr, nullptr }; 
  99.    
  100.     // uniform locations - add more as you see fit
  101.     Graphics4::TextureUnit tex;
  102.     Graphics4::ConstantLocation pvLocation;
  103.     Graphics4::ConstantLocation mLocation;
  104.    
  105.     mat4 PV;
  106.    
  107.     float lastTime = 0.0;
  108.    
  109.     Socket socket;
  110.     vec3 position(0, 0, -2.25);
  111.    
  112.     const int port = SRC_PORT;
  113.     const int destPort = DEST_PORT;
  114.     const char* destination = "localhost";
  115.    
  116.     // Send a packet to the other client
  117.     // length is the length of the packet in bytes
  118.     void sendPacket(const unsigned char data[], int length) {
  119.         socket.send(destination, destPort, data, length);
  120.     }
  121.    
  122.     // Movement data for clients
  123.     bool left = false, right = false, up = false, down = false;
  124.     bool left2 = false, right2 = false, up2 = false, down2 = false;
  125.    
  126.     void update() {
  127.         // receive packets
  128.         while (true) {
  129.             // Read buffer
  130.             u8 buffer[256];
  131.             unsigned fromAddress;
  132.             unsigned fromPort;
  133.             int read = socket.receive(buffer, sizeof(buffer), fromAddress, fromPort);   // sets fromAddress and fromPort
  134.            
  135.             // break if there was no new packet
  136.             if (read <= 0) {
  137.                 break;
  138.             }
  139.  
  140.             /************************************************************************/
  141.             /* Practical Task: Read the packets with the movement data you sent  and
  142.             /* apply them by setting the boolean values for movement control.
  143.             /************************************************************************/
  144. #ifdef MASTER
  145.             // Set the values for left2, right2, up2, down2 here
  146.             if (buffer[0] == Player2Pos) {
  147.                 bool* bools = (bool*)&buffer[1];
  148.                 left2   = bools[0];
  149.                 right2  = bools[1];
  150.                 up2     = bools[2];
  151.                 down2   = bools[3];
  152.             }
  153. #else
  154.             // Set the values for left, right, up, down here
  155.             if (buffer[0] == Player1Pos) {
  156.                 bool* bools = (bool*)&buffer[1];
  157.                 left    = bools[0];
  158.                 right   = bools[1];
  159.                 up      = bools[2];
  160.                 down    = bools[3];
  161.             }
  162.            
  163.             // receive position updates of the npc ball
  164.             if (buffer[0] == NpcPos) {
  165.                 float* floats = (float*)&buffer[1];
  166.                 balls[2]->x = floats[0];
  167.                 balls[2]->y = floats[1];
  168.                 balls[2]->z = floats[2];
  169.             }
  170. #endif // MASTER
  171.            
  172.             updateBall();
  173.         }
  174.        
  175.         float t = (float)(System::time() - startTime);
  176.         float tdif = t - lastTime;
  177.         lastTime = t;
  178.        
  179.         updateBall();
  180.        
  181.         Graphics4::begin();
  182.         Graphics4::clear(Graphics4::ClearColorFlag | Graphics4::ClearDepthFlag, 0xff9999FF, 1.0f);
  183.        
  184.         Graphics4::setPipeline(pipeline);
  185.        
  186.         PV = mat4::Perspective(90, (float)width / (float)height, 0.1f, 100) * mat4::lookAt(position, vec3(0.0, 0.0, 0.0), vec3(0, 1, 0));
  187.         Graphics4::setMatrix(pvLocation, PV);
  188.        
  189.         MeshObject** current = &objects[0];
  190.         while (*current != nullptr) {
  191.             (*current)->update(tdif);
  192.             Graphics4::setMatrix(mLocation, (*current)->M);
  193.             (*current)->render(tex);
  194.             ++current;
  195.         }
  196.        
  197. #ifdef MASTER
  198.         // send position of the npc ball
  199.         u8 data[1 + sizeof(float) * 3];     // first entry: type of data, the rest (3 entries) are the position coordinates
  200.         float* fdata = (float*)&data[1];    // fdata is a pointer -> changing it affects 'data' as well
  201.        
  202.         data[0] = (u8)NpcPos;               // indicates that the following data is about NPC's position (hence +1 in array allocation)
  203.         fdata[0] = balls[2]->x;
  204.         fdata[1] = balls[2]->y;
  205.         fdata[2] = balls[2]->z;
  206.         sendPacket(data, sizeof(data));     // data = [NpcPos, balls[2].x, balls[2].y, balls[2].z]
  207. #endif
  208.        
  209.         Graphics4::end();
  210.         Graphics4::swapBuffers();
  211.     }
  212.    
  213.     void updateBall() {
  214.         // user controlled balls
  215.         float speed = 0.05f;
  216.         if (left) {
  217.             balls[0]->dir.x() = -speed;
  218.         }
  219.         else if (right) {
  220.             balls[0]->dir.x() = speed;
  221.         }
  222.         else {
  223.             balls[0]->dir.x() = 0;
  224.         }
  225.         if (up) {
  226.             balls[0]->dir.y() = speed;
  227.         }
  228.         else if (down) {
  229.             balls[0]->dir.y() = -speed;
  230.         }
  231.         else {
  232.             balls[0]->dir.y() = 0;
  233.         }
  234.         if (left2) {
  235.             balls[1]->dir.x() = -speed;
  236.         }
  237.         else if (right2) {
  238.             balls[1]->dir.x() = speed;
  239.         }
  240.         else {
  241.             balls[1]->dir.x() = 0;
  242.         }
  243.         if (up2) {
  244.             balls[1]->dir.y() = speed;
  245.         }
  246.         else if (down2) {
  247.             balls[1]->dir.y() = -speed;
  248.         }
  249.         else {
  250.             balls[1]->dir.y() = 0;
  251.         }
  252.         // NPC ball
  253.         balls[2]->dir.y() = -0.04f;
  254. #ifdef MASTER
  255.         if (balls[2]->y == 4) {
  256.             balls[2]->x = ((float)rand() / RAND_MAX)*2-1;
  257.         }
  258. #endif
  259.     }
  260.    
  261.     /************************************************************************/
  262.     /* Practical Task: Send packets with information about the input controls
  263.     /* of the local player - keyDown
  264.     /************************************************************************/
  265.     void keyDown(KeyCode code) {
  266. #ifdef MASTER
  267.         if (code == KeyLeft) {
  268.             left = true;
  269.         }
  270.         else if (code == KeyRight) {
  271.             right = true;
  272.         }
  273.         else if (code == KeyUp) {
  274.             up = true;
  275.         }
  276.         else if (code == KeyDown) {
  277.             down = true;
  278.         }
  279.  
  280.         sendPlayerInput(Player1Pos, left, right, up, down);
  281. #else
  282.         if (code == KeyA) {
  283.             left2 = true;
  284.         }
  285.         else if (code == KeyD) {
  286.             right2 = true;
  287.         }
  288.         if (code == KeyW) {
  289.             up2 = true;
  290.         }
  291.         else if (code == KeyS) {
  292.             down2 = true;
  293.         }
  294.  
  295.         sendPlayerInput(Player2Pos, left2, right2, up2, down2);
  296. #endif // MASTER
  297.     }
  298.    
  299.     /************************************************************************/
  300.     /* Practical Task: Send packets with information about the input controls
  301.     /* of the local player - keyUp
  302.     /************************************************************************/
  303.     void keyUp(KeyCode code) {
  304. #ifdef MASTER
  305.         if (code == KeyLeft) {
  306.             left = false;
  307.         }
  308.         else if (code == KeyRight) {
  309.             right = false;
  310.         }
  311.         else if (code == KeyUp) {
  312.             up = false;
  313.         }
  314.         else if (code == KeyDown) {
  315.             down = false;
  316.         }
  317.  
  318.         sendPlayerInput(Player1Pos, left, right, up, down);
  319. #else
  320.         if (code == KeyA) {
  321.             left2 = false;
  322.         }
  323.         else if (code == KeyD) {
  324.             right2 = false;
  325.         }
  326.         else if (code == KeyW) {
  327.             up2 = false;
  328.         }
  329.         else if (code == KeyS) {
  330.             down2 = false;
  331.         }
  332.  
  333.         sendPlayerInput(Player2Pos, left2, right2, up2, down2);
  334. #endif // MASTER
  335.     }
  336.  
  337.     void sendPlayerInput(MessageType msgType, bool left, bool right, bool up, bool down) {
  338.         u8 data[1 + sizeof(bool) * 4];
  339.         bool* bdata = (bool*)&data[1];
  340.  
  341.         data[0] = (u8)msgType;
  342.         bdata[0] = left;
  343.         bdata[1] = right;
  344.         bdata[2] = up;
  345.         bdata[3] = down;
  346.         sendPacket(data, sizeof(data));
  347.     }
  348.    
  349.     void init() {
  350.         srand(42);
  351.         socket.init();
  352.         socket.open(port);
  353.        
  354.         // send "hello" when joining to tell other player you are there
  355.         u8 hello = Hello;
  356.         sendPacket(&hello, 1);
  357.        
  358. #ifdef MASTER
  359.         log(Info, "Waiting for another player (the SLAVE) to join my game...");
  360. #else
  361.         log(Info, "Waiting for another player (the MASTER) in control of the game...");
  362. #endif // MASTER
  363.        
  364.         // wait for other player
  365.         while (true) {
  366.             // read buffer
  367.             unsigned char buffer[256];
  368.             unsigned fromAddress;
  369.             unsigned fromPort;
  370.             int read = socket.receive(buffer, sizeof(buffer), fromAddress, fromPort);
  371.             if (read <= 0) {
  372.                 continue;
  373.             }
  374.  
  375.             // break if player is there
  376.             if (buffer[0] == Hello) {
  377.                 break;
  378.             }
  379.         }
  380.        
  381. #ifdef MASTER
  382.         log(Info, "Another player (the SLAVE) has joined my game!");
  383. #else
  384.         log(Info, "I have joined another players (the MASTER) game!");
  385. #endif // MASTER
  386.        
  387.         // resend hello for newly connected player
  388.         sendPacket(&hello, 1);
  389.        
  390.         FileReader vs("shader.vert");
  391.         FileReader fs("shader.frag");
  392.         vertexShader = new Graphics4::Shader(vs.readAll(), vs.size(), Graphics4::VertexShader);
  393.         fragmentShader = new Graphics4::Shader(fs.readAll(), fs.size(), Graphics4::FragmentShader);
  394.        
  395.         // This defines the structure of your Vertex Buffer
  396.         Graphics4::VertexStructure structure;
  397.         structure.add("pos", Graphics4::Float3VertexData);
  398.         structure.add("tex", Graphics4::Float2VertexData);
  399.         structure.add("nor", Graphics4::Float3VertexData);
  400.        
  401.         pipeline = new Graphics4::PipelineState;
  402.         pipeline->inputLayout[0] = &structure;
  403.         pipeline->inputLayout[1] = nullptr;
  404.         pipeline->vertexShader = vertexShader;
  405.         pipeline->fragmentShader = fragmentShader;
  406.         pipeline->depthMode = Graphics4::ZCompareLess;
  407.         pipeline->depthWrite = true;
  408.         pipeline->compile();
  409.        
  410.         tex = pipeline->getTextureUnit("tex");
  411.         pvLocation = pipeline->getConstantLocation("PV");
  412.         mLocation = pipeline->getConstantLocation("M");
  413.        
  414.         objects[0] = balls[0] = new Ball(0.5f, -2.0f, 0.0f, structure, 0.25f);
  415.         objects[1] = balls[1] = new Ball(-0.5f, -2.0f, 0.0f, structure, 0.25f);
  416.        
  417.         objects[2] = balls[2] = new Ball(((float)rand() / RAND_MAX)*2-1, 4.0f, 0.0f, structure, 0.25f);
  418.         objects[3] = new MeshObject("base.obj", "floor.png", structure);
  419.         objects[3]->M = mat4::RotationX(Kore::pi / 2.0f)*mat4::Scale(0.15f, 1, 1);
  420.         objects[4] = new MeshObject("base.obj", "StarMap.png", structure);
  421.         objects[4]->M = mat4::RotationX(Kore::pi / 2.0f)*mat4::Scale(1, 1, 1)*mat4::Translation(0, 0, 0.5f);
  422.        
  423.         Graphics4::setTextureAddressing(tex, Graphics4::U, Graphics4::Repeat);
  424.         Graphics4::setTextureAddressing(tex, Graphics4::V, Graphics4::Repeat);
  425.     }
  426. }
  427.  
  428. int kore(int argc, char** argv) {
  429. #ifdef MASTER
  430.     log(Info, "I am the MASTER, I am in control of the game.");
  431. #else
  432.     log(Info, "I am the SLAVE, I want to join another game.");
  433. #endif // MASTER
  434.    
  435.     log(Info, "I am listening on port %i", port);
  436.     log(Info, "and want to connect to %s:%i\n", destination, destPort);
  437.    
  438.     Kore::System::init("Exercise 11 - "  CLIENT_NAME, width, height);
  439.    
  440.     Memory::init();
  441.     init();
  442.    
  443.     Kore::System::setCallback(update);
  444.    
  445.     startTime = System::time();
  446.    
  447.     Keyboard::the()->KeyDown = keyDown;
  448.     Keyboard::the()->KeyUp = keyUp;
  449.    
  450.     Kore::System::start();
  451.    
  452.     return 0;
  453. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement