C++小项目-吃豆子游戏

GMap.h

#pragma once //保证头文件只被编译一次#include "stdafx.h"#define MAP_LEN    19    //逻辑地图大小 (逻辑地图由行、列各为19的方块组成)#define P_ROW 10 //大嘴出生地的横逻辑坐标
#define P_COLUMN 9 //大嘴出生地的列逻辑坐标
#define E_ROW 8 //敌人出生地的横逻辑坐标
#define E_COLUMN 9 //敌人出生地的列逻辑坐标/*地图中应该存在障碍物和豆子,所以要有豆子和障碍物的尺寸和逻辑地图点阵,以及绘制地图(包括障碍物)和豆子的绘制函数以及颜色变量和设置敌我出生位置不能有豆子存在,以及地图类要能被物体类和大嘴类访问,故设置物体类和大嘴类为地图类的友元类下面为地图类,为关卡1、关卡2、关卡3的父类
*/    
class GMap
{
protected:static int LD;    //障碍物的尺寸大小,设置为静态变量,因为要所有GMap对象共用这个变量static int PD;    //豆子的半径,设置为静态变量,因为要所有GMap对象共用这个变量bool mapData[MAP_LEN][MAP_LEN]; //障碍物逻辑地图点阵bool peaMapData[MAP_LEN][MAP_LEN]; //豆子逻辑地图点阵COLORREF color; //COLORREF是DWORD的宏,而DWORD是unsigned long//----void InitOP();    //使敌我双方的出生位置没有豆子存在public:void DrawMap(HDC &hdc); //绘制地图void DrawPeas(HDC &hdc); //绘制豆子
friend class GObject; //设置物体类为地图类的友元类,使物体类对象能访问地图类对象friend class PacMan; //设置大嘴类为地图类的友元类,使大嘴类对象能访问地图类对象
};//关卡1类,为地图类的子类
class Stage_1:public GMap  //c++默认的是private继承,无法进行转换,所以继承后面都要有一个public
{
private:bool static initData[MAP_LEN][MAP_LEN]; //关卡逻辑地图点阵public:Stage_1(); //构造函数
};class Stage_2:public GMap
{
private: bool static initData[MAP_LEN][MAP_LEN];
public:Stage_2();
};
class Stage_3:public GMap
{
private: bool static initData[MAP_LEN][MAP_LEN];
public:Stage_3();
};

 

GMap.cpp 

#include "stdafx.h"
#include "GMap.h"int GMap::LD =36; //初始化静态变量  障碍物的尺寸大小
int GMap::PD =3; //豆子的半径//使敌我双方的出生位置没有豆子存在
void GMap::InitOP()
{peaMapData[P_ROW][P_COLUMN] = false; //让大嘴出生地的豆子消失 true,有豆子 false,无豆子peaMapData[E_ROW][E_COLUMN] = false; //让敌人出生地的豆子消失 true,有豆子 false,无豆子
}//绘制地图
void GMap::DrawMap(HDC &hdc)
{for(int i=0;i<MAP_LEN;i++){for(int j=0;j<MAP_LEN;j++){if(!mapData[i][j]) //元素为B,即false,为墙壁/障碍物,则进入if内绘制   是A的位置不绘制,即为空白处
            {RECT rect; //矩形结构体对象rect.left = j*LD; //设置矩形4个方向启动的坐标rect.top = i*LD;rect.right = (j+1)*LD;rect.bottom = (i+1)*LD;FillRect(hdc,&rect,CreateSolidBrush(color)); //绘制矩形(墙壁/障碍物)
            }}}
}//绘制豆子
void GMap::DrawPeas(HDC &hdc)
{for(int i=0;i<MAP_LEN;i++){for(int j=0;j<MAP_LEN;j++){if(peaMapData[i][j]) //元素为A,即true,为豆子,则进入if内绘制   是B的位置则不绘制豆子
            {Ellipse(hdc,(LD/2-PD)+j*LD,(LD/2-PD)+i*LD,(LD/2+PD)+j*LD,(LD/2+PD)+i*LD); //绘制圆弧(豆子)
            }}}        
}#define A true
#define B false//初始化static数组InitData[MAP_LEN][MAP_LEN,即关卡1的原始数据    B表示障碍物/墙壁,A表示空白处(除出生地外的空白处有豆子)
bool Stage_1::initData[MAP_LEN][MAP_LEN] ={B,B,B,B,B,B,B,B,B,A,B,B,B,B,B,B,B,B,B,//0B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//1B,A,A,B,A,A,B,B,B,A,B,B,B,A,A,B,A,A,B,//2B,A,B,B,A,A,A,A,A,A,A,A,A,A,A,B,B,A,B,//3B,A,B,A,A,A,B,B,B,A,B,B,B,A,A,A,B,A,B,//4B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//5B,A,A,A,A,A,B,B,A,A,A,B,B,A,A,A,A,A,B,//6B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//7B,A,B,A,A,A,A,A,B,A,B,A,A,A,A,A,B,A,B,//8A,A,A,A,A,A,A,A,B,B,B,A,A,A,A,A,A,A,A,//9B,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,B,A,B,//10B,A,B,A,A,B,A,A,A,A,A,A,A,B,A,A,B,A,B,//11B,A,B,A,B,B,B,A,A,A,A,A,B,B,B,A,B,A,B,//12B,A,A,A,A,B,A,A,A,A,A,A,A,B,A,A,A,A,B,//13B,A,B,B,A,A,A,A,A,A,A,A,A,A,A,B,B,A,B,//14B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//15B,A,A,A,A,B,B,B,A,B,A,B,B,B,A,A,A,A,B,//16B,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 BStage_1::Stage_1()
{color =RGB(140,240,240); //设置关卡1的地图颜色for(int i=0;i<MAP_LEN;i++){for(int j=0;j<MAP_LEN;j++){this->mapData[i][j] = this->initData[i][j]; //初始化关卡1的地图数据this->peaMapData[i][j] = this->initData[i][j]; //初始化关卡1的豆子数据
        }}//敌我双方出现位置没有豆子出现this->InitOP();
}//Stage_2成员定义
#define A true
#define B false
bool Stage_2::initData[MAP_LEN][MAP_LEN]=
{B,B,B,B,B,B,B,B,B,A,B,B,B,A,B,B,B,B,B,//0A,A,A,A,A,A,A,B,A,A,B,A,A,A,B,A,B,A,A,//1B,A,A,A,B,A,A,B,A,A,B,A,B,A,B,A,B,A,B,//2B,B,B,A,B,A,A,B,B,A,B,A,B,A,B,A,B,B,B,//3B,A,A,A,A,A,A,A,A,A,A,A,B,B,B,A,A,A,B,//4B,A,A,B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//5B,A,A,B,A,A,A,B,B,B,B,B,B,A,A,B,A,A,B,//6B,A,A,B,A,B,A,A,A,A,A,A,A,A,A,B,A,A,B,//7B,A,A,B,A,B,A,A,B,A,B,A,A,B,A,B,A,A,B,//8A,A,A,B,A,B,A,A,B,B,B,A,A,B,A,B,A,A,A,//9B,A,A,B,A,B,A,A,A,A,A,A,A,B,A,A,A,A,B,//10B,A,A,B,A,A,A,B,B,B,B,B,A,B,A,A,A,A,B,//11B,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,B,//12B,A,A,A,B,B,B,B,B,B,B,A,A,A,A,A,A,A,B,//13B,A,A,A,A,A,A,A,A,A,A,A,A,B,A,A,A,A,B,//14B,B,B,B,B,A,A,A,A,B,B,B,A,B,A,A,A,A,B,//15B,A,A,A,B,B,B,A,A,A,A,B,A,B,B,B,A,A,B,//16A,A,A,A,B,A,A,A,A,A,A,B,A,A,A,B,A,A,A,//17                                 B,B,B,B,B,B,B,B,B,A,B,B,B,A,B,B,B,B,B,//18
};
#undef A
#undef BStage_2::Stage_2()
{color = RGB(240,140,140);for(int i= 0;i<MAP_LEN;i++){for(int j =0;j<MAP_LEN;j++){this->mapData[i][j] = this->initData[i][j]; this->peaMapData[i][j] = this->initData[i][j];}}//敌我双方出现位置没有豆子出现this->InitOP();
}//Stage_3成员定义
#define A true
#define B false
bool Stage_3::initData[MAP_LEN][MAP_LEN]=
{B,B,B,B,B,B,B,B,B,A,B,B,B,B,B,B,B,B,B,//0A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,//1B,A,A,B,A,A,B,B,B,B,B,B,B,A,A,A,B,A,B,//2B,A,B,B,A,A,A,A,A,A,A,A,B,A,A,A,B,A,B,//3B,A,B,A,A,A,B,B,B,B,B,B,B,A,A,A,B,A,B,//4B,A,B,A,B,B,B,A,A,A,A,A,B,B,B,A,B,A,B,//5B,A,A,A,B,A,B,A,A,A,A,A,A,A,A,A,B,A,B,//6B,A,B,A,B,A,A,A,A,A,A,A,A,B,A,A,B,A,B,//7B,A,B,A,B,B,A,A,B,A,B,A,A,B,A,A,B,A,B,//8B,A,A,A,A,B,A,A,B,B,B,A,A,B,A,A,B,A,B,//9B,A,B,A,A,B,A,A,A,A,A,A,A,B,A,A,A,A,B,//10B,A,B,A,A,B,A,A,A,A,A,A,B,B,B,A,B,A,B,//11B,A,B,A,A,B,A,B,B,B,B,B,B,A,B,A,B,A,B,//12B,A,B,A,A,B,A,A,A,A,A,A,A,A,B,A,B,A,B,//13B,A,B,B,A,B,B,B,B,B,B,A,B,A,B,A,B,A,B,//14B,A,A,A,A,B,A,A,A,A,A,A,B,A,B,A,B,A,B,//15B,B,B,B,B,B,A,A,B,B,B,A,B,A,B,A,B,A,B,//16A,A,A,A,A,A,A,A,B,A,A,A,A,A,B,A,A,A,A,//17                                 B,B,B,B,B,B,B,B,B,A,B,B,B,B,B,B,B,B,B,//18
};
#undef A
#undef BStage_3::Stage_3()
{color = RGB(100,300,100);for(int i= 0;i<MAP_LEN;i++){for(int j =0;j<MAP_LEN;j++){this->mapData[i][j] = this->initData[i][j]; this->peaMapData[i][j] = this->initData[i][j];}}//敌我双方出现位置没有豆子出现this->InitOP();
}

 

GObject.h

#include "stdafx.h"
#include <time.h>
#include "GMap.h"#define DISTANCE 10//图型范围
#define D_OFFSET   2//绘图误差
#define RD (DISTANCE + D_OFFSET)//绘图范围 12 
//----
#define PLAYER_SPEED 6//玩家速度
#define ENERMY_SPEED 4//敌人速度
//----
#define LEGCOUNTS 5//敌人腿的数量
#define BLUE_ALERT 8//蓝色警戒范围//方向枚举
enum TWARDS{UP,DOWN,LEFT,RIGHT,OVER};//物体类 (含有纯虚函数,为抽象类,不能被实例化)
class GObject
{
protected:int dRow; //逻辑横坐标int dColumn; //逻辑纵坐标POINT point; //中心坐标int mX; //物体的中心横坐标int mY; //物体的中心纵坐标//----TWARDS twCommand;//朝向指令缓存TWARDS tw;//朝向//----int speed;//速度int frame;//帧数//子程序bool Achive(); //判断物体是否到达逻辑坐标位置int PtTransform(int k);//将实际坐标转换为逻辑坐标virtual void AchiveCtrl();//到达逻辑点后更新数据bool Collision() ;//逻辑碰撞检测,将物体摆放到合理的位置public:static GMap* pStage; //指向地图类的指针,设置为静态,使所有自类对象都能够使用相同的地图
GObject(int Row,int Column); //有参构造函数int GetRow(); //提供共有接口,获取保护成员变量dRowint GetArray(); //提供共有接口,获取保护成员变量dColumnvirtual void action() = 0;//数据变更的表现//----void SetPosition(int Row,int Column); //设置自身中心位置void DrawBlank(HDC &hdc);virtual void Draw(HDC &hdc) = 0;//绘制对象
        
};//大嘴,玩家控制的对象
class PacMan:public GObject //PacMan是GObject的子类
{
protected:virtual void AchiveCtrl();//重写虚函数 (到达逻辑点后更新数据)public:PacMan(int Row,int Column);POINT GetPos(); //提供共有接口,获取保护成员变量pointTWARDS GetTw(); //提供共有接口,获取保护成员变量twCommand//----bool Win(); //轮询peaMapData[][],判断是否存在任意一个豆子,来判断是否获胜void SetTwCommand(TWARDS command); //设置大嘴的移动方向指令void Over(); //设置大嘴的方向为OVER//----void Draw(HDC &hdc); //重写虚函数: 根据移动方向指令,绘制不同朝向的大嘴4帧动画void action();//数据变更的表现 (直接调用父类GObject的逻辑碰撞检测函数)
};//追捕大嘴的敌人
class Enermy:public GObject //Enermy是GObject的子类
{
protected:void Catch(); //检测敌人是否抓捕到大嘴void virtual MakeDecision(bool b) = 0;//AI实现
    COLORREF color;public:static PacMan* player; //在敌人类中,定义一个玩家(大嘴) 设置为静态变量,全部敌人追捕一个公共的玩家void virtual  Draw(HDC& hdc); //绘制敌人的图像Enermy(int x,int y);void virtual action();
};//松散型的敌人,随机移动
class RedOne:public Enermy  
{
protected:void virtual MakeDecision(bool b);
public:void Draw(HDC& hdc);RedOne(int x,int y):Enermy(x,y){color = RGB(255,0,0); //松散型的敌人,颜色为红色
    }
};//守卫者
class BlueOne:public RedOne
{    
protected:void virtual MakeDecision(bool b);
public:void Draw(HDC& hdc);BlueOne(int x,int y):RedOne(x,y) //守卫者,颜色为蓝色
    {color = RGB(0,0,255);}};//扰乱者
class YellowOne:public RedOne 
{
protected:void virtual MakeDecision(bool b);
public:void Draw(HDC& hdc);YellowOne(int x,int y):RedOne(x,y) {color = RGB(200,200,100); //扰乱者,颜色为黄色
    }
};

 

GObject.cpp

#include "stdafx.h"
#include "GObject.h"//-----------------------------------------------------以下为GOject成员定义:------------------------------------------------
GMap* GObject::pStage =NULL; //静态变量使用前,必须先初始化//有参构造函数  参数为物体出生地的逻辑坐标
GObject::GObject(int Row,int Column)
{this->dRow = Row; //逻辑横坐标this->dColumn = Column; //逻辑纵坐标this->point.y = dRow*pStage->LD + pStage->LD/2; //根据逻辑坐标换算获得中心坐标  【注意y方向对应的是行dRow,x方向对应的是列dColumn】this->point.x = dColumn*pStage->LD + pStage->LD/2;this->mX = point.x; //物体的中心横坐标this->mY = point.y ; //物体的中心纵坐标
frame = 1; //初始帧数为1pStage = NULL; //初始化静态GMap指针
}//提供共有接口,获取保护成员变量dRow
int GObject::GetRow()
{return dRow;
}//提供共有接口,获取保护成员变量dColumn
int GObject::GetArray()
{return dColumn;
}//判断物体是否到达逻辑坐标位置
bool GObject::Achive()
{//若物体在逻辑坐标位置,则point.x - pStage->LD/2 为pStage->LD的整数倍,取余为0if( (point.x - pStage->LD/2)%pStage->LD==0 && (point.y - pStage->LD/2)%pStage->LD==0 ) //到达逻辑坐标位置,返回true
    {return true; //到达逻辑坐标位置,返回true
    }return false; //未到达,返回false
}//将实际坐标转换为逻辑坐标 k为point.x或者point.y
int GObject::PtTransform(int k)
{return (k - pStage->LD/2)/pStage->LD;
}//到达逻辑坐标位置后更新数据
void GObject::AchiveCtrl() //声明时,为虚函数,定义加virtual会报错
{if(Achive()) //先判断是否到达逻辑坐标位置
    {dRow = PtTransform(point.y); //更新活动逻辑横坐标,由实际横坐标转换而来 【注意y方向对应的是行dRow,x方向对应的是列dColumn】dColumn = PtTransform(point.x); //更新活动逻辑纵坐标,由实际纵坐标转换而来
    }
}//逻辑碰撞检测,将物体摆放到合理的位置    返回指令有效与否的标志位
bool GObject::Collision()
{bool cmdValid_flag = true; //指令有效与否的标志位  ==true,指令有效  ==false,指令无效//检测逻辑碰撞前,先更新数据,直到到达逻辑坐标位置,进行逻辑碰撞检测AchiveCtrl(); //更新逻辑坐标数据,若物体是大嘴,则会执行PacMan重写的AchiveCtrl()消除豆子//判断指令的有效性if(dRow<0 || dColumn<0 || dRow>MAP_LEN-1 || dColumn>MAP_LEN-1) //逻辑横、纵坐标超出允许范围,即在屏幕外,则不可以改变指令(新指令无效)cmdValid_flag = false; //(新)指令无效else if (Achive()) //到达逻辑坐标位置,才能进行逻辑碰撞检测
    {switch(twCommand) //判断前进的方向
        {case LEFT:{if(dColumn>0 && !pStage->mapData[dRow][dColumn-1]) //判断下一个格子是否是墙/障碍物  是墙,则!B=!false=truecmdValid_flag = false; //下一个格子是墙/障碍物,(新)指令无效
            }break;case RIGHT:{if(dColumn<MAP_LEN-1 && !pStage->mapData[dRow][dColumn+1])cmdValid_flag = false;}break;case UP:{if(dRow>0 && !pStage->mapData[dRow-1][dColumn])cmdValid_flag = false;}break;case DOWN:{if(dRow<MAP_LEN-1 && !pStage->mapData[dRow+1][dColumn])cmdValid_flag = false;}break;}if(cmdValid_flag)tw = twCommand; //前进方向上的下一方格不是墙壁/障碍物,则指令成功,改变方向有效
    }//依照真实的方向移动mX = point.x;mY = point.y;int MAX = pStage->LD*MAP_LEN + pStage->LD/2; //超出地图右、下边界一个方格的位置(注意是"中心"坐标)int MIN = pStage->LD/2; //超出地图左、上边界一个方格的位置switch(tw)//判断行进的方向
    {case LEFT:if(dColumn>0 && !pStage->mapData[dRow][dColumn-1])//判断下一个格子是否能够通行
        {cmdValid_flag= false;break;//"撞墙了"
        }    point.x -= speed; //改变物体在地图上的中心坐标,相当于物体在地图中移动(这里向左移动)if(point.x<MIN) //向左移动到了地图左边界外半个方格外,则从另一边出现
        {point.x = MAX;}break;//以下方向的判断原理相同case RIGHT:         if(dColumn<MAP_LEN-1&&!pStage->mapData[dRow][dColumn+1]){cmdValid_flag= false;break;//"撞墙了"
        }point.x += speed;if(point.x>MAX){point.x = MIN;}break;case UP:if(dRow>0&&!pStage->mapData[dRow-1][dColumn]){cmdValid_flag= false;break;//"撞墙了"
        }point.y -=speed;if(point.y<MIN){point.y = MAX;}break;case DOWN:if(dRow<MAP_LEN-1&&!pStage->mapData[dRow+1][dColumn]){cmdValid_flag= false;break;//"撞墙了"
        }point.y +=speed;if(point.y>MAX){point.y = MIN;}break;}return !cmdValid_flag; //返回指令有效与否的标志位
}//设置自身中心位置
void GObject::SetPosition(int Row,int Column)
{dRow = Row;dColumn = Column;point.y = dRow*pStage->LD + pStage->LD/2; //根据逻辑坐标换算获得中心坐标 【注意y方向对应的是行dRow,x方向对应的是列dColumn】point.x = dColumn*pStage->LD + pStage->LD/2;
}//将这一帧时物体所在的方格处绘制的图像擦除,移动后再绘制下一方格的图像,使物体看起来像在移动一样
void GObject::DrawBlank(HDC &hdc)
{RECT rect;rect.left = mX - RD; //这一帧时物体所在的方格(矩形),4个方向边缘坐标rect.top = mY - RD;rect.right = mX + RD;rect.bottom = mY + RD;FillRect(hdc,&rect,CreateSolidBrush(RGB(255,255,255)));
}//-----------------------------------------------------以下为PacMan(大嘴)成员定义:------------------------------------------------

PacMan::PacMan(int Row,int Column):GObject(Row,Column) //使用初始化列表,同时初始化了PacMan::dROW、dColumn、point.x、point.y等等
{this->speed = PLAYER_SPEED; //设置大嘴速度twCommand = tw = LEFT; //设置开局时大嘴的移动方向
}//提供共有接口,获取保护成员变量point
POINT PacMan::GetPos()
{return point;
}//设置大嘴的方向为OVER
void PacMan::Over()
{tw = OVER;
}//提供共有接口,获取保护成员变量tw
TWARDS PacMan::GetTw()
{return tw;
}//设置大嘴的移动方向指令
void PacMan::SetTwCommand(TWARDS command)
{twCommand = command;
}//轮询peaMapData[][],判断是否存在任意一个豆子,来判断是否获胜
bool PacMan::Win()
{for(int i=0;i<=MAP_LEN;i++){for(int j=0;j<=MAP_LEN;j++){    if(pStage->peaMapData[i][j]==true){return false; //存在任意一个豆子,没取得胜利
            }}}return true;//没有豆子,胜利
}//重写虚函数 (到达逻辑点后更新数据)
void PacMan::AchiveCtrl()
{GObject::AchiveCtrl(); //直接调用GObject类的功能函数: 到达逻辑坐标位置后更新数据//重写虚函数,为实现大嘴的吃豆子功能if(Achive()) //必须到达逻辑坐标位置,才能进行下一步
    {if(dRow>=0 && dRow<MAP_LEN && dColumn>=0 && dColumn<MAP_LEN)//防止数组越界
        {//peaMapData[dRow][dColumn]:   ==true,表示有豆子   ==false,表示没有豆子if(pStage->peaMapData[dRow][dColumn]) //豆子到达的逻辑坐标位置,如果有豆子
            {pStage->peaMapData[dRow][dColumn] = false; //则将豆子"吃掉"
            }}}    
}//行为函数,直接调用父类GObject的逻辑碰撞检测函数
void PacMan::action()
{Collision(); //直接调用父类GObject的逻辑碰撞检测函数
}//重写虚函数: 根据移动方向指令,绘制不同朝向的大嘴4帧动画
void PacMan::Draw( HDC& hdc)
{if(tw == OVER) //移动指令为OVER,无效,不执行如何程序
    {}else if(frame%2 == 0) //绘制第2帧动画和第4帧动画 (都是V形开口的圆弧)
    {int x1=0,x2=0,y1=0,y2=0;int offsetX =  DISTANCE/2+D_OFFSET;//弧弦交点 10/2+2 = 7int offsetY =  DISTANCE/2+D_OFFSET;//弧弦交点switch(tw) //移动方向不同,(大嘴)圆弧的V形开口不同
        {case UP: x1 = point.x - offsetX;x2 = point.x + offsetX;y2 = y1 = point.y-offsetY;break;case DOWN:x1 = point.x + offsetX;x2 = point.x - offsetX;y2 = y1 = point.y+offsetY;break;case LEFT:x2 = x1 = point.x-offsetX;y1 = point.y + offsetY;y2 = point.y - offsetY;break;case RIGHT: //V形开口向右x2 = x1 =point.x + offsetX;y1 = point.y - offsetY;y2 = point.y + offsetY;break;}//绘制圆弧   RIGHT朝向情况下,x1,y1和x2,y2各为右上角、右下角的弧弦交点Arc(hdc,point.x-DISTANCE,point.y-DISTANCE,point.x+DISTANCE,point.y+DISTANCE,x1,y1,x2,y2);MoveToEx(hdc,x1,y1,NULL); //RIGHT朝向情况下,移动坐标原点到右上角的弧弦交点LineTo(hdc,point.x,point.y); //绘制右上角的弧弦交点到大嘴中心坐标点的直线LineTo(hdc,x2,y2); //绘制大嘴中心坐标点到右下角的弧弦交点的直线
    }else if(frame%3 ==0) //绘制第3帧动画 (椭圆)
    {Ellipse(hdc,point.x-DISTANCE,point.y-DISTANCE,point.x+DISTANCE,point.y+DISTANCE);}else  //绘制第1帧动画 半圆
    {int x1=0,x2=0,y1=0,y2=0;switch(tw){case UP: x1 = point.x - DISTANCE;x2 = point.x + DISTANCE;y2 = y1 = point.y;break;case DOWN:x1 = point.x + DISTANCE;x2 = point.x - DISTANCE;y2 = y1 = point.y;break;case LEFT:x2 = x1 = point.x;y1 = point.y + DISTANCE;y2 = point.y - DISTANCE;break;case RIGHT:x2 = x1 =point.x ;y1 = point.y - DISTANCE;y2 = point.y + DISTANCE;break;}Arc(hdc,point.x-DISTANCE,point.y-DISTANCE,point.x+DISTANCE,point.y+DISTANCE,x1,y1,x2,y2);MoveToEx(hdc,x1,y1,NULL);LineTo(hdc,point.x,point.y);LineTo(hdc,x2,y2);}frame++;//绘制下一祯
}//-----------------------------------------------------以下为Enermy(敌人)成员定义:------------------------------------------------

PacMan* Enermy::player = NULL; //在敌人类中,定义一个玩家(大嘴) 设置为静态变量,全部敌人追捕一个公共的玩家//Enermy(敌人)的构造函数
Enermy::Enermy(int x,int y):GObject(x,y)
{this->speed = ENERMY_SPEED; //设置敌人的速度twCommand = tw = LEFT; //设置开局时,敌人的移动方向//twCommand = UP;
}//检测敌人是否抓捕到大嘴
void Enermy::Catch()
{int DX =point.x - player->GetPos().x; //敌人与玩家的中心坐标,在x方向上的距离int DY =point.y - player->GetPos().y; //敌人与玩家的中心坐标,在y方向上的距离//敌人与玩家的中心坐标,在x、y方向上的距离小于绘图距离RD,则说明敌人和玩家接触了一半身体  敌人和玩家的直径接近2*RD,实际是2*DISTANCEif((-RD<DX && DX<RD) && (-RD<DY && DY<RD)) {player->Over(); //敌人抓到了玩家,玩家方向设置为OVER,不能再移动了
    }
}//绘制敌人的图像
void Enermy::Draw(HDC& hdc)
{HPEN pen =::CreatePen(0,0,color); //创建画笔HPEN oldPen = (HPEN)SelectObject(hdc,pen); //应用创建的画笔
Arc(hdc,point.x-DISTANCE,point.y-DISTANCE,point.x+DISTANCE,point.y+DISTANCE,point.x+DISTANCE,point.y,point.x-DISTANCE,point.y);//先绘制半圆型的头int const LEGLENTH = (DISTANCE)/(LEGCOUNTS); //LEGLENTH为“腿部圆弧”的半径//根据祯数来绘制身体和“腿部”if(frame%2 == 0) //绘制第2帧和第4帧图像
    {    //绘制2根直线,作为敌人的身子MoveToEx(hdc,point.x-DISTANCE,point.y,NULL);//矩形的身子LineTo(hdc,point.x-DISTANCE,point.y +DISTANCE - LEGLENTH);MoveToEx(hdc,point.x+DISTANCE,point.y,NULL); LineTo(hdc,point.x+DISTANCE,point.y +DISTANCE - LEGLENTH);for(int i = 0;i<LEGCOUNTS;i++)//从左往右绘制“腿部”
        {//绘制腿部,为多个圆弧Arc(hdc,point.x-DISTANCE+i*2*LEGLENTH,point.y+DISTANCE-2*LEGLENTH,point.x-DISTANCE+(i+1)*2*LEGLENTH,point.y+DISTANCE,point.x-DISTANCE+i*2*LEGLENTH,point.y+DISTANCE-LEGLENTH,point.x-DISTANCE+(i+1)*2*LEGLENTH,point.y+DISTANCE-LEGLENTH);}        }else //绘制第1帧和第3帧图像
    {MoveToEx(hdc,point.x-DISTANCE,point.y,NULL);//绘制身体LineTo(hdc,point.x-DISTANCE,point.y +DISTANCE);MoveToEx(hdc,point.x+DISTANCE,point.y,NULL); LineTo(hdc,point.x+DISTANCE,point.y +DISTANCE);//从左往右绘制“腿部”
MoveToEx(hdc,point.x-DISTANCE,point.y+DISTANCE,NULL);LineTo(hdc,point.x-DISTANCE+LEGLENTH,point.y+DISTANCE-LEGLENTH);for(int i = 0;i<LEGCOUNTS-1;i++){Arc(hdc,point.x-DISTANCE+(1+i*2)*LEGLENTH,point.y+DISTANCE-2*LEGLENTH,point.x-DISTANCE+(3+i*2)*LEGLENTH,point.y+DISTANCE,point.x-DISTANCE+(1+i*2)*LEGLENTH,point.y+DISTANCE-LEGLENTH,point.x-DISTANCE+(3+i*2)*LEGLENTH,point.y+DISTANCE-LEGLENTH);}MoveToEx(hdc,point.x+DISTANCE,point.y+DISTANCE,NULL);LineTo(hdc,point.x+DISTANCE-LEGLENTH,point.y+DISTANCE-LEGLENTH);}//根据方向绘制眼睛int R = DISTANCE/5; //眼睛的半径switch(tw){case UP:Ellipse(hdc,point.x-2*R,point.y-2*R,point.x,point.y);Ellipse(hdc,point.x,point.y-2*R,point.x+2*R,point.y);break;case DOWN:Ellipse(hdc,point.x-2*R,point.y,point.x,point.y+2*R);Ellipse(hdc,point.x,point.y,point.x+2*R,point.y+2*R);break;case LEFT:Ellipse(hdc,point.x-3*R,point.y-R,point.x-R,point.y +R);Ellipse(hdc,point.x-R,point.y-R,point.x+R,point.y +R);break;case RIGHT:Ellipse(hdc,point.x-R,point.y-R,point.x+R,point.y +R);Ellipse(hdc,point.x+R,point.y-R,point.x+3*R,point.y+R);break;}frame++; //准备绘制下一祯
SelectObject(hdc,oldPen);DeleteObject(pen); //销毁画笔return;
}//敌人:数据变更的表现
void Enermy::action()
{bool b = Collision();MakeDecision(b);Catch();
}//-----------------------------------------------------以下为RedOne(敌人)成员定义:------------------------------------------------//绘制RedOne(敌人)的图像
void RedOne::Draw(HDC& hdc)
{Enermy::Draw(hdc);
}//AI-人工智能函数: 松散型
void RedOne::MakeDecision(bool b)
{//srand(time(0));int i = rand();if(b)//撞到墙壁,改变方向
    {//逆时针转向if(i%4==0){tw == UP?twCommand = LEFT:twCommand=UP;        }else if(i%3==0){tw == DOWN?twCommand =RIGHT:twCommand=DOWN;}else if(i%2==0){tw == RIGHT?twCommand = UP:twCommand=RIGHT;}else {tw == LEFT?twCommand = DOWN:twCommand=LEFT;}return;}if(i%4==0){twCommand!=UP?tw==DOWN:twCommand ==UP;        }else if(i%3==0){tw != DOWN?twCommand = UP:twCommand=DOWN;}else if(i%2==0){tw != RIGHT?twCommand = LEFT:twCommand=RIGHT;}else {tw != LEFT?twCommand = RIGHT:twCommand=LEFT;}}//-----------------------------------------------------以下为BlueOne(敌人)成员定义:------------------------------------------------//绘制BlueOne(敌人)的图像
void BlueOne::Draw( HDC& hdc)
{Enermy::Draw(hdc);
}//AI-人工智能函数: 守卫者
void BlueOne::MakeDecision(bool b)
{const int DR = this->dRow-player->GetRow();const int DA = this->dColumn-player->GetArray();if(!b&&DR==0){if(DA<=BLUE_ALERT&&DA>0)//玩家在左侧边警戒范围s
        {twCommand = LEFT;    //向左移动return;}if(DA<0&&DA>=-BLUE_ALERT)//右侧警戒范围
        {twCommand = RIGHT;//向右移动return;}}if(!b&&DA==0){if(DR<=BLUE_ALERT&&DR>0)//下方警戒范围
        {twCommand = UP;    return;}if(DR<0&&DR>=-BLUE_ALERT)//上方警戒范围
        {    twCommand = DOWN;return;}}RedOne::MakeDecision(b);//不在追踪模式时RED行为相同
}//-----------------------------------------------------以下为YellowOne(敌人)成员定义:------------------------------------------------//绘制YellowOne(敌人)的图像
void YellowOne::Draw(HDC& hdc)
{Enermy::Draw(hdc);
}//AI-人工智能函数:扰乱者
void YellowOne::MakeDecision(bool b)
{const int DR = this->dRow-player->GetRow();const int DA = this->dColumn-player->GetArray();if(!b){if(DR*DR>DA*DA){if(DA>0)//玩家在左侧边警戒范围
            {twCommand = LEFT;    //向左移动return;}else if(DA<0)//右侧警戒范围
            {twCommand = RIGHT;//向右移动return;}}else{if(DR>0)//下方警戒范围
            {twCommand = UP;    return;}if(DR<0)//上方警戒范围
            {    twCommand = DOWN;return;}}}RedOne::MakeDecision(b);
}

 

PacMan.cpp(包含主函数)

// pacman.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "pacman.h"
#include "GObject.h"//-----start-----
#define WLENTH 700
#define WHIGHT 740
#define STAGE_COUNT 3 //关卡数//游戏物体
PacMan* p ;
GObject* e1;
GObject* e2 ;
GObject* e3 ;
GObject* e4 ;//释放动态内存函数模板
template<class T>
void Realese(T t)
{if(t!=NULL)delete t; 
}//进入下一关卡的时候,还原所有物体的位置
void ResetGObjects()
{p->SetPosition(P_ROW,P_COLUMN);e1->SetPosition(E_ROW,E_COLUMN);e2->SetPosition(E_ROW,E_COLUMN);e3->SetPosition(E_ROW,E_COLUMN);e4->SetPosition(E_ROW,E_COLUMN);
}//------end------#define MAX_LOADSTRING 100// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名s// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE,int,HWND&);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: 在此放置代码。int s_n = 0;//进行到的关卡数p = new PacMan(P_ROW,P_COLUMN);e1 =new RedOne(E_ROW,E_COLUMN);e2 =new RedOne(E_ROW,E_COLUMN);e3 = new BlueOne(E_ROW,E_COLUMN);e4 = new YellowOne(E_ROW,E_COLUMN);GMap* MapArray[STAGE_COUNT] = {new Stage_1(),new Stage_2(),new Stage_3()};GObject::pStage =MapArray[s_n];//初始化为第一关地图Enermy::player = p;//-----end-----
MSG msg;HACCEL hAccelTable;// 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_PACMAN, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// 执行应用程序初始化: 【改写了】
    HWND hWnd;if (!InitInstance (hInstance, nCmdShow,hWnd)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PACMAN));DWORD t =0;// 主消息循环:while(p->GetTw()!=OVER&&s_n<3){if(p->Win()) //赢了,p->Win()返回true
        {HDC hdc = GetDC(hWnd);    s_n++;ResetGObjects(); //进入下一关卡的时候,还原所有物体的位置if(s_n <3){MessageBoxA(hWnd,"恭喜您过关","吃豆子提示",MB_OK);GObject::pStage = MapArray[s_n];RECT screenRect;screenRect.top = 0;screenRect.left = 0;screenRect.right = WLENTH;screenRect.bottom = WHIGHT;::FillRect(hdc,&screenRect,CreateSolidBrush(RGB(255,255,255)));GObject::pStage->DrawMap(hdc);}continue;}if(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}if(GetAsyncKeyState(VK_DOWN)&0x8000){p->SetTwCommand(DOWN);}if(GetAsyncKeyState(VK_LEFT)&0x8000){p->SetTwCommand(LEFT);}if(GetAsyncKeyState(VK_RIGHT)&0x8000){p->SetTwCommand(RIGHT);}if(GetAsyncKeyState(VK_UP)&0x8000){p->SetTwCommand(UP);}else{if(GetTickCount()-t>58) //每58ms,游戏的数据和画面会更新一次
            {HDC hdc = GetDC(hWnd);    e1->action();e2->action();e3->action();e4->action();p->action();GObject::pStage->DrawPeas(hdc);e1->DrawBlank(hdc);e2->DrawBlank(hdc);e3->DrawBlank(hdc);e4->DrawBlank(hdc);    p->DrawBlank(hdc);        e1->Draw(hdc);e2->Draw(hdc);e3->Draw(hdc);e4->Draw(hdc);p->Draw(hdc);DeleteDC(hdc); //销毁上下文设备
t = GetTickCount(); //GetTickCount()函数获得的是从开机到当前时刻机器运行的毫秒数
            }}}Realese(e1);Realese(e2);Realese(e3);Realese(e4);for(int i = 0;i<STAGE_COUNT;i++){Realese(MapArray[i]);}if(p->GetTw()==OVER){MessageBoxA(hWnd,"出师未捷","吃豆子提示",MB_OK);}else{MessageBoxA(hWnd,"恭喜您赢得了胜利","吃豆子提示",MB_OK);}Realese(p);return (int) msg.wParam;
}//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释:
//
//    仅当希望
//    此代码与添加到 Windows 95 中的“RegisterClassEx”
//    函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
//    这样应用程序就可以获得关联的
//    “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style            = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc    = WndProc;wcex.cbClsExtra        = 0;wcex.cbWndExtra        = 0;wcex.hInstance        = hInstance;wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PACMAN));wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_PACMAN);wcex.lpszClassName    = szWindowClass;wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));return RegisterClassEx(&wcex);
}//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow,HWND& hWnd)  //【改写了,增加了一个参数HWND& hWnd】
{hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,0, 0, WLENTH, WHIGHT, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE;
}//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND    - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY    - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;switch (message){case WM_COMMAND:wmId    = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_START:case IDM_EXIT:DestroyWindow(hWnd);default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO: 在此添加任意绘图代码...GObject::pStage->DrawMap(hdc);EndPaint(hWnd, &ps);break;case WM_DESTROY:PostQuitMessage(0);::exit(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE;
}

 

转载于:https://www.cnblogs.com/linuxAndMcu/p/9736873.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

argb888与rgb888转换程序_一文了解各平台RGB565和RGB888区别

原标题&#xff1a;一文了解各平台RGB565和RGB888区别用过AM335x平台的小伙伴应该知道&#xff0c;OK335xS开发平台的LCD接口是RGB888模式的&#xff0c;而OK335xD开发平台的LCD接口是RGB565模式的。如果把xS的镜像烧写到xD平台上&#xff0c;那么LCD会显示颜色异常。这是为什么…

d4d#9 玩Docker只要浏览器就够了,PWD是个神奇的网站

本文是d4d系列的第9篇&#xff0c;在这一篇中给大家介绍一个学习Docker最为快捷高效的方式&#xff0c;你不需要自己搭建环境&#xff0c;也不用担心把自己的开发环境搞乱&#xff0c;你需要的只是一个浏览器&#xff0c;就可以立即开始学习Docker的常用命令&#xff1b;你甚至…

基于 Docker 打造前端持续集成开发环境

知乎: https://zhuanlan.zhihu.com/p/37961402本文将以一个标准的 Vue 项目为例&#xff0c;完全抛弃传统的前端项目开发部署方式&#xff0c;基于 Docker 容器技术打造一个精简的前端持续集成的开发环境。 前置知识&#xff1a;1. CI&#xff08;持续集成&#xff09;&#xf…

哪个内存更快?Heap或ByteBuffer或Direct?

Java正在成为新的C / C &#xff0c;它被广泛用于开发高性能系统。 对像我这样的数百万Java开发人员来说非常好&#xff01; 在这个博客中&#xff0c;我将分享我可以用Java完成的不同类型的内存分配实验以及您从中获得的好处。 Java中的内存分配 Java提供哪种类型的内存分配…

java没有打印mysql日志_0216 aop和打印数据库执行日志

需求maven依赖p6spyp6spy3.8.7com.google.guavaguava28.2-jreorg.springframework.bootspring-boot-starter-data-jpaorg.springframework.bootspring-boot-starter-webmysqlmysql-connector-javaruntimeorg.projectlomboklomboktrue打印sql配置要点&#xff1a;驱动配置 appli…

php数组基础

php中&#xff0c;数组的下标可以是整数&#xff0c;或字符串。 php中&#xff0c;数组的元素顺序不是由下标决定&#xff0c;而是由其“加入”的顺序决定。 定义&#xff1a; $arr1 array(元素1&#xff0c;元素2&#xff0c;。。。。。 ); array(1, 5, 1.1, “abc”, tr…

1.格式化输入输出

1.格式化输入input() input()函数&#xff0c;通常只能返回一个数据类型&#xff0c;那么怎么可以进行多个变量的复制呢&#xff1f;看下面这段代码。 1 str1, str2 eval(input("请输入两个字符串&#xff1a;")) 2 print(str1, str2) 3 4 num1, num2 eval(input(…

canvas像素点操作 —— 视频绿幕抠图

原文地址 主要内容 上篇文章学习了canvas像素点的获取 —— 传送门&#xff0c; 今天学一下canvas像素点操作。 一个方法&#xff1a;putImageData putImageData 用法&#xff1a; context.putImageData(imgData, x, y, dX, dY, dWidth, dHeight);参数描述imgData规定要放…

Java中的迭代器设计模式–示例教程

迭代器模式是一种行为模式&#xff0c;用于提供遍历一组对象的标准方式。 Iterator模式在Java Collection Framework中得到了广泛使用&#xff0c;其中Iterator接口提供了遍历集合的方法。 根据GoF&#xff0c;迭代器设计模式的意图是&#xff1a; 提供一种在不暴露其基础表示…

random

1 import random2 3 result random.randint(1, 7) # 随机生成1到7的整数4 result random.random() # 随机生成[0,1)的浮点数5 result random.randrange(1, 7) # 随机生成1到7的整数6 result random.choice([1, 2, 3, 4]) # 从列表中随机选择一个元素7 result random.c…

面向对象 解释 经典啊

想必大家都知道面向对象三大特征&#xff1a;继承&#xff0c;封装&#xff0c;多态。 假如你现在有一个女朋友&#xff0c;那么现在你就可以称呼你的女朋友为对象啦。首先&#xff0c;你女朋友的身高三围等我们称作为属性&#xff0c;你如果想要跟你好基友分享一下你女朋友的身…

关于Unity实现AR功能(五)摄像头转换与闪光灯开关控制

1 /// <summary>2 /// 摄像头转换3 /// </summary>4 /// <param name"s_cameraDirection">摄像头转换方向</param>5 public void ChangeCameraDirectionMet(CameraDevice.CameraDirection s_cameraDirection)6 {7 …

并发编程(一):基础概述

本篇博客主要讲述并发编程中的一些基础内容&#xff0c;并了解一下基本概念。 首先我们了解一下什么是并发&#xff1f; 同时拥有两个或者多个线程&#xff0c;如果程序在单核处理器上运行&#xff0c;多个线程将交替的换入或者换出内存&#xff0c;这些线程是同时“存在”的&a…

Dumb Bones UVA - 10529(概率dp)

题意&#xff1a; 你试图把一些多米诺骨牌排成直线&#xff0c;然后推倒它们。但是如果你在放骨牌的时候不小心把刚放的骨牌碰倒了&#xff0c;它就会把相临的一串骨牌全都碰倒&#xff0c; 而你的工作也被部分的破坏了。 比如你已经把骨牌摆成了DD__DxDDD_D的形状&#xff0c;…

M - 非常可乐

1 #include <string.h>2 #include <stdio.h>3 #include <queue>4 using namespace std;5 6 int s,n,m;7 int vis[105][105][105];8 9 struct node10 {11 int s,n,m,step;12 };13 int check(int x,int y,int z)//平分条件14 {15 if(x 0 && y…

ArrayList和Vector的区别

这两个类都实现了List接口&#xff08;List接口继承了Collection接口&#xff09;&#xff0c;他们都是有序集合&#xff0c;即存储在这两个集合中的元素的位置都是有顺序的&#xff0c;相当于一种动态的数组&#xff0c;我们以后可以按位置索引号取出某个元素&#xff0c;并且…

【luogu1613】跑路 - 倍增+Floyd

题目描述 小A的工作不仅繁琐&#xff0c;更有苛刻的规定&#xff0c;要求小A每天早上在6&#xff1a;00之前到达公司&#xff0c;否则这个月工资清零。可是小A偏偏又有赖床的坏毛病。于是为了保住自己的工资&#xff0c;小A买了一个十分牛B的空间跑路器&#xff0c;每秒钟可以跑…

python哲学翻译_Python

正在学习Python开发语言的用户&#xff0c;可能会在学习过程中听说过讲师说过Python有一段有关于Python的哲学理念机设计思想&#xff0c;在Python里输入“import this”命令就会出现一段英文格言&#xff0c;这里我们把Python的这段格言的双语版分享出来&#xff0c;帮助正在学…

如何创建线程?

Java并发编程&#xff1a;如何创建线程&#xff1f; 在前面一篇文章中已经讲述了在进程和线程的由来&#xff0c;今天就来讲一下在Java中如何创建线程&#xff0c;让线程去执行一个子任务。下面先讲述一下Java中的应用程序和进程相关的概念知识&#xff0c;然后再阐述如何创建线…

经典MapReduce作业和Yarn上MapReduce作业运行机制

一、经典MapReduce的作业运行机制 如下图是经典MapReduce作业的工作原理&#xff1a; 1.1 经典MapReduce作业的实体 经典MapReduce作业运行过程包含的实体&#xff1a; 客户端&#xff0c;提交MapReduce作业。JobTracker&#xff0c;协调作业的运行。JobTracker是一个Java应用程…