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

📄 mainwin.cpp

📁 用MFC写的RPG游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		Mixing(r, MenuItem(index));
		CopyAndRepaint(r);
	}
}

//
// 显示事件范围
//
void CMainWin::ShowMessageWindow()
{
	TextDisplay = TRUE;

	TextShow = TRUE;
	Invalidate(TextRect);
	Update();
}

//
// 隐藏事件范围
//
void CMainWin::HideMessageWindow(bool update)
{
	TextDisplay = FALSE;

	if (TextShow) {
		TextShow = FALSE;
		Invalidate(TextRect);
		if (update)
			Update();
	}
}

//
// 选择/不选择显示事件范围
//
void CMainWin::FlipMessageWindow()
{
	if (TextDisplay) {
		TextShow = TextShow? FALSE: TRUE;
		Invalidate(TextRect);
		Update();
	}
}

//
// 隐藏菜单
//
void CMainWin::HideMenuWindow(bool update)
{
	if (MenuShow) {
		MenuShow = FALSE;
		Invalidate(MenuRect);
		if (update)
			Update();
	}
}

//
// 画面的全部设定成不显示
//
// pix 是填满画面的颜色
//
void CMainWin::HideAllLayer(COLORREF pix)
{
	BgColor = pix;
	BackShow = FALSE;
	OverlapShow = FALSE;
}

//
// 装配显示的内容
//
void CMainWin::Mixing(const CRect &rect, unsigned flags)
{
	// 背景
	if (BackShow)
		MixedImage.Copy(&BackLayer, rect);		// 有背景的话就复制
	else
		MixedImage.FillRect(rect, BgColor);		// 没有背景的话就涂满

	// 重叠
	if (OverlapShow)							// 有重叠的话就合成
		MixedImage.MixImage(&OverlapLayer, rect);

	// 储存与载入菜单
	if (SaveShow) {
		if (flags & SaveTitle) {
			MixedImage.DrawFrameRect(SAVE_X, SAVE_Y, SAVE_TITLE_WIDTH, SAVE_ITEM_HEIGHT);
			MixedImage.DrawText(hFont, SAVE_TEXT_OFFSET_X, SAVE_TEXT_OFFSET_Y,
				IsSaveMenu? "储存": "载入");
		}
		for (int i=0; i<PARAMS_MAX_SAVE; i++) {
			if (flags & SaveItem(i)) {
				int		y = (i + 1) * SAVE_ITEM_INTERVAL;
				MixedImage.DrawFrameRect(SAVE_X, SAVE_Y + y, SAVE_W, SAVE_ITEM_HEIGHT,
					DataTitle[i].color);
				MixedImage.DrawText(hFont, SAVE_TEXT_OFFSET_X, SAVE_TEXT_OFFSET_Y + y,
					DataTitle[i].title, DataTitle[i].color);
			}
		}
	}
	else {
		// 事件范围
		if (TextShow) {
			if (flags & TextMessage) {
				MixedImage.DrawFrameRect(TextRect);
				for (int i=0; i<MessageLine; i++) {
					MixedImage.DrawText(hFont, MsgX(0), MsgY(i), MsgBuffer[i]);
				}
			}
			else {
				MixedImage.FillHalfToneRect(TextRect & rect);
			}
			// 等待按键的符号(使用▼、挪用DrawText)
			if (WaitMarkShowing && flags & TextWaitMark)
				MixedImage.DrawText(hFont, MsgX(WAITMARK_X), MsgY(WAITMARK_Y), "▼");
		}
		// 菜单
		if (MenuShow) {
			if (flags & MenuFrame)
				MixedImage.DrawFrameRect(MenuRect);
			else
				MixedImage.FillHalfToneRect(MenuRect & rect);

			for (int i=0; i<MenuCount; i++) {
				if (flags & MenuItem(i)) {
					MixedImage.DrawText(hFont,
						MenuRect.left + MENU_FRAME_WIDTH,
						MenuRect.top + MENU_FRAME_HEIGHT + MENU_ITEM_HEIGHT * i,
						MenuBuffer[i].text, MenuBuffer[i].color);
				}
			}
		}
	}
}

//
// 若画面有变化时则重新绘制
//
BOOL CMainWin::Update(bool repaint)
{
	if (!InvalidRect.IsRectEmpty()) {			// 有无效区域
		Mixing(InvalidRect);					// 合成
		if (repaint)
			CopyAndRepaint(InvalidRect);		// 重新绘制
		InvalidRect.SetRectEmpty();				// 将无效区域设为“无”
		return TRUE;							// 已Update
	}
	return FALSE;								// 什么都不做
}

//
// 读取背景CG
//
BOOL CMainWin::LoadImageBack(const char *name)
{
	BackShow = TRUE;
	Invalidate();
	return BackLayer.LoadImage(name);
}

//
// 读取重叠CG
//
BOOL CMainWin::LoadImageOverlap(const char *name)
{
	OverlapShow = TRUE;
	Invalidate();
	return OverlapLayer.LoadImage(name);
}

//
// 消去背景CG
//
BOOL CMainWin::ClearBack()
{
	BackShow = FALSE;
	Invalidate();
	return TRUE;
}

//
// 消去重叠CG
//
// 实际上只有变更显示状况
//
BOOL CMainWin::ClearOverlap()
{
	OverlapShow = FALSE;
	Invalidate();
	return TRUE;
}

//
// 判定是否为禁用的文字(字符)
//
// 这里处理的是行尾最好禁用的字符部分
// 这里和系统中使用的字符有关
//
BOOL CMainWin::Kinsoku(const char *p)
{
	switch (UC(p[0])) {
	  case 0x81:
		switch (UC(p[1])) {
		  case 0x41:
		  case 0x42:
		  case 0x49:
		  case 0x48:
		  case 0x5B:
		  case 0x6A:
		  case 0x76:
		  case 0x78:
		  case 0x99:
		  case 0xf4:
			return TRUE;
		}
		break;

	  case 0x82:
		switch (UC(p[1])) {
		  case 0x9f:
		  case 0xa1:
		  case 0xa3:
		  case 0xa5:
		  case 0xa7:
		  case 0xe1:
		  case 0xe3:
		  case 0xe5:
		  case 0xc1:
			return TRUE;
		}
		break;

	  case 0x83:
		switch (UC(p[1])) {
		  case 0x40:
		  case 0x42:
		  case 0x44:
		  case 0x46:
		  case 0x48:
		  case 0x83:
		  case 0x85:
		  case 0x87:
		  case 0x62:
			return TRUE;
		}
	}
	return FALSE;
}

#define	STR_LIMIT	(MessageWidth - 2)
#define	STR_WIDTH	(STR_LIMIT - 2)

//
// 清除内文缓冲装置(Text Buffer)
//
void CMainWin::ClearMessage()
{
	HideMessageWindow();

	CurX = CurY = 0;

	for (int i=0; i<MessageLine; i++)
		MsgBuffer[i][0] = 0;
}

//
// 在内文缓冲装置中格式化字符串后再复制
//
// 因为正在处理禁用条例、限定日文
//
int CMainWin::FormatMessage(const char *msg)
{
	CurX = CurY = 0;

	for (int i=0; i<MessageLine; i++)
		MsgBuffer[i][0] = 0;

	while (*msg && CurY < MessageLine) {
		if (*msg == '\n') {
			msg++;
			MsgBuffer[CurY][CurX] = 0;
			CurX = 0;
			CurY++;
		}
		else if (_ismbblead(*msg)) {
			if (CurX >= STR_LIMIT || (CurX >= STR_WIDTH && Kinsoku(msg) == 0)) {
				MsgBuffer[CurY][CurX] = 0;
				CurX = 0;
				CurY++;
			}
			MsgBuffer[CurY][CurX++] = *msg++;
			MsgBuffer[CurY][CurX++] = *msg++;
		}
		else {
			if (CurX >= STR_WIDTH) {
				MsgBuffer[CurY][CurX] = 0;
				CurX = 0;
				CurY++;
			}
			MsgBuffer[CurY][CurX++] = *msg++;
		}
	}
	if (CurX > 0 && CurY < MessageLine) {
		MsgBuffer[CurY][CurX] = 0;
		CurY++;
	}
	return CurY;
}

//
// 设置菜单项目
//
void CMainWin::SetMenuItem(const char *str, int anser)
{
	int		n = strlen(str);
	memcpy(MenuBuffer[MenuCount].text, str, n + 1);
	MenuBuffer[MenuCount].anser = anser;
	MenuBuffer[MenuCount].length = n;
	MenuBuffer[MenuCount].color = WhitePixel;
	MenuCount++;
}

//
// 载入游戏
//
void CMainWin::LoadGame(int no)
{
	CParams param;
	if (!param.Load(no)) {
		MessageBox("无法载入。");
		return;
	}

	CScriptAction *action = new CScriptAction(this, 0, CScriptAction::MODE_SCENARIO);
	if (action->Load(param.last_script)) {
		HideMessageWindow(false);
		HideMenuWindow(false);
		if (SaveShow) {
			SaveShow = FALSE;
			Invalidate(SaveRect);
		}
		Update();
		action->Setup(param);
		Param = param;

		// 删除动作(Action)
		DeleteAllAction();
		Action = action;
		PostMessage(WM_KICKIDLE);
	}
}

//
// 储存游戏
//
void CMainWin::SaveGame(int no, int flags)
{
	if (!Param.Save(no)) {
		MessageBox("无法储存。");
		return;
	}
	CancelLoadSaveMenu(flags);
}

//
// 载入·显示储存菜单
//
void CMainWin::ShowLoadSaveMenu(BOOL isSave)
{
	IsSaveMenu = isSave;
	SaveShow = TRUE;

	for (int i=0; i<PARAMS_MAX_SAVE; i++) {
		CParams	param;

		if (param.Load(i)) {
			DataTitle[i].activate = true;
			sprintf(DataTitle[i].title, "%2d: %2d/%2d %2d:%02d", i + 1,
				param.save_month, param.save_date,
				param.save_hour, param.save_minute);
		}
		else {
			DataTitle[i].activate = IsSaveMenu? true: false;
			sprintf(DataTitle[i].title, "%2d: -- no data --", i + 1);
		}
		DataTitle[i].color = DataTitle[i].activate? WhitePixel: GrayPixel;
	}

	Invalidate(SaveRect);
	if (TextShow)
		Invalidate(TextRect);
	if (MenuShow)
		Invalidate(MenuRect);

	Update();
}

//
// 载入·消去储存菜单
//
void CMainWin::HideLoadSaveMenu()
{
	SaveShow = FALSE;

	Invalidate(SaveRect);
	if (TextShow)
		Invalidate(TextRect);
	if (MenuShow)
		Invalidate(MenuRect);

	Update();
}

//
// 载入·回复储存画面
//
void CMainWin::CancelLoadSaveMenu(int flags)
{
	HideLoadSaveMenu();

	CAction *old = Action->GetOldAction();
	delete Action;
	Action = old;
	Action->Resume();

	if (flags & IS_TIMEDOUT)
		Action->TimedOut(TimerSleep);

	PostMessage(WM_KICKIDLE);
}

//
// 切换载入与储存项目的选取/非选取
//
void CMainWin::SelectLoadSaveMenu(int index, bool select)
{
	if (index >= 0) {
		DataTitle[index].color = select? RedPixel: WhitePixel;
		int		y = index * SAVE_ITEM_INTERVAL + SAVE_ITEM_INTERVAL;
		CRect	rect(SAVE_X, SAVE_Y + y, SAVE_X + SAVE_W, SAVE_Y + y + SAVE_ITEM_HEIGHT);
		Mixing(rect, SaveItem(index));
		CopyAndRepaint(rect);
	}
}

//
// 取得载入与储存项目
//
// 等间距并列,其位置可由计算得到
//
int CMainWin::GetLoadSaveSelect(CPoint point)
{
	if (point.x >= SAVE_X && point.x < SAVE_X + SAVE_W
	 && point.y >= SAVE_Y + SAVE_ITEM_INTERVAL) {
		int		index = point.y - SAVE_Y - SAVE_ITEM_INTERVAL;
		if (index % SAVE_ITEM_INTERVAL < SAVE_ITEM_HEIGHT) {
			index /= SAVE_ITEM_INTERVAL;
			if (index < PARAMS_MAX_SAVE && DataTitle[index].activate)
				return index;
		}
	}
	return -1;
}

//
// 取得下一项载入·储存项目
//
int CMainWin::NextLoadSaveSelect(int index)
{
	for (int i=1; i<=PARAMS_MAX_SAVE; i++) {
		int	next = (index + i) % PARAMS_MAX_SAVE;
		if (DataTitle[next].activate)
			return next;
	}
	return -1;
}

//
// 取得前一项载入·储存项目
//
int CMainWin::PrevLoadSaveSelect(int index)
{
	for (int i=PARAMS_MAX_SAVE - 1; i>0; i--) {
		int	prev = (index + i) % PARAMS_MAX_SAVE;
		if (DataTitle[prev].activate)
			return prev;
	}
	return -1;
}

//
// 音乐播放
//
BOOL CMainWin::StartMusic(int no)
{
	if (MusicNo != no) {
		MusicNo = no;
		if (music) {
			music->Stop();
			return music->Play(no);
		}
	}
	return TRUE;
}

//
// 音乐重新播放
//
BOOL CMainWin::RestartMusic()
{
	if (music)
		return music->Replay();
	return TRUE;
}

//
// 音乐停止
//
BOOL CMainWin::StopMusic()
{
	MusicNo = 0;
	if (music)
		return music->Stop();
	return TRUE;
}

//
// 播放Wave
//
BOOL CMainWin::StartWave(const char *name)
{
	char	path[_MAX_PATH];
	sprintf(path, WAVEPATH "%s.wav", name);

	return wave.Play(path);
}

//
// 战斗
//
BOOL CMainWin::Battle(const char *name)
{
	CBattleAction *action = new CBattleAction(this, Action);
	if (!action->Load(name)) {
		delete action;
		return false;
	}
	Action = action;
	PostMessage(WM_KICKIDLE);	// 为存安全,发送空事件
	return true;
}

⌨️ 快捷键说明

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