www.pudn.com > PG20101.zip > Battle.cpp
// // 執行戰鬥 // // Copyright (c) 2000-2001 Chihiro.SAKAMOTO (HyperWorks) // #include "stdafx.h" #include#include "MainWin.h" #include "File.h" #include "Misc.h" #include "Battle.h" // // 建構式 // CBattleAction::CBattleAction(CMainWin *win, CAction *oldAction): CAction(win, oldAction), _map_data(0), map_data(0), ViewImage(win->GetViewImage()) { status = STATUS_NONE; } // // 解構式 // CBattleAction::~CBattleAction() { delete _map_data; delete map_data; } void CBattleAction::KeyDown(UINT key) { if (status == STATUS_NONE) { CCharacter &s = player_list.back(); CPoint pos = s.GetMapPoint(); switch (key) { case VK_UP: if (pos.y > MapRect.top && map_data[pos.y - 1][pos.x].type == NONE) { map_data[pos.y][pos.x].type = NONE; map_data[pos.y][pos.x].sprite = 0; anime.push_back(MoveAnime(&s, CCharacter::UP)); } break; case VK_DOWN: if (pos.y < MapRect.bottom - 1 && map_data[pos.y + 1][pos.x].type == NONE) { map_data[pos.y][pos.x].type = NONE; map_data[pos.y][pos.x].sprite = 0; anime.push_back(MoveAnime(&s, CCharacter::DOWN)); } break; case VK_LEFT: if (pos.x > MapRect.left && map_data[pos.y][pos.x - 1].type == NONE) { map_data[pos.y][pos.x].type = NONE; map_data[pos.y][pos.x].sprite = 0; anime.push_back(MoveAnime(&s, CCharacter::LEFT)); } break; case VK_RIGHT: if (pos.x < MapRect.right - 1 && map_data[pos.y][pos.x + 1].type == NONE) { map_data[pos.y][pos.x].type = NONE; map_data[pos.y][pos.x].sprite = 0; anime.push_back(MoveAnime(&s, CCharacter::RIGHT)); } break; default: return; } StartAnime(); } } // // 計時器的處理 // 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 |= PLAYER; map_data[pos.y][pos.x].sprite = character; status = STATUS_NONE; return true; } } } break; } return false; } // // 初始化 // bool CBattleAction::Init() { // 讀入CG資料 if (!Cursor.LoadImage("cursor") || !MapImage.LoadImage("map1") || !Player.LoadImage("fighter") || !Enemy.LoadImage("puyo")) return false; // 設定sprite CursorSprite.Set(&Cursor, CPoint(0, 0), CSize(MAPGRID_WIDTH, MAPGRID_HEIGHT), CMapSprite::DEPTH_CURSOR); CursorPos.x = -1; CursorPos.y = -1; SelPos.x = -1; SelPos.y = -1; SelChar = 0; status = STATUS_NONE; MapSize.cx = MapSize.cy = 10; // 地圖的尺寸大小 MapRect.SetRect(0, 0, MapSize.cx, MapSize.cy); // 確認map-data的可用空間 _map_data = new MapData[MapSize.cx * MapSize.cy]; map_data = new MapData *[MapSize.cy]; for (int i=0; i InvalidateRect(NULL); return true; } // // 產生地圖畫面 // void CBattleAction::DrawMap(CImage *image, const CRect &rect) { // 若地圖有背景,則顯示之 if (MapImage.IsOK()) { image->Copy(&MapImage, rect); } // 顯示sprite for (mapset::iterator p = sprite.begin(); p != sprite.end(); p++) { (*p)->Draw(image, rect); } } // // 顯示地圖(整個地圖) // void CBattleAction::DrawMap(CImage *image) { DrawMap(image, CRect(0, 0, WindowWidth, WindowHeight)); } // // 移動地圖游標 // void CBattleAction::SetCursor(CPoint point) { if (CursorPos != point) { // 若地圖位置有更改 ClearCursor(); // 則刪除目前顯示的游標 CursorPos = point; // 重新設定新的位置 DrawCursor(); // 顯示新的游標 } } // // 刪除地圖游標 // void CBattleAction::ClearCursor() { if (MapRect.PtInRect(CursorPos)) { RemoveSprite(&CursorSprite); } CursorPos.x = CursorPos.y = -1; } // // 顯示地圖游標 // void CBattleAction::DrawCursor() { if (MapRect.PtInRect(CursorPos)) { CursorSprite.SetMapPoint(CursorPos); AddSprite(&CursorSprite); } } // 重新繪製sprite void CBattleAction::RedrawSprite(CSprite *s) { CRect rect; s->GetRect(&rect); UpdateRect(rect); } // 新增sprite void CBattleAction::AddSprite(CSprite *s) { sprite.insert(s); RedrawSprite(s); } // 刪除sprite void CBattleAction::RemoveSprite(CSprite *s) { if (sprite.erase(s)) { RedrawSprite(s); } } // 尋找移動範圍 void CBattleAction::FindDist(int x, int y, int dist, bool first) { if (!first) { AddDistCursor(x, y, dist, 0); map_data[y][x].type |= MOVEDIST; } map_data[y][x].dist = dist; if (dist == 0) return; if (y > MapRect.top && map_data[y - 1][x].ChkMove(dist)) FindDist(x, y - 1, dist - 1, false); if (y < MapRect.bottom - 1 && map_data[y + 1][x].ChkMove(dist)) FindDist(x, y + 1, dist - 1, false); if (x > MapRect.left && map_data[y][x - 1].ChkMove(dist)) FindDist(x - 1, y, dist - 1, false); if (x < MapRect.right - 1 && map_data[y][x + 1].ChkMove(dist)) FindDist(x + 1, y, dist - 1, false); } // 顯示範圍 void CBattleAction::AddDistCursor(int x, int y, int dist, int type) { if ((map_data[y][x].type & (MOVEDIST | ATTACKDIST)) != 0) // 已登錄的部分 return; cursor_list.push_back(CMapSprite(&Cursor, x, y, CSize(MAPGRID_WIDTH, MAPGRID_HEIGHT), CMapSprite::DEPTH_AREA)); CMapSprite &s = cursor_list.back(); s.SetSrcPos(0, 32 + type * 32); AddSprite(&s); } // 刪除顯示範圍 void CBattleAction::ClearDistCursor() { while (cursor_list.size()) { CMapSprite &cr = cursor_list.front(); CPoint pos = cr.GetMapPoint(); RemoveSprite(&cr); map_data[pos.y][pos.x].type &= ~(MOVEDIST | ATTACKDIST); map_data[pos.y][pos.x].dist = 0; cursor_list.pop_front(); } } // 人物移動 void CBattleAction::MovePlayer(CCharacter *character, CPoint point) { MoveCharacter(point.x, point.y, map_data[point.y][point.x].dist, character); CPoint pos = character->GetMapPoint(); map_data[pos.y][pos.x].type = NONE; map_data[pos.y][pos.x].sprite = 0; map_data[pos.y][pos.x].dist = 0; SetCursor(CPoint(-1, -1)); ClearDistCursor(); StartAnime(); } // 登錄人物的移動動畫 void CBattleAction::MoveCharacter(int x, int y, int dist, CCharacter *character) { if (map_data[y][x].sprite != character) { dist++; if (y > MapRect.top && map_data[y - 1][x].dist == dist) { MoveCharacter(x, y - 1, dist, character); anime.push_back(MoveAnime(character, CCharacter::DOWN)); } else if (y < MapRect.bottom - 1 && map_data[y + 1][x].dist == dist) { MoveCharacter(x, y + 1, dist, character); anime.push_back(MoveAnime(character, CCharacter::UP)); } else if (x > MapRect.left && map_data[y][x - 1].dist == dist) { MoveCharacter(x - 1, y, dist, character); anime.push_back(MoveAnime(character, CCharacter::RIGHT)); } else if (x < MapRect.right - 1 && map_data[y][x + 1].dist == dist) { MoveCharacter(x + 1, y, dist, character); anime.push_back(MoveAnime(character, CCharacter::LEFT)); } } } // 執行移動動畫 void CBattleAction::StartAnime() { if (anime.size()) { Parent->SetTimer(TIMER_MOVE_ID, TIMER_MOVE_TIME); status = STATUS_ANIME; } else { status = STATUS_NONE; } }