Current Working Tree on <2023-10-16>
This commit is contained in:
parent
11b568550c
commit
1a7348dbd0
|
@ -17,8 +17,7 @@
|
|||
const char * messageStrings[] = {"HELLO", "GOODBYE", "PING", "PONG", "SECRET"};
|
||||
typedef struct SpacewarNetworkConfig
|
||||
{
|
||||
uint8_t playerNumber;
|
||||
uint32_t secretKey;
|
||||
SpacewarClientInput input;
|
||||
SpacewarState * state;
|
||||
} SpacewarNetworkConfig;
|
||||
|
||||
|
@ -42,23 +41,20 @@ void * runNetworkThread (void * parameters)
|
|||
|
||||
// A structure to store the most recent state from the network:
|
||||
SpacewarState * updatedState = calloc(1, sizeof(SpacewarState));
|
||||
|
||||
SpacewarClientInput input;
|
||||
input.secret = configuration->secretKey;
|
||||
input.playerNumber = configuration->playerNumber;
|
||||
|
||||
while (true)
|
||||
{
|
||||
sendto(udpSocket, &input, sizeof(SpacewarClientInput), 0, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
|
||||
sendto(udpSocket, &configuration->input, sizeof(SpacewarClientInput), 0,
|
||||
(struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
|
||||
recvfrom(udpSocket, updatedState, sizeof(SpacewarState), 0, NULL, NULL);
|
||||
memcpy(configuration->state, updatedState, sizeof(SpacewarState));
|
||||
// printf("Received, %f\t%f\n", updatedState->playerStates[0].position.xComponent,
|
||||
// updatedState->playerStates[0].position.yComponent);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
xyVector upVector = {0, 0.1};
|
||||
|
||||
// Initialize the SDL library, video, sound, and input:
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||
{
|
||||
|
@ -73,7 +69,8 @@ int main(int argc, char ** argv)
|
|||
TTF_Init();
|
||||
|
||||
// Create an SDL window and rendering context in that window:
|
||||
SDL_Window * window = SDL_CreateWindow("SDL_TEST", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 360, 0);
|
||||
SDL_Window * window = SDL_CreateWindow("SDL_TEST", SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED, 640, 360, 0);
|
||||
uint32_t rendererFlags = SDL_RENDERER_ACCELERATED;
|
||||
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, rendererFlags);
|
||||
SDL_SetWindowTitle(window, "Spacewar!");
|
||||
|
@ -167,6 +164,7 @@ int main(int argc, char ** argv)
|
|||
printf("Connected.\n");
|
||||
|
||||
bool playerNumberSet, secretKeySet;
|
||||
uint8_t playerNumber;
|
||||
SpacewarNetworkConfig networkConfiguration;
|
||||
SpacewarMessage message;
|
||||
|
||||
|
@ -178,21 +176,20 @@ int main(int argc, char ** argv)
|
|||
case 0:
|
||||
{
|
||||
playerNumberSet = true;
|
||||
networkConfiguration.playerNumber = message.content;
|
||||
playerNumber = message.content;
|
||||
networkConfiguration.input.playerNumber = message.content;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
secretKeySet = true;
|
||||
networkConfiguration.secretKey = message.content;
|
||||
networkConfiguration.input.secret = message.content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
networkConfiguration.state = calloc(1, sizeof(SpacewarState));
|
||||
|
||||
printf("Player Number: %u\n"
|
||||
"Secret Key: %u\n", networkConfiguration.playerNumber, networkConfiguration.secretKey);
|
||||
SpacewarState * state = calloc(1, sizeof(SpacewarState));
|
||||
networkConfiguration.state = state;
|
||||
|
||||
// Spawn network thread:
|
||||
pthread_t networkThread;
|
||||
|
@ -203,20 +200,101 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
pthread_t clientSidePredictionThread;
|
||||
}
|
||||
|
||||
// Load in all of our textures:
|
||||
SDL_Texture * blackHoleTexture, * idleTexture, * acceleratingTexture, * clockwiseTexture,
|
||||
* anticlockwiseTexture, * currentTexture, * acceleratingTexture2, *blackHolePointerTexture;
|
||||
|
||||
SDL_Rect starfieldRect;
|
||||
SDL_Texture * starfieldTexture = IMG_LoadTexture(renderer, "../Images/Starfield.png");
|
||||
SDL_QueryTexture(starfieldTexture, NULL, NULL, &starfieldRect.w, &starfieldRect.h);
|
||||
|
||||
idleTexture = IMG_LoadTexture(renderer, "../Images/Ship-Idle.png");
|
||||
blackHoleTexture = IMG_LoadTexture(renderer, "../Images/Black-Hole.png");
|
||||
clockwiseTexture = IMG_LoadTexture(renderer, "../Images/Ship-Clockwise.png");
|
||||
acceleratingTexture = IMG_LoadTexture(renderer, "../Images/Ship-Accelerating.png");
|
||||
anticlockwiseTexture = IMG_LoadTexture(renderer, "../Images/Ship-Anticlockwise.png");
|
||||
blackHolePointerTexture = IMG_LoadTexture(renderer, "../Images/Black-Hole-Pointer.png");
|
||||
acceleratingTexture2 = IMG_LoadTexture(renderer, "../Images/Ship-Accelerating-Frame-2.png");
|
||||
currentTexture = acceleratingTexture;
|
||||
|
||||
SDL_Rect blackHoleRectangle;
|
||||
blackHoleRectangle.x = 0;
|
||||
blackHoleRectangle.y = 0;
|
||||
SDL_QueryTexture(blackHoleTexture, NULL, NULL,
|
||||
&blackHoleRectangle.w, &blackHoleRectangle.h);
|
||||
|
||||
|
||||
SDL_Rect blackHolePointerRectangle;
|
||||
blackHolePointerRectangle.x = 0;
|
||||
blackHolePointerRectangle.y = 0;
|
||||
blackHolePointerRectangle.w = 128;
|
||||
blackHolePointerRectangle.h = 128;
|
||||
|
||||
SDL_Rect shipRectangles[32];
|
||||
for (int index = 0; index < 32; index++)
|
||||
{
|
||||
shipRectangles[index].w = 32;
|
||||
shipRectangles[index].h = 32;
|
||||
}
|
||||
|
||||
// Spawn graphics thread:
|
||||
int width, height;
|
||||
while (true)
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
SDL_GetKeyboardState(&keyCount);
|
||||
SDL_GetWindowSize(window, &width, &height);
|
||||
|
||||
// Do input:
|
||||
networkConfiguration.input.input.turningClockwise = keyboardState[SDL_SCANCODE_RIGHT];
|
||||
networkConfiguration.input.input.turningAnticlockwise = keyboardState[SDL_SCANCODE_LEFT];
|
||||
networkConfiguration.input.input.accelerating = keyboardState[SDL_SCANCODE_UP];
|
||||
|
||||
// Clear the screen:
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
|
||||
SDL_GetWindowSize(window, &width, &height);
|
||||
SDL_RenderDrawLine(renderer, width/2, height/2,
|
||||
width/2 + (long)(networkConfiguration.state->playerStates[0].velocity.xComponent),
|
||||
height/2 + (long)(networkConfiguration.state->playerStates[0].velocity.yComponent));
|
||||
|
||||
// Draw the starfield:
|
||||
starfieldRect.x = -900 - (long)state->playerStates[playerNumber].position.xComponent % 800;
|
||||
starfieldRect.y = -900 - (long)state->playerStates[playerNumber].position.yComponent % 800;
|
||||
|
||||
while(starfieldRect.x <= (width + 800))
|
||||
{
|
||||
while(starfieldRect.y <= (height + 800))
|
||||
{
|
||||
SDL_RenderCopy(renderer, starfieldTexture, NULL, &starfieldRect);
|
||||
starfieldRect.y += 800;
|
||||
}
|
||||
starfieldRect.y = -900 - (long)state->playerStates[playerNumber].position.yComponent % 800;
|
||||
starfieldRect.x += 800;
|
||||
}
|
||||
|
||||
// Draw the black hole:
|
||||
blackHoleRectangle.x = ((long)(0 - state->playerStates[playerNumber].position.xComponent
|
||||
- (blackHoleRectangle.w / 2)) + width/2);
|
||||
blackHoleRectangle.y = ((long)(0 - state->playerStates[playerNumber].position.yComponent
|
||||
- (blackHoleRectangle.h / 2)) + height/2);
|
||||
|
||||
SDL_RenderCopy(renderer, blackHoleTexture, NULL, &blackHoleRectangle);
|
||||
|
||||
// Draw the black hole directional indicator:
|
||||
blackHolePointerRectangle.x = width/2 - (blackHolePointerRectangle.w / 2);
|
||||
blackHolePointerRectangle.y = height/2 - (blackHolePointerRectangle.h / 2);
|
||||
SDL_RenderCopyEx(renderer, blackHolePointerTexture, NULL, &blackHolePointerRectangle,
|
||||
angleBetweenVectors(&state->playerStates[playerNumber].gravity, &upVector) + 90,
|
||||
NULL, 0);
|
||||
|
||||
// Draw the player's ship:
|
||||
shipRectangles[playerNumber].x = (width/2) - 16;
|
||||
shipRectangles[playerNumber].y = (height/2) - 16;
|
||||
|
||||
SDL_RenderCopyEx(renderer, currentTexture, NULL, &shipRectangles[playerNumber],
|
||||
angleBetweenVectors(&state->playerStates[playerNumber].engine, &upVector) + 90,
|
||||
NULL, 0);
|
||||
|
||||
// Present to the screen:
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_Delay(1000 / 144);
|
||||
}
|
||||
pthread_join(networkThread, NULL);
|
||||
|
||||
|
@ -240,5 +318,5 @@ int main(int argc, char ** argv)
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Local Variables:
|
||||
// compile-command: "gcc `sdl2-config --libs --cflags` Spacewar-Client.c Spacewar-Graphics.c Spacewar-Server.c -lSDL2_image -lSDL2_ttf -lm -o 'Spacewar-Client'"
|
||||
// compile-command: "gcc `sdl2-config --libs --cflags` Spacewar-Client.c Spacewar-Graphics.c Spacewar-Server.c Spacewar-Physics.c -lSDL2_image -lSDL2_ttf -lm -o 'Spacewar-Client'"
|
||||
// End:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
void doPhysicsTick(SpacewarState * state)
|
||||
{
|
||||
double gravityMagnitude, gravityAcceleration;
|
||||
double gravityMagnitude, gravityAcceleration, velocityMagnitude;
|
||||
for (int shipIndex = 0; shipIndex < 32; shipIndex++)
|
||||
{
|
||||
SpacewarShipState * currentShip = &state->playerStates[shipIndex];
|
||||
|
@ -21,26 +21,40 @@ void doPhysicsTick(SpacewarState * state)
|
|||
0.0, 0.0, ¤tShip->gravity);
|
||||
gravityMagnitude = normalizeXYVector(¤tShip->gravity);
|
||||
gravityAcceleration = 0;
|
||||
|
||||
|
||||
// Some maths that felt okay:
|
||||
if (gravityMagnitude >= 116)
|
||||
{
|
||||
gravityAcceleration = pow(2, (3000 / (gravityMagnitude / 2))) / 16;
|
||||
gravityAcceleration = (45000 / pow(gravityMagnitude, 2)) * 6.67;
|
||||
}
|
||||
// We're actually in the black hole; teleport:
|
||||
// We're pactually in the black hole; teleport:
|
||||
else
|
||||
{
|
||||
currentShip->position.xComponent = (double)(random() % 7500);
|
||||
currentShip->position.yComponent = (double)(random() % 7500);
|
||||
currentShip->velocity.xComponent *= 0.01;
|
||||
currentShip->velocity.yComponent *= 0.01;
|
||||
currentShip->velocity.xComponent = 0;
|
||||
currentShip->velocity.yComponent = 0;
|
||||
}
|
||||
|
||||
|
||||
multiplyXYVector(¤tShip->gravity, gravityAcceleration);
|
||||
|
||||
// Apply Inputs:
|
||||
|
||||
// Rotate the engine vector if needed:
|
||||
if (state->playerInputs[shipIndex].turningClockwise == 1)
|
||||
{
|
||||
rotateXYVector(¤tShip->engine, 2.5);
|
||||
}
|
||||
if (state->playerInputs[shipIndex].turningAnticlockwise == 1)
|
||||
{
|
||||
rotateXYVector(¤tShip->engine, -2.5);
|
||||
}
|
||||
|
||||
// Apply Gravity and Velocity to Position:
|
||||
if (state->playerInputs[shipIndex].accelerating == 1)
|
||||
{
|
||||
addXYVector(¤tShip->velocity, ¤tShip->engine);
|
||||
}
|
||||
addXYVector(¤tShip->velocity, ¤tShip->gravity);
|
||||
addXYVector(¤tShip->position, ¤tShip->velocity);
|
||||
|
||||
|
@ -65,7 +79,6 @@ void doPhysicsTick(SpacewarState * state)
|
|||
state->playerStates[shipIndex].position.yComponent = 7999.0;
|
||||
state->playerStates[shipIndex].velocity.yComponent *= 0.9;
|
||||
}
|
||||
printf("%f %f\n", currentShip->position.xComponent, currentShip->position.yComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ typedef struct SpacewarShipState
|
|||
typedef struct SpacewarShipInput
|
||||
{
|
||||
double turningAmount, acceleratingAmount;
|
||||
bool turningClockwise, turningAnticlockwise, accelerating;
|
||||
uint8_t turningClockwise, turningAnticlockwise, accelerating;
|
||||
} SpacewarShipInput;
|
||||
|
||||
typedef struct SpacewarClientInput
|
||||
|
|
|
@ -43,7 +43,11 @@ void sendCurrentState(SpacewarState * state, SpacewarConnection * connections, i
|
|||
void * runServerPhysics(void * parameters)
|
||||
{
|
||||
SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters;
|
||||
|
||||
for(int index = 0; index < 32; index++)
|
||||
{
|
||||
sharedState->physicsState->playerStates[index].engine.yComponent = 0.1;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
doPhysicsTick(sharedState->physicsState);
|
||||
|
@ -67,25 +71,21 @@ void * runInputReceiver(void * parameters)
|
|||
{
|
||||
bytesRead = recvfrom(sharedState->udpSocket, &input, sizeof(SpacewarClientInput), 0,
|
||||
(struct sockaddr *)&clientAddress, &socketAddressLength);
|
||||
// printf("Read an input... ");
|
||||
if (bytesRead == sizeof(SpacewarClientInput))
|
||||
{
|
||||
// printf("It's the right size... ");
|
||||
if (input.playerNumber < 32)
|
||||
{
|
||||
// printf("Valid player number... ");
|
||||
if (input.secret == sharedState->connections[input.playerNumber].playerSecret)
|
||||
{
|
||||
// printf("Valid input for player %d!\n", index);
|
||||
sharedState->physicsState->playerStates[input.playerNumber].inPlay = true;
|
||||
memcpy(&sharedState->connections[input.playerNumber].clientAddress,
|
||||
&clientAddress, sizeof(struct sockaddr_in));
|
||||
memcpy(&sharedState->physicsState->playerInputs[input.playerNumber], &(input.input),
|
||||
sizeof(struct SpacewarShipInput));
|
||||
memcpy(&sharedState->physicsState->playerInputs[input.playerNumber], &input.input,
|
||||
sizeof(SpacewarShipInput));
|
||||
}
|
||||
}
|
||||
}
|
||||
bzero(&input, sizeof(struct SpacewarClientInput));
|
||||
bzero(&input, sizeof(SpacewarClientInput));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue