It's been awhile since I last posted, and I apologize. I'm a web designer and been HEAVILY swamped with work lately. For the next two-six months I will be working solely on web sites and have no time for this project. As promised I will supply the source code, for those who are interested.
Client:
#include <DarkGDK.h>
#include <SC_Collision.h>
#include <MikeNet.h>
// Below used to identify what each packet is supposed to be for
#define OP_NEWPLAYER 0 // Tcp
#define OP_LEFTPLAYER 1 // Tcp
#define OP_SHOT 2 // Tcp
#define OP_POSITIONPLAYER 0 // Udp
#define HitObjects 100 // All Objects that the bullet would collide with must be bigger than this
#define BulletObjects 1000 // This is the range from where the code looks for free slots to create new bullets
#define MaxBullets 100 // This is the Max number of bullets to cycle, this effects memory
#define ShootDelay 10 // This is the amount of time between shooting
#define BulletSpeed 50 // This is the speed the bullet travels
#define BulletLife 1000 // The bullet will be killed after this time to prevent it from moving around aimlesly
// declare all variables here
float oldx;
float oldy;
float oldz;
float x;
float y;
float z;
float oax;
float oay;
float oaz;
float angx;
float angy;
float angz;
float fCameraAngleX = 0.0f;
float fCameraAngleY = 0.0f;
float vy = 0;
float gravity = -0.1f;
float slope = 0.5f;
float mouseX;
float mouseY;
int maxconnections;
int ammo = 20;
int character;
int score = 0;
int MaximumClients;
int MaximumOperations;
int collide = 0;
int bcollide = 0;
int ReloadTimer; // This is the timer alowing the player to shoot
int CurrentBullet = 200; // This is the bullet cycle
int ground = 1;
int respawnPoint;
int killedPlayer = 0;
int Bcol = 0;
char * connectIP;
char * characterInput;
char * UserName;
char * MessageSend;
unsigned int characterModel;
unsigned short connectPort = 6789;
long long int RecvPacket = mnCreatePacket();
long long int SendPacket = mnCreatePacket();
void Connect ( void ) {
mnSetMemorySize(SendPacket,1024);
int Result = mnStart(1,0);
// get ip
dbPrint("Enter the IP that you would like to connect to: ");
connectIP = dbInput();
// try connecting
int connect = mnConnect(0,connectIP,connectPort,connectIP,connectPort,10,true);
if(connect == 1)
{
dbPrint("Connection was successful!");
MaximumClients = mnGetMaxClients(0);
MaximumOperations = mnGetMaxOperations(0);
}
// If the connection timed out
if(connect == 0)
{
dbPrint("Connection timed out! Check that the server is switched on");
dbWaitKey();
return;
}
// If an error occurred during connection
if(connect == -1)
{
dbPrint("An error occurred while trying to connect");
dbWaitKey();
return;
}
}
void SelectAPlayer ( void ) {
if (mnClientConnected(0,0) == 1) {
dbCLS();
dbPasteImage(4,(dbScreenWidth()/2)-400,(dbScreenHeight()/2)-300);
dbPrint("Select a model:");
dbPrint("1. Soilder");
dbPrint("2. Sargent");
dbPrint("3. Camo");
characterInput = dbInput();
characterModel = atoi(characterInput);
if (characterModel > 3) {
character = 1;
}
else if (characterModel < 1) {
character = 1;
}
else if (characterModel == 1) {
character = 1;
}
else if (characterModel == 2) {
character = 2;
}
else if (characterModel == 3) {
character = 3;
}
}
}
void EnterUserName ( void ) {
if (mnClientConnected(0,0) == 1) {
dbCLS();
dbPasteImage(4,(dbScreenWidth()/2)-400,(dbScreenHeight()/2)-300);
dbPrint("Enter a screen name: *Less than 25 characters");
UserName = dbInput();
}
}
void CreateAPlayer ( void ){
int playerid = mnGetClientID(0);
playerid = playerid + 100;
dbMakeObjectBox (playerid,40,100,40);
respawnPoint = dbRnd(4);
respawnPoint++;
dbMakeCamera(1);
dbColorBackdrop(1, dbRGB(0,0,255) );
if (respawnPoint == 1){
dbPositionObject (playerid, 1100, 100, 0);
dbPositionCamera (1,1100,100,0);
}
else if (respawnPoint == 2){
dbPositionObject (playerid, 900, 100, 1150);
dbPositionCamera (1,900,100,1150);
}
else if (respawnPoint == 3){
dbPositionObject (playerid, -900, 100, 1150);
dbPositionCamera (1,-900,100,1150);
}
else if (respawnPoint == 4){
dbPositionObject (playerid, -1100, 100, 0);
dbPositionCamera (1,-1100,100,0);
}
else if (respawnPoint == 5){
dbPositionObject (playerid, 0, 222, 0);
dbPositionCamera (1,0,222,0);
}
dbHideObject(playerid);
SC_SetupObject (playerid, 0, 1);
}
void CreateMap ( void ) {
dbCLS();
dbLoadObject("maps/1/map.dbo",100);
dbSetObjectLight(100,0);
SC_SetupComplexObject (100,1,2);
}
void LoadImages ( void ) {
dbLoadImage("images/crosshair.png",1);
dbLoadImage("images/reload.png",3);
dbLoadImage("images/bulletmarker.png",4);
dbLoadImage("images/dead.png",5);
dbLoadImage("images/gun.jpg",6);
dbLoadImage("images/lefthud.png",7);
dbLoadImage("images/maphud.png",8);
dbSprite(1,(dbScreenWidth()/2)-24,(dbScreenHeight()/2)-24,1);
dbSprite(2,2,dbScreenHeight()-120,7);
dbSprite(3,(dbScreenWidth()/2)-200,(dbScreenHeight()/2)-150,3);
dbHideSprite(3);
dbSprite(4,(dbScreenWidth()/2)-200,(dbScreenHeight()/2)-150,5);
dbHideSprite(4);
dbSprite(5,dbScreenWidth()-233,2,8);
}
void LoadSounds ( void ) {
dbLoadSound("sounds/shoot.wav",1);
dbLoadSound("sounds/reload.wav",2);
dbLoadSound("sounds/click.wav",3);
}
void SetDisplay ( void ) {
int display;
display = dbCheckDisplayMode ( 1280, 1024, 32 );
if (display == 1) {
dbSetDisplayMode(1280,1024,32);
}
else {
display = dbCheckDisplayMode ( 1024, 768, 32 );
if (display == 1) {
dbSetDisplayMode(1024,768,32);
}
else {
display = dbCheckDisplayMode ( 800, 600, 32 );
if (display == 1) {
dbSetDisplayMode(800,600,32);
}
else {
dbCLS();
dbPrint("Your computer can not handle this game. Please get a new graphics card.");
dbWaitKey();
return;
}
}
}
dbSetWindowOff ( );
dbHideMouse ( );
dbLoadImage("images/splash.png",4);
dbPasteImage(4,(dbScreenWidth()/2)-400,(dbScreenHeight()/2)-300);
}
void Respawn ( void ) {
respawnPoint = dbRnd(4);
respawnPoint++;
int playerid = mnGetClientID(0);
playerid = playerid + 100;
if (respawnPoint == 1){
dbPositionObject (playerid, 1100, 100, 0);
dbPositionCamera (1,1100,100,0);
}
else if (respawnPoint == 2){
dbPositionObject (playerid, 900, 100, 1150);
dbPositionCamera (1,900,100,1150);
}
else if (respawnPoint == 3){
dbPositionObject (playerid, -900, 100, 1150);
dbPositionCamera (1,-900,100,1150);
}
else if (respawnPoint == 4){
dbPositionObject (playerid, -1100, 100, 0);
dbPositionCamera (1,-1100,100,0);
}
else if (respawnPoint == 5){
dbPositionObject (playerid, 0, 222, 0);
dbPositionCamera (1,0,222,0);
}
}
void CheckNetwork ( void ) {
// Check for new TCP messages
int iTcpPackets = mnRecvTCP(0,RecvPacket,NULL);
// If there is a new TCP message
if(iTcpPackets > 0)
{
// Get operation of new message
// and player that it applies to
int Operation = mnGetInt(RecvPacket);
int Player = mnGetInt(RecvPacket);
int Target = mnGetInt(RecvPacket);
// If the server is telling us that a new player has joined
// then create a cube for that player
if(Operation == OP_NEWPLAYER)
{
if(dbObjectExist(Player+100) == 0)
{
dbMakeObjectCube(Player+100,50);
//dbLoadObject ( "models/Colonel-X.X", Player+100 );
//dbLoopObject ( Player+100, 235, 259);
//dbRotateObject ( Player+100, 0, 180, 0);
SC_SetupObject ( Player+100,0,0 );
}
}
// If the server is telling us that a player has left then
// delete the cube of that player
if(Operation == OP_LEFTPLAYER)
{
if(dbObjectExist(Player+100) == 1)
{
dbDeleteObject(Player+100);
SC_RemoveObject(Player+100);
}
}
// Get Player SHOT Information
if(Operation == OP_SHOT)
{
int Killed_By = Player;
int Client_Me = mnGetClientID(0);
if (Target == Client_Me){
Respawn();
}
}
}
// Check for new UDP messages on a per client per operation basis
// Check each client
for(int Player = 1;Player<=MaximumClients;Player++)
{
// Check each operation for current client
for(int Operation = 0;Operation<MaximumOperations;Operation++)
{
// Check for new UDP messages
int UdpPackets = mnRecvUDP(0,RecvPacket,Player,Operation);
if(dbObjectExist(Player+100) == 1)
{
// If there is a new UDP message
if(UdpPackets == 1)
{
// Get the player's position and angle
// and apply them to his/her cube
float PosX = mnGetFloat(RecvPacket);
float PosY = mnGetFloat(RecvPacket);
float PosZ = mnGetFloat(RecvPacket);
float RotX = mnGetFloat(RecvPacket);
float RotY = mnGetFloat(RecvPacket);
float RotZ = mnGetFloat(RecvPacket);
dbPositionObject(Player+100,PosX,PosY,PosZ);
dbRotateObject(Player+100,RotX,RotY,RotZ);
SC_UpdateObject(Player+100);
}
}
}
}
// Send our position/angle to the server via UDP
// Formulate packet
mnAddInt(SendPacket,OP_POSITIONPLAYER);
mnAddFloat(SendPacket,dbCameraPositionX(1));
mnAddFloat(SendPacket,dbCameraPositionY(1));
mnAddFloat(SendPacket,dbCameraPositionZ(1));
mnAddFloat(SendPacket,dbCameraAngleX(1));
mnAddFloat(SendPacket,dbCameraAngleY(1));
mnAddFloat(SendPacket,dbCameraAngleZ(1));
// Send packet
mnSendUDP(0,SendPacket,NULL,false,true);
}
void MovePlayer ( void ) {
int playerid = mnGetClientID(0);
playerid = playerid + 100;
oldx = dbCameraPositionX(1);
oldy = dbObjectPositionY(playerid);
oldz = dbCameraPositionZ(1);
int speed = 3;
if (dbShiftKey()){
speed = speed + 3;
}
dbControlCameraUsingArrowKeys ( 1, speed, 0.3f );
fCameraAngleX = dbWrapValue ( fCameraAngleX + dbMouseMoveY ( ) * 0.4f );
fCameraAngleY = dbWrapValue ( fCameraAngleY + dbMouseMoveX ( ) * 0.4f );
vy = vy + gravity;
x = dbCameraPositionX(1);
z = dbCameraPositionZ(1);
collide = SC_SphereCastGroup( 1, oldx,oldy,oldz, oldx,oldy+vy,oldz, 30, 0 );
if ( collide > 0 )
{
vy=0;
}
else
{
oldy = oldy + vy;
ground = 0;
}
collide = SC_SphereSlideGroup( 1, oldx,oldy,oldz, x,oldy,z, 30, 0 );
if ( collide > 0 )
{
x = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
z = SC_GetCollisionSlideZ();
}
dbPositionObject( playerid, x, oldy, z );
dbPositionCamera( 1, x, oldy, z );
dbXRotateCamera ( 1, fCameraAngleX );
dbYRotateCamera ( 1, fCameraAngleY );
SC_UpdateObject( playerid );
}
void AmmoInfo ( void ) {
dbSetTextFont("Arial");
dbSetTextSize(20);
dbText(35,dbScreenHeight()-68,dbStr(ammo));
}
void HealthInfo ( void ) {
dbText(30,dbScreenHeight()-110,"100");
}
void SendMessage ( void ) {
dbSetTextFont("Arial");
dbSetTextSize(14);
dbSetCursor ( 0, 0 );
MessageSend = dbInput();
//MessageSend = dbEntry();
}
void ShootBullet ( void ) {
float boldx = dbCameraPositionX(1);
float boldy = dbCameraPositionY(1);
float boldz = dbCameraPositionZ(1);
dbMoveCamera(1, 2000 );
float bx = dbCameraPositionX(1);
float by = dbCameraPositionY(1);
float bz = dbCameraPositionZ(1);
dbMoveCamera(1, -2000 );
bcollide = SC_RayCast( 0, boldx,boldy,boldz, bx,by,bz, 0 );
if ( bcollide > 100 ) {
int Client_Killed = bcollide - 100;
int Client_Me = mnGetClientID(0);
mnAddInt(SendPacket,OP_SHOT);
mnAddInt(SendPacket,Client_Me);
mnAddInt(SendPacket,Client_Killed);
mnSendTCP(0,SendPacket,1,false,false);
score++;
}
else if ( bcollide > 0 ) {
//get the collision point
float newx = SC_GetStaticCollisionX();
float newy = SC_GetStaticCollisionY();
float newz = SC_GetStaticCollisionZ();
//get collision normal
float normx = SC_GetCollisionNormalX();
float normy = SC_GetCollisionNormalY();
float normz = SC_GetCollisionNormalZ();
//position and point a marker in the right direction
dbPositionObject( 501, newx + normx/100.0f, newy + normy/100.0f, newz + normz/100.0f );
dbPointObject( 501, newx + normx, newy + normy, newz + normz );
dbShowObject( 501 );
}
dbText( 0,100,dbStr(bcollide) );
// SEND INFORMATION ON WHO HAS BEEN SHOT
}
void DisplayLocation ( void ) {
dbText(dbScreenWidth()/2,0,dbStr(dbCameraPositionX(1)));
dbText(dbScreenWidth()/2,20,dbStr(dbCameraPositionY(1)));
dbText(dbScreenWidth()/2,40,dbStr(dbCameraPositionZ(1)));
}
void DisplayInfo ( void ){
dbText(0,215,"Score:");
dbText(55,215,dbStr(score));
dbText(0,230,"Welcome,");
dbText(80,230,UserName);
dbText(0,245,"Your ID:");
dbText(65,245,dbStr(mnGetClientID(0)));
}
void DisplayFPS ( void ) {
dbText(0,0,"FPS:");
dbText(40,0,dbStr(dbScreenFPS()));
}
void DarkGDK ( void )
{
SetDisplay();
Connect();
SC_Start();
SelectAPlayer();
EnterUserName();
CreateAPlayer();
CreateMap();
LoadImages();
LoadSounds();
dbSyncOn ( );
dbSyncRate ( 0 );
dbAutoCamOff( );
dbMakeObjectPlain( 501,5,5 );
dbTextureObject( 501, 4 );
dbHideObject( 501 );
dbSetObjectTransparency( 501,1);
dbLoadObject ("models/gun.x",25);
dbRotateObject(25,90,-5,0);
dbPositionObject(25,10,-10,18);
dbTextureObject(25,6);
dbLockObjectOn(25);
// our main loop
while( (mnClientConnected(0,0) == 1) && (LoopGDK() == true) )
{
MovePlayer();
AmmoInfo();
HealthInfo();
//DisplayLocation();
//DisplayFPS();
DisplayInfo();
if (dbScanCode() == 41){
SendMessage();
}
int mouseClick = dbMouseClick();
int mousePressed;
if (mouseClick == 1) {
mousePressed = mousePressed + 1;
if (mousePressed == 1){
if (ammo > 0){
ShootBullet();
ammo = ammo - 1;
dbPlaySound(1);
if (ammo == 0){
dbShowSprite(3);
}
}
else if (ammo == 0){
dbPlaySound(3);
}
}
}
if (mouseClick == 2) {
ammo = 20;
dbPlaySound(2);
dbHideSprite(3);
}
if (mouseClick == 0) {
mousePressed = 0;
}
CheckNetwork();
// update the screen
dbSync ( );
}
// If we have become disconnected from the server
dbPrint("Lost connection to server!");
dbSync();
dbWaitKey();
// Close all ports and deallocate all memory
mnFinish(-1);
mnDeletePacket(RecvPacket);
mnDeletePacket(SendPacket);
// Delete images
dbDeleteImage(1);
dbDeleteImage(2);
dbDeleteImage(3);
dbDeleteImage(4);
// Delete variables
delete [] connectIP;
delete [] characterInput;
delete [] UserName;
delete [] MessageSend;
// return back to windows
return;
}
Host:
#include <DarkGDK.h>
#include <MikeNet.h>
// Below used to identify what each packet is supposed to be for
// Tcp
#define OP_NEWPLAYER 0
#define OP_LEFTPLAYER 1
#define OP_SHOT 2 // Tcp
// Udp
#define OP_POSITIONPLAYER 0
void DarkGDK ( void )
{
// Set the local port of the server, this is the port that the server will use for both TCP and UDP
unsigned short LocalPort = 6789;
// Set the local IP of the server, this is the local IP that the server will use for both TCP and UDP
char * LocalIP = "";
// Variable to hold the result of a MikeNet command
int Result;
// Create packets to store send/recv data
long long int RecvPacket = mnCreatePacket();
long long int SendPacket = mnCreatePacket();
mnSetMemorySize(SendPacket,1024);
// Start MikeNet
Result = mnStart(1,0);
// If an error occurred starting MikeNet
if(Result == -1)
{
dbPrint("Error starting MikeNet");
dbWaitKey();
return;
}
// Set the local IP and port of the server Note: if we did not use this command then MikeNet would find a local IP and port to use automatically
Result = mnSetLocal(0,LocalIP,LocalPort,LocalIP,LocalPort);
// If an error occurred setting the local address
if(Result == -1)
{
dbPrint("Error setting the local address");
dbWaitKey();
return;
}
// Attempt to start the server
Result = mnStartServer(0,10,1,UDPMODE_PER_CLIENT_PER_OPERATION);
// If started successfully
if(Result == 0)
{
dbSetWindowTitle(mnGetLocalIP(0));
dbPrint("Server started");
dbPrint("------------------------------------------------------");
dbPrint("Server local TCP port:");
dbPrint(dbStr(mnGetLocalPortTCP(0)));
dbPrint("Server local UDP port:");
dbPrint(dbStr(mnGetLocalPortUDP(0)));
}
// If failed to start
else
{
dbPrint("Server failed to start");
dbWaitKey();
return;
}
while ( LoopGDK ( ) ){
Sleep(1);
dbWait(1);
// Check to see if a new client has joined
int Joined = mnClientJoined(0);
// If a new client has joined
if(Joined > 0)
{
// Print the client id of the new client
dbPrintC("A new client has joined. Client ID is: ");
dbPrint(dbStr(Joined));
dbPrintC("Client TCP IP is: ");
dbPrint(mnGetClientIPTCP(0,Joined));
dbPrintC("Client TCP port is: ");
dbPrint(dbStr(mnGetClientPortTCP(0,Joined)));
dbPrintC("Client UDP IP is: ");
dbPrint(mnGetClientIPUDP(0,Joined));
dbPrintC("Client UDP port is: ");
dbPrint(dbStr(mnGetClientPortUDP(0,Joined)));
dbPrint();
// Tell the new client what clients are currently connected
for(int Client = 1;Client<=10;Client++)
{
if(mnClientConnected(0, Client) == 1)
{
if(Client != Joined)
{
mnAddInt(SendPacket,OP_NEWPLAYER);
mnAddInt(SendPacket,Client);
mnSendTCP(0,SendPacket,Joined,false,false);
}
}
}
// Tell clients that a new client has joined
mnAddInt(SendPacket,OP_NEWPLAYER);
mnAddInt(SendPacket,Joined);
mnSendTCPAll(0,SendPacket,false,false,Joined);
}
// Check to see if any clients have left recently
int Left = mnClientLeft(0);
// If a client has left recently
if(Left > 0)
{
// Print the client id of the client who left
dbPrintC("Client ");
dbPrintC(dbStr(Left));
dbPrint(" has disconnected");
// Tell clients that a client has left
mnAddInt(SendPacket,OP_LEFTPLAYER);
mnAddInt(SendPacket,Left);
mnSendTCPAll(0,SendPacket,false,false,Left);
}
// Deal with new packets from all clients
for(int Client = 1; Client<=10; Client++)
{
// Check to see if any new TCP packets have been received
int TcpPackets = mnRecvTCP(0,RecvPacket,Client);
// If any have been received then do nothing
// since we don't want tcp packets from clients
if(TcpPackets > 0)
{
int Operation = mnGetInt(RecvPacket);
int Killed_By = mnGetInt(RecvPacket);
int Client_Killed = mnGetInt(RecvPacket);
if (Operation = OP_SHOT){
mnAddInt(SendPacket,OP_SHOT);
mnAddInt(SendPacket,Killed_By);
mnAddInt(SendPacket,Client_Killed);
mnSendTCPAll(0,SendPacket,false,false,Left);
dbPrint("---------------------------------------");
dbPrintC("Client: ");
dbPrintC(dbStr(Killed_By));
dbPrintC(" killed Client: ");
dbPrint(dbStr(Client_Killed));
dbPrint("---------------------------------------");
}
}
for(int Operation = 0;Operation<1;Operation++)
{
// Check to see if any new UDP packets have been received
int UdpPackets = mnRecvUDP(0,RecvPacket,Client,Operation);
// If any have been received
if(UdpPackets > 0)
{
// Get data from packet
float PosX = mnGetFloat(RecvPacket);
float PosY = mnGetFloat(RecvPacket);
float PosZ = mnGetFloat(RecvPacket);
float RotX = mnGetFloat(RecvPacket);
float RotY = mnGetFloat(RecvPacket);
float RotZ = mnGetFloat(RecvPacket);
// Relay data to clients
// Formulate packet
mnAddInt(SendPacket,Client);
mnAddInt(SendPacket,OP_POSITIONPLAYER);
mnAddFloat(SendPacket,PosX);
mnAddFloat(SendPacket,PosY);
mnAddFloat(SendPacket,PosZ);
mnAddFloat(SendPacket,RotX);
mnAddFloat(SendPacket,RotY);
mnAddFloat(SendPacket,RotZ);
// Send packet to all clients
mnSendUDPAll(0,SendPacket,false,false,Client);
}
}
}
}
// Close all sockets and shutdown MikeNet before exiting
mnFinish(-1);
mnDeletePacket(SendPacket);
mnDeletePacket(RecvPacket);
}
Hopes this helps some users! =) Raycasting, collision, networking, arrays, variables, object positioning, etc... =)
[ freelance DarkGDK coder ]