修改论文很久,闲来头脑一热,留有后用。
总的工作流程为:
17日夜晚:查了下资料,想了下设计。
18日下午1:00-4:00 : 写了基类与玩家的部分,不过有bug。
19日上午9:00-下午14:00 : 完成。
上午9:00-10:00修改18日bug。
bug: 为 windows 下坐标系 与 自然数学坐标系的转换,导致x , y 颠倒
修改完bug后一气呵成写完并测试。
总结:
1 、 结构设计要合理, 参考书籍资料等等也有很多不太合理的地方,总之按照自己的想法来。
结构设计好,全好了。
2、 基础编码功底要好,包括:
1) C++ 语言基本功底,面向对象, 多态(这个特别重要);
2)code功底: 这是我做这个小例子的出发点,希望我们的集训队同学不要急着去上工程,老老实实搞竞赛,注重基础功底,工作时能上手就行。
3)百度API, 多参考,多试一试。
3、不足之处:
1) 地图只设置了1关
难度可以从地图、还有敌人的个数与速度下手,不过接口已经做好。
2) 人工智能AI搜索这一块不够好, 这里可以研究研究。
--------------------------------------------------------------------------------------------------------------------------------------------------------
设计类视图
基类
</pre><pre name="code" class="cpp">#pragma once
#include "stdafx.h"
#include "GMap.h"
#include <time.h>
#define PLAYSPEED 6
#define ENERMYSPEED 4
#define DISTANCE 10
#define D_OFFSET 2
#define RD 12
enum TWARDS{UP , DOWN , LEFT , RIFHT , OVER};
class GObject
{
protected:
POINT prepos ;
POINT pos ;
TWARDS tw ;
TWARDS twCommand ;
int m_row ;
int m_col ;
int speed ;
int frame ;
bool Achive() ;
bool Collision() ;
int TransPos(int ) ;
virtual void AchiveUpdate() ;
public:
GObject(void);
~GObject(void);
GObject(int row , int col) ;
static GMap *pState ;
int GetRow() ;
int GetCol() ;
void SetPositin(int row , int col) ;
void DrawBlank(HDC &hdc) ;
void virtual Draw(HDC &hdc) = 0 ;
void virtual Action() = 0 ;
};
#include "StdAfx.h"
#include "GObject.h"
GMap * GObject::pState = NULL ;
GObject::GObject(void)
{
}
GObject::~GObject(void)
{
}
GObject::GObject(int row , int col){
this->frame = 1 ;
this->pState = NULL ;
this->m_row = row ;
this->m_col = col ;
this->pos.y = row * pState->LenObstacle + pState->LenObstacle / 2 ;
this->pos.x = col * pState->LenObstacle + pState->LenObstacle / 2 ;
prepos = pos ;
}
int GObject::GetRow(){
return m_row ;
}
int GObject::GetCol(){
return m_col ;
}
int GObject::TransPos(int k){
return (k - pState->LenObstacle/2) / pState->LenObstacle ;
}
bool GObject::Achive(){
int a = (pos.x - pState->LenObstacle/2) % pState->LenObstacle ;
int b = (pos.y - pState->LenObstacle/2) % pState->LenObstacle ;
return (a == 0) && (b == 0) ;
}
void GObject::AchiveUpdate(){
if(Achive()){
m_row = TransPos(pos.y) ;
m_col = TransPos(pos.x) ;
}
}
void GObject::DrawBlank(HDC &hdc){
RECT rec ;
rec.left = prepos.x - RD ;
rec.right = prepos.x + RD ;
rec.top = prepos.y - RD ;
rec.bottom = prepos.y + RD ;
FillRect(hdc , &rec , ::CreateSolidBrush(RGB(255,255,255,))) ;
}
void GObject::SetPositin(int row , int col){
m_row = row ;
m_col = col ;
this->pos.y = m_row * pState->LenObstacle + pState->LenObstacle / 2 ;
this->pos.x = m_col * pState->LenObstacle + pState->LenObstacle / 2 ;
}
bool GObject::Collision(){
bool ishit = false ;
AchiveUpdate() ;
if(m_row < 0 || m_row > MAPLENTH -1 || m_col < 0 || m_col > MAPLENTH - 1 ){
ishit = true ;
}
else if(Achive()){
if(twCommand == LEFT){
if(m_col > 0 && pState->mapObstacle[m_row][m_col-1]) ishit = true ;
}
else if(twCommand == RIFHT){
if(m_col < MAPLENTH-1 && pState->mapObstacle[m_row][m_col+1]) ishit = true ;
}
else if(twCommand == UP){
if(m_row > 0 && pState->mapObstacle[m_row-1][m_col]) ishit = true ;
}
else if(twCommand == DOWN){
if(m_row < MAPLENTH-1 && pState->mapObstacle[m_row+1][m_col]) ishit = true ;
}
if(! ishit) tw = twCommand ;
}
prepos = pos ;
int m_max = MAPLENTH * pState->LenObstacle + pState->LenObstacle/2 ;
int m_min = pState->LenObstacle/2 ;
if(tw == LEFT){
if(m_col > 0 && pState->mapObstacle[m_row][m_col-1]) ishit = true ;
else{
pos.x -= this->speed ;
if(pos.x < m_min) pos.x = m_max ;
}
}
else if(tw == RIFHT){
if(m_col < MAPLENTH-1 && pState->mapObstacle[m_row][m_col+1]) ishit = true ;
else{
pos.x += this->speed ;
if(pos.x > m_max) pos.x = m_min ;
}
}
else if(tw == UP){
if(m_row > 0 && pState->mapObstacle[m_row-1][m_col]) ishit = true ;
else{
pos.y -= this->speed ;
if(pos.y < m_min) pos.y = m_max ;
}
}
else if(tw == DOWN){
if(m_row < MAPLENTH-1 && pState->mapObstacle[m_row+1][m_col]) ishit = true ;
else{
pos.y += this->speed ;
if(pos.y > m_max) pos.y = m_min ;
}
}
return ishit ;
}
------------------------------------------------------------------------------
敌人
#pragma once
#include "GObject.h"
#include "Player.h"
class Enermy : public GObject
{
protected:
void Catch() ;
void virtual AI(bool) = 0 ;
COLORREF color ;
public:
Enermy(void);
~Enermy(void);
static Player *player ;
void virtual Draw(HDC &hdc) ;
void virtual Action() ;
Enermy(int row , int col):GObject(row , col){
this->speed = ENERMYSPEED ;
tw = LEFT ;
twCommand = UP ;
}
};
#include "StdAfx.h"
#include "Enermy.h"
Enermy::Enermy(void)
{
}
Enermy::~Enermy(void)
{
}
Player * Enermy::player = NULL ;
void Enermy::Draw(HDC &hdc){
HPEN pen = ::CreatePen(0 , 0 , color) ;
HPEN oldpen = (HPEN)SelectObject(hdc , pen) ;
Arc(hdc , pos.x - DISTANCE , pos.y - DISTANCE , pos.x + DISTANCE , pos.y + DISTANCE ,
pos.x + DISTANCE , pos.y , pos.x - DISTANCE , pos.y) ;
int LegLen = DISTANCE / 5 ;
if(frame % 2 == 0){
MoveToEx(hdc , pos.x - DISTANCE , pos.y , NULL) ;
LineTo(hdc , pos.x - DISTANCE , pos.y + DISTANCE - LegLen) ;
MoveToEx(hdc , pos.x + DISTANCE , pos.y , NULL) ;
LineTo(hdc , pos.x + DISTANCE , pos.y + DISTANCE - LegLen) ;
for(int i = 0 ; i < 5 ; i++){
Arc(hdc , pos.x - DISTANCE + 2*i*LegLen , pos.y + DISTANCE - 2*LegLen ,
pos.x - DISTANCE + 2*(i+1)*LegLen , pos.y + DISTANCE ,
pos.x - DISTANCE + 2*i*LegLen , pos.y + DISTANCE - LegLen ,
pos.x - DISTANCE + 2*(i+1)*LegLen , pos.y + DISTANCE - LegLen ) ;
}
}
else{
MoveToEx(hdc , pos.x - DISTANCE , pos.y , NULL) ;
LineTo(hdc , pos.x - DISTANCE , pos.y + DISTANCE - LegLen) ;
MoveToEx(hdc , pos.x + DISTANCE , pos.y , NULL) ;
LineTo(hdc , pos.x + DISTANCE , pos.y + DISTANCE - LegLen) ;
for(int i = 0 ; i < 4 ; i++){
Arc(hdc , pos.x - DISTANCE + (2*i + 1)*LegLen , pos.y + DISTANCE - 2*LegLen ,
pos.x - DISTANCE + (2*i+3)*LegLen , pos.y + DISTANCE ,
pos.x - DISTANCE + (2*i+1)*LegLen , pos.y + DISTANCE - LegLen ,
pos.x - DISTANCE + (2*i+3)*LegLen , pos.y + DISTANCE - LegLen ) ;
}
}
frame++ ;
SelectObject(hdc , oldpen) ;
DeleteObject(pen) ;
}
void Enermy::Action(){
bool d = Collision() ;
AI(d) ;
Catch() ;
}
void Enermy::Catch(){
int dx = pos.x - player->GetPos().x ;
int dy = pos.y - player->GetPos().y ;
if(-RD < dx && dx < RD && -RD < dy && dy < RD){
player->Over() ;
}
}
-----------------------------------------------------------------------------------------------------------
红色敌人
#pragma once
#include "Enermy.h"
#include "GObject.h"
class RedEnermy :public Enermy
{
protected:
void virtual AI(bool) ;
public:
RedEnermy(void);
~RedEnermy(void);
void Draw(HDC &hdc) ;
RedEnermy(int row , int col):Enermy(row , col){
color = RGB(255 , 0 , 0) ;
}
};
#include "StdAfx.h"
#include "RedEnermy.h"
RedEnermy::RedEnermy(void)
{
}
RedEnermy::~RedEnermy(void)
{
}
void RedEnermy::Draw(HDC &hdc){
Enermy::Draw(hdc) ;
}
void RedEnermy::AI(bool hit){
int d = rand() % 4 ;
DWORD t ;
for(int k = 0 ; k < 4 ; k++){
int i = (k + d) % 4 ;
if(i == 0){
if(m_row > 0 && !pState->mapObstacle[m_row - 1][m_col]){
twCommand = UP ;
return ;
}
}
else if(i == 1){
if(m_row < MAPLENTH - 1 && !pState->mapObstacle[m_row + 1][m_col]){
twCommand = DOWN ;
return ;
}
}
else if(i == 2){
if(m_col > 0 && !pState->mapObstacle[m_row][m_col-1]){
twCommand = LEFT ;
return ;
}
}
else{
if(m_col < MAPLENTH - 1 && !pState->mapObstacle[m_row][m_col+1]){
twCommand = RIFHT ;
return ;
}
}
}
}
-------------------------------------------------------
绿色敌人
#pragma once
#include "RedEnermy.h"
class GreenEnermy : public RedEnermy{
protected:
void virtual AI(bool) ;
public:
GreenEnermy(void);
~GreenEnermy(void);
void Draw(HDC &hdc) ;
GreenEnermy(int row , int col):RedEnermy(row , col){
color = RGB(0 , 255 , 0) ;
}
};
#include "StdAfx.h"
#include "GreenEnermy.h"
GreenEnermy::GreenEnermy(void)
{
}
GreenEnermy::~GreenEnermy(void)
{
}
void GreenEnermy::Draw(HDC &hdc){
Enermy::Draw(hdc) ;
}
void GreenEnermy::AI(bool hit){
if(hit){
RedEnermy::AI(hit) ;
return ;
}
int drow = m_row - player->GetRow() ;
int dcol = m_col - player->GetCol() ;
if(drow == 0){
if(dcol > 0) twCommand = LEFT ;
else twCommand = RIFHT ;
return ;
}
else if(dcol == 0){
if(drow > 0) twCommand = UP ;
else twCommand = DOWN ;
return ;
}
RedEnermy::AI(hit) ;
}
-----------------------------------------------------
蓝色敌人:
#pragma once
#include "RedEnermy.h"
class BlueEnermy : public RedEnermy
{
protected:
void virtual AI(bool) ;
public:
BlueEnermy(void);
~BlueEnermy(void);
void Draw(HDC &hdc) ;
BlueEnermy(int row , int col):RedEnermy(row , col){
color = RGB(0 , 0 , 255) ;
}
};
#include "StdAfx.h"
#include "BlueEnermy.h"
BlueEnermy::BlueEnermy(void)
{
}
BlueEnermy::~BlueEnermy(void)
{
}
void BlueEnermy::Draw(HDC &hdc){
Enermy::Draw(hdc) ;
}
void BlueEnermy::AI(bool hit){
if(hit){
RedEnermy::AI(hit) ;
return ;
}
int drow = m_row - player->GetRow() ;
int dcol = m_col - player->GetCol() ;
if(drow * drow >= dcol * dcol){
if(dcol > 0) twCommand = LEFT ;
else twCommand = RIFHT ;
return ;
}
else if(dcol == 0){
if(drow > 0) twCommand = UP ;
else twCommand = DOWN ;
return ;
}
RedEnermy::AI(hit) ;
}
-------------------------------------------------------------------------
地图
#pragma once
#include "stdafx.h"
#define MAPLENTH 19
class GMap{
protected:
static int LenObstacle ;
static int RadiusPean ;
void InitOP() ;
bool mapObstacle[MAPLENTH][MAPLENTH] ;
bool mapPean[MAPLENTH][MAPLENTH] ;
COLORREF color ;
public:
GMap();
virtual ~GMap();
void DrawObstacle(HDC &hdc) ;
void DrawPean(HDC &hdc) ;
friend class GObject ;
friend class Player ;
friend class RedEnermy ;
};
#include "stdafx.h"
#include "GMap.h"
GMap::GMap(void)
{
}
GMap::~GMap(void)
{
}
int GMap::LenObstacle = 36 ;
int GMap::RadiusPean = 3 ;
void GMap::DrawObstacle(HDC &hdc){
for(int i = 0 ; i < MAPLENTH ; i++){
for(int j = 0 ; j < MAPLENTH ; j++){
if(mapObstacle[i][j]){
RECT rec ;
rec.left = j * LenObstacle ;
rec.top = i * LenObstacle ;
rec.right = (j + 1) * LenObstacle ;
rec.bottom = (i + 1) * LenObstacle ;
FillRect(hdc , &rec , CreateSolidBrush(color)) ;
}
}
}
}
void GMap::DrawPean(HDC &hdc){
for(int i = 0 ; i < MAPLENTH ; i++){
for(int j = 0 ; j < MAPLENTH ; j++){
if(mapPean[i][j]){
Ellipse(hdc , j * LenObstacle + (LenObstacle/2 - RadiusPean)
, i * LenObstacle + (LenObstacle/2 - RadiusPean)
, j * LenObstacle + (LenObstacle/2 + RadiusPean)
, i * LenObstacle + (LenObstacle/2 + RadiusPean)) ;
}
}
}
}
----------------------------------
第一关
#pragma once
#include "stdafx.h"
#include "GMap.h"
class StageOne : public GMap
{
private:
bool static m_map[MAPLENTH][MAPLENTH] ;
public:
StageOne(void);
~StageOne(void);
};
#include "StdAfx.h"
#include "StageOne.h"
#define A true
#define B false
bool StageOne::m_map[MAPLENTH][MAPLENTH] ={
B,B,B,B,B,B,B,B,B,A,B,B,B,B,B,B,B,B,B,//0
B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//1
B,A,A,B,A,A,B,B,B,A,B,B,B,A,A,B,A,A,B,//2
B,A,B,B,A,A,A,A,A,A,A,A,A,A,A,B,B,A,B,//3
B,A,B,A,A,A,B,B,B,A,B,B,B,A,A,A,B,A,B,//4
B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//5
B,A,A,A,A,A,B,B,A,A,A,B,B,A,A,A,A,A,B,//6
B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//7
B,A,B,A,A,A,A,A,B,A,B,A,A,A,A,A,B,A,B,//8
A,A,A,A,A,A,A,A,B,B,B,A,A,A,A,A,A,A,A,//9
B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//10
B,A,B,A,A,B,A,A,A,A,A,A,A,B,A,A,B,A,B,//11
B,A,B,A,B,B,B,A,A,A,A,A,B,B,B,A,B,A,B,//12
B,A,A,A,A,B,A,A,A,A,A,A,A,B,A,A,A,A,B,//13
B,A,B,B,A,A,A,A,A,A,A,A,A,A,A,B,B,A,B,//14
B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//15
B,A,A,A,A,B,B,B,A,B,A,B,B,B,A,A,A,A,B,//16
B,A,A,A,A,B,A,A,A,A,A,A,A,B,A,A,A,A,B,//17
B,B,B,B,B,B,B,B,B,A,B,B,B,B,B,B,B,B,B,//18
};
#undef A
#undef B
StageOne::StageOne()
{
color = RGB(166, 202, 240) ;
memset(mapObstacle , 0 , sizeof(mapObstacle)) ;
memset(mapPean , 0 , sizeof(mapPean)) ;
for(int i = 0 ; i < MAPLENTH ; i++){
for(int j = 0 ; j < MAPLENTH ; j++){
if(m_map[i][j]) this->mapPean[i][j] = 1 ;
else this->mapObstacle[i][j] = 1 ;
}
}
}
StageOne::~StageOne(void)
{
}
-----------------------------------------------------
效果