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

📄 unigen.cpp

📁 游戏编程精粹,对刚入门的游戏开发者很有帮助
💻 CPP
字号:
/* Copyright (C) Guy W. Lecky-Thompson, 2000.  * All rights reserved worldwide. * * This software is provided "as is" without express or implied * warranties. You may freely copy and compile this source into * applications you distribute provided that the copyright text * below is included in the resulting source code, for example: * "Portions Copyright (C) Guy W. Lecky-Thompson, 2000" */// Universe Generation and Display Engine// (c) 2000 Guy W. Lecky-Thompson// Standard C libraries to use#include <stdlib.h>#include <string.h>// Windows-specific libraries#include <windows.h>// Engine-specific includes#include "unigen.h"void GenerateRandomUniverse(int universe[UNIVERSE_SIDE][UNIVERSE_SIDE],									 long universe_serial_number){	int x, y;	long grid_reference;	int random_value;	for (y = 0; y < UNIVERSE_SIDE; y++)	{		for (x = 0; x < UNIVERSE_SIDE; x++)		{			// Calculate the grid reference for this point			grid_reference = x + (y * UNIVERSE_SIDE);			// Seed the random number generator			srand((unsigned)universe_serial_number + (unsigned)grid_reference);			// Choose a value for this point			random_value = rand() % 100;			if (random_value > STAR_THRESHOLD)			{				universe[x][y] = 1;			}			else			{				universe[x][y] = 0;			}		}	}}int FeatureAt(long universe_serial_number, int grid_x, int grid_y){	int random_value, position_counter;	srand((unsigned)universe_serial_number + (unsigned)grid_y);	position_counter = grid_x;	while (position_counter > -1)	{		random_value = rand() % 100;		position_counter--;	} 	if (random_value > STAR_THRESHOLD) return 1;	return 0;}void DisplayUniverse(long universe_serial_number,							RECT * rcTarget,							HDC hdcTarget){	HPEN hBlackPen = CreatePen(PS_SOLID,1,RGB(0,0,0));	HPEN hWhitePen = CreatePen(PS_SOLID,1,RGB(255,255,255));	HBRUSH hBlackBrush = CreateSolidBrush(RGB(0,0,0));	HBRUSH hWhiteBrush = CreateSolidBrush(RGB(255,255,255));	HPEN hOldPen;	HFONT hOldFont;	HBRUSH hOldBrush;	char name[10];	int name_length;	RECT rcNameRect;   TEXTMETRIC tm;	int nSquareXSide = (rcTarget->right  - rcTarget->left) / UNIVERSE_SIDE;	int nSquareYSide = (rcTarget->bottom - rcTarget->top)  / UNIVERSE_SIDE;	int x,y;	HFONT hfnt;	LOGFONT lf;	SetTextColor(hdcTarget,RGB(255,255,255));	SetBkColor(hdcTarget,RGB(0,0,0));	hfnt = (HFONT)GetStockObject(SYSTEM_FONT);	GetObject(hfnt, sizeof(LOGFONT), &lf);	lf.lfWeight = FW_THIN;	lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;	lf.lfPitchAndFamily = VARIABLE_PITCH|FF_SWISS;	lf.lfHeight = -8;	lf.lfWidth = 0;	hfnt = CreateFontIndirect(&lf);	hOldFont = (HFONT)SelectObject(hdcTarget,hfnt);	hOldBrush = (HBRUSH)SelectObject(hdcTarget,hBlackBrush);	hOldPen = (HPEN)SelectObject(hdcTarget,hBlackPen);	Rectangle(hdcTarget,rcTarget->left,rcTarget->top,							  rcTarget->left + (nSquareXSide * UNIVERSE_SIDE),							  rcTarget->top  + (nSquareYSide * UNIVERSE_SIDE));	for (y = 0; y < UNIVERSE_SIDE; y++)	{		for (x = 0; x < UNIVERSE_SIDE; x++)		{			if (FeatureAt(universe_serial_number,x,y) == 1)			{				hOldPen = (HPEN)SelectObject(hdcTarget,hWhitePen);				hOldBrush = (HBRUSH)SelectObject(hdcTarget,hWhiteBrush);				Ellipse(hdcTarget,x * nSquareXSide, y * nSquareYSide,									  (x * nSquareXSide) + 2,									  (y * nSquareYSide) + 2);				name_length = GenerateName(universe_serial_number,x,y,name);				rcNameRect.left = (x * nSquareXSide) + 3;				rcNameRect.top  = (y * nSquareYSide) + 3;				// Use the font size to figure if we're too close to the edge or over it				GetTextMetrics(hdcTarget,&tm);				if (rcNameRect.left + (tm.tmMaxCharWidth * name_length) > rcTarget->right)				{					rcNameRect.left = rcNameRect.left -						((rcNameRect.left + (tm.tmMaxCharWidth * name_length)) -						  rcTarget->right);				}				TextOut(hdcTarget,rcNameRect.left,rcNameRect.top,								name,name_length);				SelectObject(hdcTarget,hOldPen);            SelectObject(hdcTarget,hOldBrush);			}		}	}	// Clean up to prevent memory leaks	SelectObject(hdcTarget,hOldFont);	SelectObject(hdcTarget,hOldBrush);	SelectObject(hdcTarget,hOldPen);	DeleteObject(hfnt);	DeleteObject(hBlackPen);	DeleteObject(hWhitePen);	DeleteObject(hBlackBrush);	DeleteObject(hWhiteBrush);}int GenerateName(long universe_serial_number,						int x, int y,						char name[10]){	int word_length;	int char_pos;	srand((unsigned)universe_serial_number + (unsigned)(UNIVERSE_SIDE * y) + (unsigned)x);	word_length = (rand() % 6) + 4;	for (char_pos = 0; char_pos <= word_length; char_pos++)	{		name[char_pos] = 'A' + (rand() % 26);		name[char_pos+1] = '\0';	}	return word_length;}void GetNumberOfPlanets(long universe_serial_number,						int x, int y,						char number_of_planets[12]){	srand((unsigned)universe_serial_number + (unsigned)(UNIVERSE_SIDE * y) + (unsigned)x);	wsprintf(number_of_planets,"Planets : %2d",rand() % 12);}void DisplayFeatureInformation(long universe_serial_number,										 RECT * rcMapWindow,										 int mouse_x, int mouse_y,										 RECT * rcMapInfo,HDC hdcTarget){	int map_x, map_y,name_length;	int nSquareXSide = (rcMapWindow->right  - rcMapWindow->left) / UNIVERSE_SIDE;	int nSquareYSide = (rcMapWindow->bottom - rcMapWindow->top)  / UNIVERSE_SIDE;	char name[10];	char number_of_planets[12];	HFONT hfnt, hOldFont;	LOGFONT lf;	RECT rcTextRect;	HPEN hGrayPen, hOldPen;	HBRUSH hGrayBrush, hOldBrush;	hGrayPen = CreatePen(PS_SOLID,1,PALETTERGB(200,200,200));	hGrayBrush = CreateSolidBrush(PALETTERGB(200,200,200));	hOldPen = (HPEN)SelectObject(hdcTarget,hGrayPen);	hOldBrush = (HBRUSH)SelectObject(hdcTarget,hGrayBrush);	hfnt = (HFONT)GetStockObject(SYSTEM_FONT);	GetObject(hfnt, sizeof(LOGFONT), &lf);	map_x = mouse_x / nSquareXSide;	map_y = mouse_y / nSquareYSide;	if (FeatureAt(universe_serial_number,map_x,map_y) == 1)	{		name_length = GenerateName(universe_serial_number,map_x,map_y,name);		lf.lfWeight = FW_THIN;		lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;		lf.lfPitchAndFamily = VARIABLE_PITCH|FF_SWISS;		SetTextColor(hdcTarget,RGB(0,0,0));		SetBkColor(hdcTarget,PALETTERGB(200,200,200));		rcTextRect.left = rcMapInfo->left + 1;		rcTextRect.right = rcMapInfo->right - 1;		rcTextRect.top    = rcMapInfo->top + 1;		rcTextRect.bottom = ((rcMapInfo->bottom - rcMapInfo->top) -2) / 4;		Rectangle(hdcTarget,rcTextRect.left,rcTextRect.top,								  rcTextRect.right,rcTextRect.bottom);		lf.lfHeight = (rcTextRect.bottom - rcTextRect.top);		lf.lfWidth = 0;		hfnt = CreateFontIndirect(&lf);		hOldFont = (HFONT)SelectObject(hdcTarget,hfnt);		DrawText(hdcTarget,name,name_length,&rcTextRect,DT_SINGLELINE|DT_VCENTER|DT_CENTER);		SelectObject(hdcTarget,hOldFont);		DeleteObject(hfnt);		// Show the number of planets		GetNumberOfPlanets(universe_serial_number,map_x,map_y,number_of_planets);		rcTextRect.top = rcTextRect.bottom;		rcTextRect.bottom = rcTextRect.bottom + (((rcMapInfo->bottom - rcMapInfo->top) -2) / 4);  		Rectangle(hdcTarget,rcTextRect.left,rcTextRect.top,								  rcTextRect.right,rcTextRect.bottom);		lf.lfHeight = (rcTextRect.bottom - rcTextRect.top);		lf.lfWidth = 0;		hfnt = CreateFontIndirect(&lf);		hOldFont = (HFONT)SelectObject(hdcTarget,hfnt);		DrawText(hdcTarget,number_of_planets,12,&rcTextRect,DT_SINGLELINE|DT_VCENTER|DT_CENTER);		SelectObject(hdcTarget,hOldFont);		DeleteObject(hfnt);	}	SelectObject(hdcTarget,hOldFont);	SelectObject(hdcTarget,hOldBrush);	SelectObject(hdcTarget,hOldPen);	DeleteObject(hfnt);	DeleteObject(hGrayPen);	DeleteObject(hGrayBrush);}void BlankRect(HDC hdcTarget, RECT * rcTarget, COLORREF fg, COLORREF bk){	HPEN hPen, hOldPen;	HBRUSH hBrush, hOldBrush;	hPen = CreatePen(PS_SOLID,1,fg);	hBrush = CreateSolidBrush(bk);	hOldPen = (HPEN)SelectObject(hdcTarget,hPen);	hOldBrush = (HBRUSH)SelectObject(hdcTarget,hBrush);	Rectangle(hdcTarget,		rcTarget->left,rcTarget->top,rcTarget->right,rcTarget->bottom);	SelectObject(hdcTarget,hOldBrush);	SelectObject(hdcTarget,hOldPen);	DeleteObject(hPen);	DeleteObject(hBrush);}void ShowText(HDC hdcTarget,RECT * rcTextRect,char * text,int text_length,					COLORREF fg, COLORREF bk){	HFONT hfnt, hOldFont;	LOGFONT lf;	hfnt = (HFONT)GetStockObject(SYSTEM_FONT);	GetObject(hfnt, sizeof(LOGFONT), &lf);	lf.lfWeight = FW_THIN;	lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;	lf.lfPitchAndFamily = VARIABLE_PITCH|FF_SWISS;	lf.lfHeight = (rcTextRect->bottom - rcTextRect->top);	lf.lfWidth = 0;	SetTextColor(hdcTarget,fg);	SetBkColor(hdcTarget,bk);	hfnt = CreateFontIndirect(&lf);	hOldFont = (HFONT)SelectObject(hdcTarget,hfnt);	DrawText(hdcTarget,text,text_length,rcTextRect,				DT_SINGLELINE|DT_VCENTER|DT_CENTER);	SelectObject(hdcTarget,hOldFont);	DeleteObject(hfnt);}void	DisplayStar(long universe_serial_number,						int map_x,int map_y,int number_of_planets,						HDC hdcTarget,RECT * rcStarRect){	// Choose color	srand((unsigned)universe_serial_number + (unsigned)(UNIVERSE_SIDE * map_y) + (unsigned)map_x);	int nColor = rand() % 3;	COLORREF crStar;	int size;	switch (nColor)	{		case 0 : crStar = PALETTERGB(255,0,0); break;		case 1 : crStar = PALETTERGB(255,255,0); break;		case 2 : crStar = PALETTERGB(255,255,255); break;	}   number_of_planets = number_of_planets + 2;	// The size depends on the number of planets	size = (((100 * number_of_planets) / 14) * (rcStarRect->right - rcStarRect->left)) / 100;	HPEN hPen, hOldPen;	HBRUSH hBrush, hOldBrush;	hPen = CreatePen(PS_SOLID,1,crStar);	hBrush = CreateSolidBrush(crStar);	hOldPen = (HPEN)SelectObject(hdcTarget,hPen);	hOldBrush = (HBRUSH)SelectObject(hdcTarget,hBrush);	Ellipse(hdcTarget,	rcStarRect->left + (((rcStarRect->right - rcStarRect->left) / 2) - (size / 2)),	rcStarRect->top + (((rcStarRect->bottom - rcStarRect->top) / 2) - (size / 2)),	rcStarRect->left + (((rcStarRect->right - rcStarRect->left) / 2) + (size / 2)),	rcStarRect->top + (((rcStarRect->bottom - rcStarRect->top) / 2) + (size / 2)));	SelectObject(hdcTarget,hOldPen);	SelectObject(hdcTarget,hOldBrush);	DeleteObject(hPen);	DeleteObject(hBrush);}void	DisplayPlanet(long universe_serial_number,						int map_x,int map_y,int planet_number,						HDC hdcTarget,RECT * rcStarRect){	// Choose color	srand((unsigned)universe_serial_number + (unsigned)(UNIVERSE_SIDE * map_y) + (unsigned)map_x + (unsigned)planet_number);	int nColor = rand() % 4;	COLORREF crPlanet;	int size;	switch (nColor)	{		case 0 : crPlanet = PALETTERGB(0,0,255); break;		case 1 : crPlanet = PALETTERGB(0,255,0); break;		case 2 : crPlanet = PALETTERGB(128,128,128); break;		case 3 : crPlanet = PALETTERGB(0,128,128); break;	}	size = (rand() % 80) + 20;	size = (int)((size / 100.0) * (rcStarRect->bottom - rcStarRect->top));	HPEN hPen, hOldPen;	HBRUSH hBrush, hOldBrush;	hPen = CreatePen(PS_SOLID,1,crPlanet);	hBrush = CreateSolidBrush(crPlanet);	hOldPen = (HPEN)SelectObject(hdcTarget,hPen);	hOldBrush = (HBRUSH)SelectObject(hdcTarget,hBrush);	Ellipse(hdcTarget,	rcStarRect->left + (((rcStarRect->right - rcStarRect->left) / 2) - (size / 2)),	rcStarRect->top + (((rcStarRect->bottom - rcStarRect->top) / 2) - (size / 2)),	rcStarRect->left + (((rcStarRect->right - rcStarRect->left) / 2) + (size / 2)),	rcStarRect->top + (((rcStarRect->bottom - rcStarRect->top) / 2) + (size / 2)));	SelectObject(hdcTarget,hOldPen);	SelectObject(hdcTarget,hOldBrush);	DeleteObject(hPen);	DeleteObject(hBrush);}void	DisplayPlanets(long universe_serial_number,						int map_x,int map_y,int number_of_planets,						HDC hdcTarget,RECT * rcStarRect){	int nPlanet;	RECT rcPlanet;	rcPlanet.top = rcStarRect->top;	rcPlanet.left = rcStarRect->left;	rcPlanet.bottom = rcStarRect->bottom;	rcPlanet.right = rcStarRect->right;	for (nPlanet = 0; nPlanet < number_of_planets; nPlanet++)	{		rcPlanet.top = rcStarRect->top + ((rcStarRect->bottom - rcStarRect->top) * nPlanet);		rcPlanet.bottom = rcPlanet.top + (rcStarRect->bottom - rcStarRect->top);		rcPlanet.left = (rcStarRect->right - rcStarRect->left) / 2;		rcPlanet.left = rcPlanet.left - ((rcPlanet.bottom - rcPlanet.top) / 2);		rcPlanet.left = rcPlanet.left + rcStarRect->left;		rcPlanet.right = rcPlanet.left + (rcPlanet.bottom - rcPlanet.top);		DisplayPlanet(universe_serial_number,map_x,map_y,nPlanet,hdcTarget,&rcPlanet);	}}void	DisplaySolarSystem(long universe_serial_number,RECT * rcMapWindow,												int mouse_x, int mouse_y,											  RECT * rcSolarSystemWindow,											  HDC hdcTarget){	int nSquareXSide = (rcMapWindow->right  - rcMapWindow->left) / UNIVERSE_SIDE;	int nSquareYSide = (rcMapWindow->bottom - rcMapWindow->top)  / UNIVERSE_SIDE;	char name[10];	char coords[20];	int coords_length;	char number_of_planets[12];	int map_x, map_y, name_length;	RECT rcNameRect, rcSolarSystemRect, rcStarRect;	map_x = mouse_x / nSquareXSide;	map_y = mouse_y / nSquareYSide;	// Name, co-ordinates	BlankRect(hdcTarget,rcSolarSystemWindow,RGB(0,0,0),RGB(0,0,0));	if (FeatureAt(universe_serial_number,map_x,map_y) == 1)	{		name_length = GenerateName(universe_serial_number,map_x,map_y,name);		rcNameRect.left = rcSolarSystemWindow->left + 1;		rcNameRect.right = rcSolarSystemWindow->right - 1;		rcNameRect.top = rcSolarSystemWindow->top;		rcNameRect.bottom =				  ((rcSolarSystemWindow->bottom - rcSolarSystemWindow->top)) / 16;		rcNameRect.bottom = rcNameRect.bottom + rcNameRect.top;		ShowText(hdcTarget,&rcNameRect,name,name_length,RGB(0,0,0),RGB(255,255,255));		rcNameRect.top = rcNameRect.bottom;		rcNameRect.bottom = rcNameRect.top +				  ((rcSolarSystemWindow->bottom - rcSolarSystemWindow->top)) / 24;		coords_length = wsprintf(coords,"%d,%d",map_x,map_y);		ShowText(hdcTarget,&rcNameRect,coords,coords_length,RGB(0,0,0),RGB(255,255,255));		GetNumberOfPlanets(universe_serial_number,map_x,map_y,number_of_planets);		rcSolarSystemRect.top = rcNameRect.bottom;		rcSolarSystemRect.left = rcNameRect.left;		rcSolarSystemRect.right = rcNameRect.right;		rcSolarSystemRect.bottom = rcSolarSystemWindow->bottom;		rcStarRect.top = rcSolarSystemRect.top;		rcStarRect.bottom = rcSolarSystemRect.top + ((rcSolarSystemRect.bottom - rcSolarSystemRect.top) / 5);		rcStarRect.left = (rcSolarSystemRect.right - rcSolarSystemRect.left) / 2;		rcStarRect.left = rcStarRect.left - ((rcStarRect.bottom - rcStarRect.top) / 2);		rcStarRect.left = rcStarRect.left + rcSolarSystemRect.left;		rcStarRect.right = rcStarRect.left + (rcStarRect.bottom - rcStarRect.top);		DisplayStar(universe_serial_number,map_x,map_y,atoi(number_of_planets+9),hdcTarget,&rcStarRect);		rcSolarSystemRect.top = rcStarRect.bottom;		rcSolarSystemRect.bottom = (rcSolarSystemRect.bottom - rcSolarSystemRect.top) / 12;		rcSolarSystemRect.bottom = rcSolarSystemRect.bottom + rcSolarSystemRect.top;		DisplayPlanets(universe_serial_number,map_x,map_y,atoi(number_of_planets+9),hdcTarget,&rcSolarSystemRect);	}}

⌨️ 快捷键说明

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