📄 main.cpp
字号:
//********************************************
// 主模块 相关函数
// 创建于2000年4月日10日
//********************************************
#include <windows.h>
#include <stdio.h>
#include "gamelib\goldpoint.h"
#include "interface\interface.h"
#include "menu\menu_inc.h"
#include "mapedit\mapedit.h"
#include "mapedit\dialog.h"
#include "main.h"
#include "cursor.h"
#include "map.h"
#include "findpath.h"
#include "role.h"
#include "npc.h"
#include "talk.h"
#include "message.h"
#include "script.h"
#include "events.h"
#include "fight\fight.h"
#include "resource.h"
//////////////////////////////////
//通用变量
//////////////////////////////////
LPDIRECTDRAWSURFACE lpDDSSour=NULL, lpDDSTemp=NULL; //临时页面
LPDIRECTDRAWSURFACE lpDDSBackGround; // 背景页面
LPDIRECTDRAWSURFACE lpDDSTools; // 编辑器专用小图标
LPDIRECTDRAWSURFACE *lpDDSMap; // 地图地面页面
LPDIRECTDRAWSURFACE lpDDSMask; // 光照图
enum ePLAYSTATE g_ePlayState=PS_MAIN; //游戏当前状态
enum ePLAYSTATE g_ePlayState_Old=PS_MAIN;
enum eDISPLAYSTATE g_eDisplayState=DS_NORMAL; //当前显示模式
POINT point; //鼠标坐标
int cx,cy; //鼠标格子
int StartX=0,StartY=0; //主区起始坐标
int EndX=639,EndY=479; //主区结束坐标
int MainWidth=640,MainHeight=480; //主区大小
int ShowCellW=20, ShowCellH=15; //显示区域格子数
int RoleNum; //主角数量(1-4)
CIniSet GameIni; //游戏配置文件
CScript Script; //游戏脚本机
CMessage Message; //游戏消息处理
CEvents Events; //特殊事件
CTitle Title; //封面
CMenu Menu; //菜单
CMap map; //当前地图
CGpFont font(true); //字体对象
CGpFont DebugFont(true); //调试字体对象
CRole role[4]; //角色
CTalk talk; //对话
CMsgWindow GameMessage; //游戏消息框
CSound Sound; //音效
CMusic Music; //背景音乐
CProess Proess; //进度条
unsigned mouse, key, joystick; //鼠标、键盘和手柄的缓冲区数据接受
bool bControl=true; //是否可控制
CFight Fight; //战斗
char CurrentPath[MAX_PATH]; //当前工作目录
int CurrentNpc=-1; //当前鼠标指向的NPC编号(-1=NULL)
int NowTick=0, OldTick=0, DelayTick=40;
extern char strHelp[]; //帮助
extern char *CGetDlgMessage; //提示文字
extern char *CGetStringDlgBuffer; //字符串
extern HMENU pmmParent;
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//游戏初始化
BOOL InitGame()
{
char *strTemp=NULL;
//创建后台临时表面
CreateBitmap(lpDDSBackGround, ScreenWidth, ScreenHeight);
CreateBitmap(lpDDSSour, ScreenWidth, ScreenHeight);
CreateBitmap(lpDDSTemp, ScreenWidth, ScreenHeight);
Events.GoldPointLogo("pic\\interface\\logo.bmp", RGB(255,255,255),
190, 170, 272, 112, 7);
//获取当前路径
GetCurrentDirectory(256, CurrentPath);
//打开游戏主配置文件
GameIni.Open("ini\\heroland.ini");
//透明色
int r=GameIni.ReadInt("ColorKey","Red");
int g=GameIni.ReadInt("ColorKey","Green");
int b=GameIni.ReadInt("ColorKey","Blue");
ColorKey=RGB(r,g,b);
//初始化字体
font.InitFont(16, "宋体");
//初始化字体
strTemp = GameIni.ReadText("配置文件","字体");
DebugFont.LoadFont(strTemp, "版本字体");
_FREE(strTemp);
// 进度条
Proess.LoadIni("ini\\menu\\proess.ini", "进度条");
//初始化编辑器专用图素图片
strTemp=GameIni.ReadText("编辑器","ToolPic");
CreateBitmap(lpDDSTools, 0,0, strTemp);
DDSetColorKey(lpDDSTools, ColorKey);
_FREE(strTemp);
//初始化光线图片
CreateBitmap(lpDDSMask, 0,0, "pic\\mask.bmp" );
//初始化图素图片
Max_GroundPic=GameIni.ReadInt("地图元素","Max_GroundPic");
lpDDSMap=new LPDIRECTDRAWSURFACE[Max_GroundPic];
for(int i=0; i<Max_GroundPic; i++)
{
strTemp = GameIni.ReadText("地图元素",i);
CreateBitmap(lpDDSMap[i], 0,0, strTemp);
DDSetColorKey(lpDDSMap[i], ColorKey);
_FREE(strTemp);
}
//初始化光标
strTemp = GameIni.ReadText("配置文件","光标");
CCursor::Init(strTemp, "header");
_FREE(strTemp);
//初始化对话框
strTemp = GameIni.ReadText("配置文件","对话框");
talk.Init(strTemp, "普通对话");
_FREE(strTemp);
//初始化消息框
strTemp = GameIni.ReadText("配置文件","消息框");
GameMessage.LoadMsgWindowIni(strTemp, "游戏消息");
_FREE(strTemp);
//初始化菜单系统
strTemp = GameIni.ReadText("配置文件","菜单系统");
Menu.LoadMenuIni(strTemp, "菜单系统");
_FREE(strTemp);
strTemp = GameIni.ReadText("配置文件","物品列表");
Menu.Goods.LoadGoodsIni(strTemp);
_FREE(strTemp);
strTemp = GameIni.ReadText("配置文件","魔法列表");
Menu.Magic.LoadMagicIni(strTemp);
_FREE(strTemp);
//初始化地图
map.InitMap(32,32);
strTemp = GameIni.ReadText("配置文件", "动态图块");
map.LoadAniCell(strTemp, "动态图块");
_FREE(strTemp);
talk.OpenFile("maps\\talk.txt");
//初始化脚本解释机
strTemp = GameIni.ReadText("配置文件","脚本指令");
char *index = GameIni.ReadText("配置文件","脚本变量");
Script.Init(strTemp, index);
_FREE(strTemp);
_FREE(index);
//初始化战斗
Fight.Init();
//初始化敌人列表
CFight::LoadEnemyList("ini\\fight\\enemy.ini", "敌人列表");
//为新游戏初试数据
NewGame();
//读入模式
g_ePlayState = g_ePlayState_Old = (enum ePLAYSTATE)GameIni.ReadInt("Start","PlayState");
g_eDisplayState = (enum eDISPLAYSTATE)GameIni.ReadInt("Start","DisplayState");
SetTimer(hWnd, 1, 5000, NULL); //时钟
//debug方式
g_bDebug = GameIni.ReadInt("Start","Debug");
//封面
Title.LoadTitleIni( "ini\\menu\\title.ini", "封面");
Title.DoMenu(lpDDSBack);
return true;
}
//新游戏初始化数据
void NewGame()
{
//初始化角色
RoleNum = GameIni.ReadInt("角色","主角数量");
char* strTemp = GameIni.ReadText("角色","主角");
for(int i=0; i<RoleNum; i++)
{
role[i].LoadRoleIni(strTemp, GameIni.ReadText("角色", i));
}
_FREE(strTemp);
map.LoadMap("maps\\word\\null.map");
role[0].bShowed = false;
Script.RestoreValue();
}
//--------------------------------------------------
//结束游戏,释放内存
BOOL ReleaseGame()
{
int i;
CCursor::Release();
CFindPath cfp(&map);
cfp.Release();
//地面图素
for(i=0; i<Max_GroundPic; i++)
{
_RELEASE( lpDDSMap[i] );
}
_DELETE( lpDDSMap );
//释放
_RELEASE( lpDDSBackGround );
_RELEASE( lpDDSSour );
_RELEASE( lpDDSTemp );
if(pmmParent)
DestroyMenu(pmmParent);
_FREE(CGetStringDlgBuffer);
Script.Release();
return true;
}
//--------------------------------------------------
//获取输入信息
void GetInputData()
{
//获取鼠标当前的格子坐标
GetCursorPos(&point);
if( WindowMode != 0 ) //窗口
{
point.x-=RectWindow.left;
point.y-=RectWindow.top;
if( point.x < 0 )
point.x = 0;
if( point.x >= ScreenWidth )
point.x = ScreenWidth-1;
if( point.y < 0 )
point.y = 0;
if( point.y >= ScreenHeight )
point.y = ScreenHeight-1;
}
cx=map.GetCellX(point.x, point.y);
cy=map.GetCellY(point.x, point.y);
Mouse.GetMouseState(); //获取鼠标立即信息
mouse=Mouse.GetMouseData(); //获取鼠标缓冲信息
Key.GetKeyData(); //获取键盘缓冲数据(附带即时数据)
key=Key.GetKey(); //获取键盘数据
g_Joystick.GetJoystickState(); //获取手柄立即数据
g_Joystick.GetJoystickData(); //获取手柄缓冲数据
joystick=g_Joystick.GetKey();
}
//主循环
void MainLoop()
{
//延时控速
NowTick=timeGetTime();
if( NowTick < OldTick+DelayTick )
return;
OldTick=NowTick;
//获取输入信息
GetInputData();
switch( g_ePlayState )
{
case PS_Null: //空循环
break;
case PS_MAIN: //游戏主循环
GameLoop();
break;
case PS_SCROLLMAP: //卷动地图
map.ScrollLoop();
break;
case PS_EDIT: //编辑器主循环
EditLoop();
break;
}
//取NPC的坐标
for(int i=0; i<map.m_vNpc.size(); i++)
{
map.m_vNpc[i]->State.X=_grid_x(map.m_vNpc[i]->State.x);
map.m_vNpc[i]->State.Y=_grid_y(map.m_vNpc[i]->State.y);
}
//计算当前地图左上角坐标
map.sx=_point_x(map.SX)-map.DX;
map.sy=_point_y(map.SY)-map.DY;
//更新屏幕
if( g_ePlayState == g_ePlayState_Old )
{
switch( g_ePlayState )
{
case PS_Null: //空循环
break;
case PS_MAIN: //游戏主循环
if( Message.IsEmpty() && bControl )
ShowMouseCursor();
else
ShowMouseCursor(lpDDSBack,false);
UpdateScreen();
break;
case PS_SCROLLMAP: //卷动地图
ShowMouseCursor();
UpdateScreen();
break;
case PS_EDIT: //编辑器主循环
UpdateScreen();
break;
}
}
else
g_ePlayState_Old = g_ePlayState;
// 运行脚本消息
Message.Run();
}
//--------------------------------------------------
//--------------------------------------------------
//游戏主循环
void GameLoop()
{
if( Message.IsEmpty() && bControl ) //是否可以控制
{
for(int i =0;i<map.m_vNpc.size();i++)
//获取当前指向NPC
if( cx == map.m_vNpc[i]->State.X && cy == map.m_vNpc[i]->State.Y )
{
CurrentNpc=i;
}
//移动
if( (!role[0].bMoving|| map.Cell[map.Width * role[0].State.Y +
role[0].State.X].CP == BLOCK_CP ))
{
if( LEFT_ON )
{
role[0].MoveTo(role[0].State.x-CellWidth, role[0].State.y);
Fight.RandomStart(map.GetEnemyFrequency()); //踩地雷
}
else if( RIGHT_ON )
{
role[0].MoveTo(role[0].State.x+CellWidth, role[0].State.y);
Fight.RandomStart(map.GetEnemyFrequency()); //踩地雷
}
else if( UP_ON )
{
role[0].MoveTo(role[0].State.x, role[0].State.y-CellHeight);
Fight.RandomStart(map.GetEnemyFrequency()); //踩地雷
}
else if( DOWN_ON )
{
role[0].MoveTo(role[0].State.x, role[0].State.y+CellHeight);
Fight.RandomStart(map.GetEnemyFrequency()); //踩地雷
}
//触发脚本
if( A_UP )
{
// 触发NPC脚本
static int dir[4][2]={ 0,1, -1,0, 0,-1, 1,0 };
int npcx=role[0].State.X+dir[role[0].State.CurrentDir][0];
int npcy=role[0].State.Y+dir[role[0].State.CurrentDir][1];
for(int i=0; i<map.m_vNpc.size(); i++)
{
if( map.m_vNpc[i]->State.X==npcx && map.m_vNpc[i]->State.Y==npcy )
{
CurrentNpc=i;
char *NpcName=new char[32];
strcpy(NpcName, map.m_vNpc[CurrentNpc]->Name);
//调整NPC的位置,让他停下来说话
map.m_vNpc[CurrentNpc]->AdjustPosition();
BOOL bAct=map.m_vNpc[CurrentNpc]->State.bActive;
//npc停止活动
Message.PutMessage( MSG_SETNPCACTIVE, false, CurrentNpc, 1);
char *ScriptFile = (char*)malloc(sizeof(char)*64);;
strcpy(ScriptFile,map.m_vNpc[CurrentNpc]->ScriptFile);
//调整主角和NPC的方向,发生NPC脚本
Message.PutMessage( MSG_TALKDIR, CurrentNpc,0,0,ScriptFile );
//npc恢复活动
Message.PutMessage( MSG_SETNPCACTIVE, bAct, CurrentNpc, 1);
_DELETE_ARRAY(NpcName);
}
}
// 触发陷阱脚本
role[0].RunScript();
}
}
if( mouse == LB_UP )
{
if( CurrentNpc != -1 ) //和NPC对话
{
BOOL bAct=map.m_vNpc[CurrentNpc]->State.bActive;
char *NpcName=new char[32];
strcpy(NpcName, map.m_vNpc[CurrentNpc]->Name);
map.m_vNpc[CurrentNpc]->AdjustPosition();
Message.PutMessage( MSG_SETNPCACTIVE, false, CurrentNpc, 1);//npc停止活动
int x,y;
//计算坐标
if(map.m_vNpc[CurrentNpc]->Path)
{
x = map.m_vNpc[CurrentNpc]->Path[map.m_vNpc[CurrentNpc]->PathSteps-1].x;
y = map.m_vNpc[CurrentNpc]->Path[map.m_vNpc[CurrentNpc]->PathSteps-1].y;
}
else
{
x = map.m_vNpc[CurrentNpc]->State.X;
y = map.m_vNpc[CurrentNpc]->State.Y;
}
Message.PutMessage( MSG_MOVE, x,y,1); //主角移动过去
char *ScriptFile = (char*)malloc(sizeof(char)*64);;
strcpy(ScriptFile,map.m_vNpc[CurrentNpc]->ScriptFile);
//调整主角和NPC的方向,发生NPC脚本
Message.PutMessage( MSG_TALKDIR, CurrentNpc,bAct,0,ScriptFile);
_DELETE_ARRAY(NpcName);
}
else //行走
{
//踩地雷
if( Fight.RandomStart(map.GetEnemyFrequency()<<2) )
return;
//窗口
if( WindowMode!=0 )
{
if( point.x >= 0 && point.x<ScreenWidth && point.y>=0 && point.y<ScreenHeight )
role[0].MoveTo(_point_x(cx), _point_y(cy));
}
else //全屏
{
role[0].MoveTo(_point_x(cx), _point_y(cy));
}
//显示目的地光标
CCursor::GetCursor(CCursor::CS_CHANGEMAP).pPic.SetPos(map.sx+point.x, map.sy+point.y);
CCursor::GetCursor(CCursor::CS_CHANGEMAP).pPic.SetShowCount(3);
}
}
//菜单
if( B_UP || mouse == RB_UP )
{
Menu.DoMenuLoop();
}
if( mouse == RB_UP && Key.KeyDown(DIK_LCONTROL) )
{
Message.PutMessage( MSG_SETPOSITION, cx, cy);
Message.PutMessage( MSG_CENTERMAP, cx, cy );
role[0].bMoving=false;
}
}
if( key == DIK_F11 ) //test战斗
{
key = 0;
Fight.RandomStart(12000);
}
//显示地图
map.ShowMap();
}
//*****************************
//处理主窗口消息
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
static bool bMusicPlaying=false;
static bool bFMusicPlaying = false;
switch( message )
{
case WM_ACTIVATE: //应用程序是否活动
if(LOWORD(wParam)==WA_INACTIVE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -