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

📄 battle.cpp

📁 RPG游戏的剧情部分源码。是Visual C++角色扮演游戏程序设计的第七章的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 执行战斗
//
//		Copyright (c) 2000-2001 Chihiro.SAKAMOTO (HyperWorks)
//
#include "stdafx.h"
#include <stdlib.h>
#include "MainWin.h"
#include "File.h"
#include "Misc.h"
#include "Battle.h"
#include "Lexer.h"
#include "less.h"

//
// 构造函数
//
CBattleAction::CBattleAction(CMainWin *win, CAction *oldAction):
	CAction(win, oldAction), _map_data(0), map_data(0),
	ViewImage(win->GetViewImage()),
	MixedImage(win->GetMixedImage()),
	BackLayer(win->GetBackLayer())
{
	status = STATUS_NONE;
	turn = PLAYER_TURN;

	// 角色信息的显示
	for (int i=0; i<MAX_CHARACTER; i++) {
		StatusCharacter[i] = 0;
	}

	// 事前字型的产生
	hFont = CreateFont(-16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
		GB2312_CHARSET, OUT_DEFAULT_PRECIS, CLIP_CHARACTER_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "冼极");
}

//
// 析构函数
//
CBattleAction::~CBattleAction()
{
	DeleteObject(hFont);

	delete _map_data;
	delete map_data;
}

//
// 暂停
//
void CBattleAction::Pause()
{
}

//
// 暂停解除
//
void CBattleAction::Resume()
{
}

//
// 按下鼠标左键时执行的处理
//
void CBattleAction::LButtonDown(UINT modKeys, CPoint point)
{
	// 只有轮到的游戏角色才有的鼠标按钮反应
	if (turn == PLAYER_TURN) {
		CPoint pos = PointToIndex(point);	// 需要地图座标
		switch (status) {
		  case STATUS_NONE:
			// 选取游戏角色
			if (MapRect.PtInRect(pos) && map_data[pos.y][pos.x].type & PLAYER) {
				SelPos = pos;
				SelChar = (CCharacter *)map_data[SelPos.y][SelPos.x].sprite;
				ShowCommand(point);
			}
			break;

		  case STATUS_COMMAND:
			SelectCommand(point);
			break;

		  case STATUS_MOVE:
			// 点选时的移动范围
			if (MapRect.PtInRect(pos) && map_data[pos.y][pos.x].type & MOVEDIST) {
				MovePlayer(SelChar, pos);
				SelChar->move_done = true;
			}
			break;

		  case STATUS_ATTACK:
			// 已点选攻击目标
			if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | ENEMY)) == (ATTACKDIST | ENEMY)) {
				Attack(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
				SelChar->attack_done = true;
			}
			break;

		  case STATUS_MAGIC_ENEMY:
			// 点选时的魔法范围
			if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | ENEMY)) == (ATTACKDIST | ENEMY)) {
				Magic(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
				SelChar->attack_done = true;
			}
			break;

		  case STATUS_MAGIC_PLAYER:
			// 点选时的魔法范围
			if (MapRect.PtInRect(pos) && (map_data[pos.y][pos.x].type & (ATTACKDIST | PLAYER)) == (ATTACKDIST | PLAYER)) {
				Magic(SelChar, (CCharacter *)map_data[pos.y][pos.x].sprite, true);
				SelChar->attack_done = true;
			}
			break;

		  case STATUS_ANIME:
			break;

		  case STATUS_NEXTTURN:
			// 点选Turn End(轮完)结束
			if (TurnEndSprite.PtIn(point)) {
				status = STATUS_NONE;
				HideTurnEnd();
				ChangeTurn(ENEMY_TURN);
			}
			break;
		}
	}
}

//
// 按下鼠标右键时执行的处理
//
void CBattleAction::RButtonDown(UINT modKeys, CPoint point)
{
	// 按下右键传回的动作
	if (turn == PLAYER_TURN) {
		switch (status) {
		  case STATUS_NONE:				// 若没有选取任何东西时
			status = STATUS_NEXTTURN;	// 显示“下一轮”(NEXT TURN)
			ShowTurnEnd(point);
			break;

		  case STATUS_COMMAND:			// 若选取了指令时
			status = STATUS_NONE;		// 设定状态为“无”
			HideCommand();
			break;

		  case STATUS_MOVE:				// 移动
		  case STATUS_ATTACK:			// 攻击范围
		  case STATUS_MAGIC_ENEMY:		// 魔法范围
		  case STATUS_MAGIC_PLAYER:		// 当指定角色
			status = STATUS_NONE;		// 指定回“无”的状态
			ClearDistCursor();
			break;

		  case STATUS_NEXTTURN:			// 若是下一轮(Next turn)时
			status = STATUS_NONE;		// 指定回“无”的状态
			HideTurnEnd();
			break;
		}
	}
}

//
// 移动鼠标时的处理
//
void CBattleAction::MouseMove(UINT modKeys, CPoint point)
{
	if (turn == PLAYER_TURN) {
		switch (status) {
		  case STATUS_NONE:			// 初始状态
		  case STATUS_MOVE:			// 显示移动范围
		  case STATUS_ATTACK:		// 显示攻击范围
		  case STATUS_MAGIC_ENEMY:	// 显示魔法范围
		  case STATUS_MAGIC_PLAYER:	// 显示魔法范围
			SetCursor(PointToIndex(point));
			break;

		  case STATUS_COMMAND:		// 显示指令菜单
			HighlightCommand(point);
			break;

		  case STATUS_NEXTTURN:		// 显示下一轮指令菜单
			SelectTurnEnd(TurnEndSprite.PtIn(point)? true: false);
			break;
		}
	}
}

//
// 按下键盘时的处理
//
void CBattleAction::KeyDown(UINT key)
{
}

//
// IDLE处理
//
BOOL CBattleAction::IdleAction()
{
	if (turn == ENEMY_TURN) {
		if (status != STATUS_ANIME) {
			if (!enemy_ptr->move_done) {		// 若尚未移动,则移动
				MoveEnemy();
			}
			else if (!enemy_ptr->attack_done) {	// 若尚未攻击,则攻击
				AttackEnemy();
			}
			else {
				if (status == STATUS_BATTLE_END) {	// 结束
					return FALSE;
				}
				else if (++enemy_ptr == enemy_list.end()) {
					ChangeTurn(PLAYER_TURN);
				}
			}
		}
		return TRUE;
	}
	return FALSE;
}

//
// 计时器的处理
//
bool CBattleAction::TimedOut(int timerId)
{
	switch (timerId) {
	  case TIMER_MOVE_ID:	// 移动动画
		{
			ASSERT(status == STATUS_ANIME);
			MoveAnime &ar = anime.front();
			CCharacter *character = ar.character;
			RemoveSprite(character);
			character->MoveAnime(ar.action, ar.count);
			AddSprite(character);
			if (ar.count++ == 3) {	// 4个模式后前进到下一格
				anime.pop_front();
				// 若不再登录,则结束动画
				if (anime.size() == 0) {
					CPoint pos = character->GetMapPoint();
					map_data[pos.y][pos.x].type |= (turn == PLAYER_TURN)? PLAYER: ENEMY;
					map_data[pos.y][pos.x].sprite = character;
					status = STATUS_NONE;
					return true;
				}
			}
		}
		break;

	  case TIMER_ATTACK_ID:	// 峌攻击动画
		ASSERT(status == STATUS_ANIME);

		if (AttackAnimeCount < CCharacter::ATTACK_STEP) {
			AttackFrom->AttackAnime(AttackAnimeCount++);
			RedrawSprite(AttackFrom);
		}
		else if (AttackAnimeCount < CCharacter::ATTACK_STEP + CCharacter::HIT_STEP) {
			AttackTo->HitAnime(AttackAnimeCount++ - CCharacter::ATTACK_STEP);
			RedrawSprite(AttackTo);
		}
		else {
			AttackFrom->NormalStatus();
			AttackTo->NormalStatus();
			RedrawSprite(AttackFrom);
			RedrawSprite(AttackTo);

			AttackPhase2();
			return true;
		}
		break;

	  case TIMER_NUMBER_ID:	// 破坏力动画
		ASSERT(status == STATUS_ANIME);
		if (AttackAnimeCount < 4) {
			for (int i=0; i<NumberView; i++) {
				Number[i].SetDrawPos(Number[i].GetDrawPos().x, Number[i].GetDrawPos().y - 1);
				CRect	rect;
				Number[i].GetRect(&rect);
				rect.bottom++;
				UpdateRect(rect);
			}
		}
		else if (AttackAnimeCount < 8) {
			for (int i=0; i<NumberView; i++) {
				Number[i].SetDrawPos(Number[i].GetDrawPos().x, Number[i].GetDrawPos().y + 1);
				CRect	rect;
				Number[i].GetRect(&rect);
				rect.top--;
				UpdateRect(rect);
			}
		}
		else {
			int n = NumberView;
			NumberView = 0;
			for (int i=0; i<n; i++) {
				RedrawSprite(Number + i);
			}
			AttackPhase3();
			return true;
		}
		AttackAnimeCount++;
		break;

	  case TIMER_MAGIC_ID:	// 魔法动画
		ASSERT(status == STATUS_ANIME);
		switch (magic_param.id) {
		  case MAGIC_HEAL:			// 恢复
			return MagicHeal();

		  case MAGIC_FIREBALL:		// Fire ball
			return MagicFireBall();
		}
	}
	return false;
}

//
// 擦入(Wipe)结束时的处理
//
void CBattleAction::WipeDone()
{
	if (status == STATUS_WAIT_START)	// 开始Wipe等待
		status = STATUS_NONE;
}

//
// Wave播放结束时的处理
//
void CBattleAction::WaveDone()
{
}

//
// 结束执行
//
void CBattleAction::Abort()
{
}

//
// 输出错误事件
//
void __cdecl CBattleAction::Error(TextReader &reader, const char *fmt, ...)
{
	va_list	args;

	char	str[256];
	int len = sprintf(str, "%s:%d ", reader.GetFileName(), reader.GetLineNo());
	va_start(args, fmt);
	_vsnprintf(str + len, sizeof(str) - len, fmt, args);
	va_end(args);

	Parent->MessageBox(str);
}

// player
bool CBattleAction::PlayerCmd(TextReader &reader, Lexer &lexer)
{
	int number;
	bool b = lexer.GetValue(&number);
	const char *name = lexer.GetString();
	const char *file = lexer.GetString();

	if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
		Error(reader, "文法错误");
		return false;
	}
	CChip chip(name, file);
	if (chip.image == 0) {
		Error(reader, "无法读取CG资料");
		return false;
	}
	chip_list.insert(pair<int, CChip>(PlayerNumber(number - 1), chip));

	return true;
}

// enemy
bool CBattleAction::EnemyCmd(TextReader &reader, Lexer &lexer)
{
	int number;
	bool b = lexer.GetValue(&number);
	const char *name = lexer.GetString();
	const char *file = lexer.GetString();

	if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
		Error(reader, "文法错误");
		return false;
	}
	CChip chip(name, file);
	if (chip.image == 0) {
		Error(reader, "无法读取CG资料");
		return false;
	}
	chip_list.insert(pair<int, CChip>(EnemyNumber(number - 1), chip));

	return true;
}

// object
bool CBattleAction::ObjectCmd(TextReader &reader, Lexer &lexer)
{
	int number;
	bool b = lexer.GetValue(&number);
	const char *name = lexer.GetString();
	const char *file = lexer.GetString();

	if (name == 0 || file == 0 || !b || lexer.GetString() != 0) {
		Error(reader, "文法错误");
		return false;
	}
	CChip chip(name, file);
	if (chip.image == 0) {
		Error(reader, "无法读取CG资料");
		return false;
	}
	chip_list.insert(pair<int, CChip>(ObjectNumber(number - 1), chip));

	return true;
}

// mapsize
bool CBattleAction::MapSizeCmd(TextReader &reader, Lexer &lexer)
{
	int width, height;
	if (!lexer.GetValue(&width)
	 || !lexer.GetValue(&height)
	 || lexer.GetString() != 0) {
		Error(reader, "文法错误");
		return false;
	}
	MapSize.cx = width;
	MapSize.cy = height;

	MapRect.SetRect(0, 0, width, height);

	// 保留map_data的空间
	_map_data = new MapData[width * height];
	map_data = new MapData *[height];

	for (int i=0; i<height; i++) {
		map_data[i] = _map_data + i * width;
	}

	return true;
}

// mapimage
bool CBattleAction::MapImageCmd(TextReader &reader, Lexer &lexer)
{
	const char *name = lexer.GetString();

	if (name == 0 || lexer.GetString() != 0) {
		Error(reader, "文法错误");
		return false;
	}
	if (!MapImage.LoadImage(name)) {

⌨️ 快捷键说明

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