⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 <B>很多DirectX 9.0游戏编程源码例子</B>
💻 CPP
字号:
//-----------------------------------------------------------------------------
// Name: Sockets_TurnGame
//
// Description: Example code showing how to implement
//				simple turn-based gameplay over TCP/IP
//
// File Function: Main program file (main.cpp)
//
// Code: 
//		Copyright (c) 2003 LostLogic Corporation. All rights reserved.
//
// Libraries Required:
//		ws2_32.lib
//		winmm.lib
//
// Local Files Required:
//		main.h
//		main.cpp
//
//-----------------------------------------------------------------------------

// Main header
#include "main.h"

//
// Function to Create the Window and Display it ( REQUIRED FOR ALL WINDOWS PROGRAMS )
//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG			msg;
	HWND		hWnd;
	WNDCLASSEX	wndclass;
	
	// Set up window attributes
	wndclass.cbSize			= sizeof(wndclass);
	wndclass.style			= CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc	= fnMessageProcessor;
	wndclass.cbClsExtra		= 0;
	wndclass.cbWndExtra		= 0;
	wndclass.hInstance		= hInstance;
	wndclass.hIcon			= LoadIcon( NULL, IDI_APPLICATION );
	wndclass.hCursor		= LoadCursor( NULL, IDC_ARROW );
	wndclass.hbrBackground	= (HBRUSH)(COLOR_WINDOW);
	wndclass.lpszMenuName	= NULL;
	wndclass.lpszClassName	= lpszApplicationName;	// Registered Class Name
	wndclass.hIconSm		= LoadIcon( NULL, IDI_APPLICATION );

	if( RegisterClassEx( &wndclass ) == 0 ) 
	{
		// Do error logic here
		exit(1);
	}

	// Create the window
	hWnd = CreateWindow(	lpszApplicationName,		// Application Name
							lpszTitle,					// Name Displayed on Title Bar
							WS_OVERLAPPEDWINDOW,
							100,
							100,
							400,
							340,
							NULL,
							NULL,
							hInstance,
							NULL );
	
	// Set global handles
	g_hInst	= hInstance;
	g_hWnd	= hWnd;
	
	// Create child window controls
	vCreateWindowControls( hWnd );

	// Initialize sockets
	vInitializeSockets();
	
	ShowWindow( hWnd, nCmdShow );
	UpdateWindow( hWnd );
	
	// Enter the message loop
    while( msg.message != WM_QUIT ) {
        if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    };

	// Clean up sockets
	vShutdownSockets();

	return(msg.wParam);
}

// -------------------------------------------------------------------------------
LRESULT CALLBACK fnMessageProcessor ( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
	switch (iMsg)
    {
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				// Check if player wants to connect to the server
				case IDC_hBU_Connect:
					vConnect();
					break;

				// Check if player wants to host the server
				case IDC_hBU_Host:
					vHost();
					break;

				// Signal that I am done taking my turn
				case IDC_hBU_TurnDone:
					PlaySound("button.wav",NULL,SND_FILENAME|SND_ASYNC);
					if( g_bMyTurn ) {
						vTurnDone();
					}
					break;

				default:
					break;
			}
			break;

		case WM_DESTROY:
			PostQuitMessage( 0 );
			break;
			
		default:
			break;
    }
	return DefWindowProc( hWnd, iMsg, wParam, lParam );
}

//
// Function to Initialize window objects
//
void vCreateWindowControls(HWND hWnd)
{
	// hEB_InputServerIP
	hST_TextServerIP = CreateWindow(
		"static","Server IP",
		WS_CHILD | SS_CENTER | WS_VISIBLE,
		5,
		5,
		120,
		28,
		hWnd,(HMENU)IDC_hST_TextServerIP,g_hInst,NULL);

	// hEB_InputServerIP
	hST_TextServerPort = CreateWindow(
		"static","Port",
		WS_CHILD | SS_CENTER | WS_VISIBLE,
		125,
		5,
		50,
		28,
		hWnd,(HMENU)IDC_hST_TextServerPort,g_hInst,NULL);

	// hEB_InputServerIP
	hEB_InputServerIP = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		"EDIT","192.168.0.2",
		WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
		5,
		20,
		120,
		28,
		hWnd,(HMENU)IDC_hEB_InputServerIP,g_hInst,NULL);

	// hEB_InputServerPort
	hEB_InputServerPort = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		"EDIT","6001",
		WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT,
		125,
		20,
		50,
		28,
		hWnd,(HMENU)IDC_hEB_InputServerPort,g_hInst,NULL);

	// hLB_Output
	hLB_Output = CreateWindowEx(
		WS_EX_CLIENTEDGE,
		"LISTBOX",
		NULL,
		WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_BORDER,
		5,
		47,
		380,
		230,
		hWnd,(HMENU)IDC_hLB_Output,g_hInst,NULL);	
	
	// hBU_Connect
	hBU_Connect = CreateWindow(
		"BUTTON",
		"Connect",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		285,
		280,
		100,
		28,
		hWnd,(HMENU)IDC_hBU_Connect,g_hInst,NULL);

	// hBU_Host
	hBU_Host = CreateWindow(
		"BUTTON",
		"Host",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		175,
		280,
		100,
		28,
		hWnd,(HMENU)IDC_hBU_Host,g_hInst,NULL);
}

//
// Function to Initialize sockets
//
void vInitializeSockets( void )
{
	WSADATA		wsaData;
	WORD		wVersionRequested;

	// Tell WinSock we want version 2
	wVersionRequested = MAKEWORD( 2, 0 );

	// Startup WinSock
	WSAStartup( wVersionRequested, &wsaData );
}

//
// Function to display text into the edit window
//
void vShowText(char *szText)
{
	int Line;
	
	// add string to the listbox
	SendMessage(hLB_Output,LB_ADDSTRING,0,(LPARAM) szText);
	
	// determine number of items in listbox
	Line = SendMessage(hLB_Output,LB_GETCOUNT,0,0);
	
	// flag last item as the selected item, to scroll listbox down
	SendMessage(hLB_Output,LB_SETCURSEL,Line-1,0);
	
	// unflag all items to eliminate negative highlite
	SendMessage(hLB_Output,LB_SETCURSEL,-1,0);
}

//
// Function to host the game.  The host listens on a socket and
// accepts the client connection when it comes in.  Once the client
// is connected, the server waits for the first game turn packet.
//
void vHost( void )
{
	sockaddr_in saServerAddress;
	sockaddr_in saClientAddress;
	int			iClientSize = sizeof(sockaddr_in);
	int			iPort = 6001;
	int			iStatus;

	// ** FOR YOU TO DO **
	// Pull the port number from the
	// windows controls.

	// Set global var
	g_bIsServer = 1;
	
	// Initialize the socket handle
	g_skListenSocket = INVALID_SOCKET;

	// Create the socket
	g_skListenSocket = socket( AF_INET, SOCK_STREAM, 0 );
	
	// Check if there was an error
	if( g_skListenSocket == INVALID_SOCKET ) {
		vShowText( "** ERROR ** Could Not Create Socket" );
		return;
	}

	vShowText( "<- Socket Created ->" );

	// Clear out the socket address structure
	memset(&saServerAddress, 0, sizeof(sockaddr_in));

	// Initialize the socket address structure
	saServerAddress.sin_family = AF_INET;
	saServerAddress.sin_addr.s_addr = htonl( INADDR_ANY );
	saServerAddress.sin_port = htons( iPort );

	// Attempt to bind
	if( bind( g_skListenSocket, (sockaddr*) &saServerAddress, sizeof(sockaddr) ) == SOCKET_ERROR ) {
		vShowText( "** ERROR ** Could Not Bind Socket" );
		return;
	}

	vShowText( "<- Socket Bound ->" );

	// Listen for a connection
	iStatus = listen( g_skListenSocket, 32 );

	if( iStatus == SOCKET_ERROR ) {
		vShowText( "** ERROR ** Could Not Listen" );
		// Close the socket
		closesocket(g_skListenSocket);
		return;
	}

	vShowText( "<- Socket Listening ->" );
	
	g_skClientSocket = accept( g_skListenSocket, (struct sockaddr*)&saClientAddress, &iClientSize );
	
	if( g_skClientSocket == INVALID_SOCKET ) {
		vShowText( "** ERROR ** Could Not Accept Client" );
		// Close the socket
		closesocket(g_skListenSocket);
		return;
	}

	// Turn off buttons
	DestroyWindow( hBU_Connect );
	DestroyWindow( hBU_Host );

	vShowText( "<- Client Connected ->" );

	// Flag as connected
	g_bConnected = 1;

	// Flag that it is the other player's turn
	// to end the turn
	g_bMyTurn = 0;

	// Wait for client's first turn
	vTurnDone();
}

//
// Function to connect to the host game server.  Once connected, the
// client has the option to end the turn.
//
void vConnect( void )
{
	sockaddr_in saServerAddress;
	int			iPort = 6001,iStatus;
	LPHOSTENT	lpHost;
	char		szHost[128];

	// ** FOR YOU TO DO **
	// Pull the server IP and port number from the
	// windows controls.

	// Set global var
	g_bIsServer = 0;

	// Init the host value, change this IP to whatever valid IP you wish
	sprintf( szHost,"192.168.0.2" );

	// Initialize the socket handle
	g_skClientSocket = INVALID_SOCKET;

	// Create the socket
	g_skClientSocket = socket( AF_INET, SOCK_STREAM, 0 );

	// Check if there was an error
	if( g_skClientSocket == INVALID_SOCKET ) {
		vShowText( "** ERROR ** Could Not Create Socket" );
		return;
	}

	vShowText( "<- Socket Created ->" );

	// Initialize the server address data structure
	memset(&saServerAddress,0,sizeof(sockaddr_in));
	// Set this by default
	saServerAddress.sin_family = AF_INET;
	// Load the IP Address
	saServerAddress.sin_addr.s_addr = inet_addr(szHost);

	// If the host specified is not an IP Address we must look up the value
	if( saServerAddress.sin_addr.s_addr == INADDR_NONE )
	{
		vShowText( "<- Looking Up Host ID ->" );
		// Get the host name
		lpHost = gethostbyname(szHost);
		// Check if we got something back
		if (lpHost != NULL) {
			// Load the server address with the host information
			saServerAddress.sin_addr.s_addr = ((LPIN_ADDR)lpHost->h_addr)->s_addr;
		}
		else {
			vShowText( "** ERROR ** Could Not locate host" );
			return;
		}
	}

	// Set the Server Port
	saServerAddress.sin_port = htons(iPort);

	// Attempt to connect to the server
	iStatus = connect( g_skClientSocket, (struct sockaddr*)&saServerAddress,sizeof(sockaddr));

	// Check if there was an error
	if( iStatus == SOCKET_ERROR ) {
		vShowText( "** ERROR ** Could Not Connect To Server" );
		return;
	}

	// Turn off buttons
	DestroyWindow( hBU_Connect );
	DestroyWindow( hBU_Host );

	vShowText( "<- Connected To Server ->" );

	// Flag as connected
	g_bConnected = 1;
	// Flag that it is my turn to end the turn
	g_bMyTurn = 1;

	// Turn on the Turn Done window
	hBU_TurnDone = CreateWindow(
		"BUTTON",
		"Turn Done",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		5,
		280,
		100,
		28,
		g_hWnd,(HMENU)IDC_hBU_TurnDone,g_hInst,NULL);

	vShowText( ":Server waiting, make your turn" );
}

//
// Function to close any outstanding sockets
//
void vShutdownSockets( void )
{
	// Check if connected
	if( g_bConnected ) {
		// Check if server
		if( g_bIsServer ) {
			// Close listen socket
			closesocket( g_skListenSocket );
		}
		// Close client socket
		closesocket( g_skClientSocket );
	}

	// Clean up WinSock
	WSACleanup();
}

//
// Function to tell the other player the turn is complete.
//
void vTurnDone( void )
{
	// If connected, check to send or receive turn message
	if( g_bConnected ) {

		// My turn, send the message
		if( g_bMyTurn ) {

			// Disable turn button
			DestroyWindow( hBU_TurnDone );

			// Send turn over message
			vSendTurnMessage();

			if( g_bIsServer ) {
				vShowText( ":Waiting for client's turn" );
			}
			else {
				vShowText( ":Waiting for servers's turn" );
			}
			// Wait for receive message
			vReceiveTurnMessage();

			if( g_bIsServer ) {
				vShowText( ":Client waiting, make your turn" );
			}
			else {
				vShowText( ":Server waiting, make your turn" );
			}
		}
		else {
			if( g_bIsServer ) {
				vShowText( ":Waiting for client's turn" );
			}
			else {
				vShowText( ":Waiting for servers's turn" );
			}
			// Wait for receive message
			vReceiveTurnMessage();
			
			if( g_bIsServer ) {
				vShowText( ":Client waiting, make your turn" );
			}
			else {
				vShowText( ":Server waiting, make your turn" );
			}
		}
	}
}

//
// Sends the actual turn-end packet.
//
void vSendTurnMessage( void )
{
	char	szTurnPacket[ 32 ];
	int		iBytes = 0;

	// Create a "dummy" packet
	sprintf( szTurnPacket, "turnpacket" );
	// Send the packet
	iBytes = send( g_skClientSocket, szTurnPacket, 32, 0 );
	if( iBytes != SOCKET_ERROR ) {
	}
	else {
		vShowText( "** ERROR ** Sending" );
		return;
	}

	// Set to receive mode now
	g_bMyTurn = 0;
}

//
// Waits for a turn-end packet.
//
void vReceiveTurnMessage( void )
{
	char	szTurnPacket[ 32 ];
	int		iBytes = 0;

	iBytes = recv( g_skClientSocket, szTurnPacket, 32, 0 );
	// Check return code
	if( iBytes != SOCKET_ERROR ) {
	}
	else {
		vShowText( "** ERROR ** Receiving" );
		return;
	}

	// Set to send mode now
	g_bMyTurn = 1;

	// Turn on the Turn Done button
	hBU_TurnDone = CreateWindow(
		"BUTTON",
		"Turn Done",
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		5,
		280,
		100,
		28,
		g_hWnd,(HMENU)IDC_hBU_TurnDone,g_hInst,NULL);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -