超级玛丽demo9

在超级玛丽中 有带问号的箱子 还有会运动的蘑菇 还有金币

这显然是不普通的 障碍物

今天我们实现一个 顶箱子 然后出现 会自动移动的蘑菇功能

直接放代码 这玩意写了我两天 实现了能走的蘑菇 还有顶出金币的箱子 还有吃金币。

过程懒得写了,不过说实话 这9个demo之后,写了几千行 应该差不多1万行代码 前前后后

项目工程能力 有了提升。

对游戏开发 卷轴 敌人 碰撞 等等的基础开发框架 开发模式 有了初步了解。

说实话最大的体会就是之前玩了一款游戏使用汇编语言编程,现在用一个c++这样的底层语言之后,能完成这种规模的项目,如果用汇编语言是完全没有可能去实现的。

汇编语言 要一行一行的完成 到处都是goto语句 阅读起来也很困难 哪怕是个for循环都要写10行。

后面这个项目我看找机会录个视频发b站讲解一下吧。

目录

超级玛丽demo9

管理类

BarrierManager.h

cpp 复制代码
#pragma once
#include<list>
#include"BarrierManager.h"
using namespace std;

class CBarrier;
class CHero;



class CBarrierManager {
public:
	list<CBarrier*> m_BarrierList;
public:
	bool AddBarrier(CBarrier* pBarrier);
	bool HeroBarCld(CHero* pHero, int fx);
	void Run();
};

extern CBarrierManager g_BarrierManager;

BarrierManager.cpp

cpp 复制代码
#include "BarrierManager.h"
#include"Hero.h"
#include"Barrier.h"

CBarrierManager g_BarrierManager;

bool CBarrierManager::AddBarrier(CBarrier* pBarrier)
{
    if (pBarrier == nullptr)
        return false;
    m_BarrierList.push_back(pBarrier);
    return true;
}

bool CBarrierManager::HeroBarCld(CHero* pHero, int fx)
{
    if (pHero == nullptr)
        return false;

    //把英雄构造成矩形
    //属性结构体是封装了的 用get函数 访问私有变量 SX* GetSx();
    //CMyrect 里面的东西没有封装 是public 直接用
    CMyRect heroRect;
    heroRect.left = pHero->GetSx()->x;
    heroRect.top = pHero->GetSx()->y;
    heroRect.right = pHero->GetSx()->x + pHero->GetSx()->w - 1;
    heroRect.bottom = pHero->GetSx()->y + pHero->GetSx()->h - 1;
    //还是该写个中间量 写了一大堆pHero->GetSx() 耽误时间了 不过也是复制粘贴

    for (auto pBarrier : m_BarrierList) {
        if (pBarrier->getRect().collider(&heroRect)) {
            //pBarrier->ColliderFun(*pHero, fx);
            return true;
        }
    }
    return false;
}

void CBarrierManager::Run() {
    for (auto pBarrier : m_BarrierList) {
        pBarrier->Run();
    }
}

BoxManager.h

cpp 复制代码
#pragma once
#include<list>
#include"Box.h"
using namespace std;

class CBox;

class CBoxManager {
public:
	list<CBox*> m_boxList;
public:
	bool AddBox(CBox* pBox);
	void Run();
};

extern CBoxManager g_CBoxManager;

BoxManager.cpp

cpp 复制代码
#include "BoxManager.h"

CBoxManager g_CBoxManager;

bool CBoxManager::AddBox(CBox* pBox) {
	if(pBox == nullptr)
		return false;
	m_boxList.push_back(pBox);
	return true;
}

void CBoxManager::Run() {
	for (auto pBox : m_boxList) {
		pBox->Run();
	}
}

HeroManager.h

cpp 复制代码
#pragma once
#include<vector>
#include<iostream>
using namespace std;

class CHero;


class CHeroManager {
public:
     vector<CHero*> m_HeroList;
public:
    bool AddHero(CHero* pHero);
    void Run();//用管理类 遍历更新所有英雄(调用所有英雄的run()) 虽然目前只有一个
};

extern CHeroManager g_CHeroManager;

HeroManager.cpp

cpp 复制代码
#include "HeroManager.h"
#include "Hero.h"
//在cpp文件里定义全局变量,在头文件里extern 这样其他文件包含头文件时,就能使用全局变量了
CHeroManager g_CHeroManager;

bool CHeroManager::AddHero(CHero* pHero)
{
    if(pHero == nullptr)
        return false;
    m_HeroList.push_back(pHero);
    return true;
}


void CHeroManager::Run()
{
    //遍历所有英雄  因为用不到下标 直接用auto了
    //c++ 11 新特性 自动推导类型
    for(auto pHero : m_HeroList)
    {
        pHero->Run();
    }
}

源文件.cpp

cpp 复制代码
#include <iostream>
#include"GameDraw.h"
#include"Hero.h"
#include"Mario.h"
#include"MyRect.h"
#include"Barrier.h"
#include"BarrierManager.h"
#include"HeroManager.h"
#include"wall.h"
#include"windows.h"
#include"pipe.h"
#include"Mushroom.h"
#include"Item.h"
#include"Box.h"
#include"BoxManager.h"
using namespace std;



void main() {
	g_gd.Init();
	//          1 2 3 4 5 6 7
	g_gd.SetTs("▲★●■▽□○");


	//创建地面障碍物
	
		char* map = (char*) malloc(sizeof(char) * 70);
		for (int i = 0; i < 70; i++) {
			map[i] = 4;
		}
		Cwall ground;
		ground.setPos(0, 15);
		ground.setWH(70, 1);
		ground.SetBmp("ground",map);
		g_BarrierManager.AddBarrier(&ground);


		//?Box
		char* map_box1 = (char*)malloc(sizeof(char) * 1);
		for (int i = 0; i < 1; i++) {
			map_box1[i] = 6;
		}
		char* map_box2 = (char*)malloc(sizeof(char) * 1);
		map_box2[0] = 4;
		CBox box;
		box.Init();
		box.setPos(11, 7);
		box.setWH(1, 1);
		box.SetBmp(box.m_bmpKey[0], map_box1);
		box.SetBmp(box.m_bmpKey[1], map_box2);
		g_BarrierManager.AddBarrier(&box);
		g_CBoxManager.AddBox(&box);

		CBox boxes[20];
		for (int j = 0; j < 4; j++) {
			for (int i = 0; i < 5; i++) {
				int index = j * 5 + i;
				boxes[index].Init();
				boxes[index].setPos(22+i+j*10, 7);
				boxes[index].setWH(1, 1);
				boxes[index].SetBmp(boxes[index].m_bmpKey[0], map_box1);
				boxes[index].SetBmp(boxes[index].m_bmpKey[1], map_box2);
				g_BarrierManager.AddBarrier(&boxes[index]);
				g_CBoxManager.AddBox(&boxes[index]);
			}

		}
		
		int temp_map[20] = {
			4,4,4,4,
			4,4,4,4,
			0,4,4,0,
			0,4,4,0,
			0,4,4,0,
		};
		char* map_pipe = (char*)malloc(sizeof(char) * 20);
		for (int i = 0; i < 20; i++) {
			map_pipe[i] = temp_map[i];
		}


		Cpipe pipe[5];
		for (int i = 0; i < 5; i++) {
			pipe[i].setPos(1+i*10, 10);
			pipe[i].setWH(4, 5);
			pipe[i].SetBmp("pipe", map_pipe);
			g_BarrierManager.AddBarrier(&pipe[i]);
			

		}
		
		
		CMario mario;
		mario.Init();
		g_CHeroManager.AddHero(&mario);

		char* map_craft3 = (char*)malloc(sizeof(char) * 3);
		for (int i = 0; i < 3; i++) {
			map[i] = 4;
		}
		Cwall craft3;
		craft3.setPos(12, 7);
		craft3.setWH(3, 1);
		craft3.SetBmp("craft", map);
		g_BarrierManager.AddBarrier(&craft3);

		CMushroom mushroom;
		char* map_mushroom = (char*)malloc(sizeof(char) * 1);
		map_mushroom[0] = 7;

		mushroom.Init();
		mushroom.SetPos(14, 8);
		mushroom.SetWH(1, 1);
		mushroom.SetBmp("mushroom", map_mushroom);
		


		
	while (1) {
		g_gd.Begin();
		g_BarrierManager.Run();

		g_CHeroManager.Run();
		mushroom.Run();



		g_gd.cx = mario.m_sx.x - g_gd.cw / 2;
		if (g_gd.cx < 0)	g_gd.cx = 0;
		if (g_gd.cx > 70 - g_gd.cw) g_gd.cx = 70 - g_gd.cw;
		g_gd.End();
		cout << "金币数量为" << g_gd.money << endl;
		Sleep(100);

		if (mario.m_sx.x == 69) {
			g_gd.Begin();
			g_gd.End();
			cout << "恭喜通关!" << endl<<endl;
			cout << "金币数量为" << g_gd.money << endl << endl;
			system("pause");
		}
		
	}
}

GameDraw类

GameDraw.h

cpp 复制代码
#pragma once
#include <map>

// 纹理集符号索引枚举(对应纹理集中的字符顺序)
enum TextureIndex {
	Space = 0,       // 空格(索引0)
	TriangleUp = 1,  // ▲(三角形,索引1)
	Star = 2,        // ★(五角星,索引2)
	Circle = 3,      // ●(圆形,索引3)
	Square = 4,      // ■(正方形,索引4)
	TriangleDown = 5 // ▽(倒三角形,索引5)
};

struct BMP {
	int w, h;
	char* _map;//存放堆的首地址 这里用char 后面使用char来存放整数 节约内存
};

class CGameDraw {
	public:
	//这里我们用 int ww = 70, wh = 16; 代表当前世界的宽高
	//int _max_w, _max_h;  这个游戏 最大支持 的宽高 这里暂时不用 (在游戏分辨率的调整中会有用)
	//int _w, _h;   这是当前屏幕的宽高
	int _max_w = 256, _max_h = 32;
    int _w=15, _h=16;
	int ww=70, wh=16;

	int cx = 0, cy = 0, cw = 15, ch = 16;
	int client[70 * 16];
	int money = 0;

	std::map<const char*, BMP> bmp_map;
public:
	char _ts[128];
	int _tslen;
	char print[(15 * 2 + 1) * 16 + 1];//窗口大小 宽15 高16

public:
	~CGameDraw();
	void Init();
	void Begin();//把窗口中的client清零
	void End();//把client中的内容显示到窗口上

	bool SetTs(const char* ts);
	void Draw(const char* key,int x,int y);//给client 赋值,必须是已经存在的bmp
	

	bool AddBmp(const char* key, int w,int h, const char* map);
};

extern CGameDraw g_gd;

GameDraw.cpp

cpp 复制代码
#include "GameDraw.h"
#include <iostream>
#include "Hero.h"
#include <map>
using namespace std;

CGameDraw g_gd;

CGameDraw::~CGameDraw()
{
    map<const char*, BMP>::iterator it;
    for (it = bmp_map.begin(); it != bmp_map.end(); it++) {
        free(it->second._map);
    }
}


bool CGameDraw::SetTs(const char* ts)
{
    if (ts == nullptr) {
        return false;
    }
    int i = 0;
    while (1) {
        if (ts[i] == '\0' || ts[i + 1] == '\0') {
            break;
        }
        _tslen++;
        _ts[_tslen * 2] = ts[i++];
        _ts[_tslen * 2 + 1] = ts[i++];
    }
    return true;
}

void CGameDraw::Init()
{
    ww = 70;
    wh = 16;

    _ts[0] = "  "[0];
    _ts[1] = "  "[1];
    _tslen = 0;

}

void CGameDraw::Begin()
{
    for (int i = 0; i < wh; i++) {
        for (int j = 0; j < ww; j++) {
            client[i * ww + j] = 0;
        }
    }
}

void CGameDraw::Draw(const char* key, int x, int y)
{

    ////第一个 左上角的定位点在地图中就行,其他的出界就不画

    if (key == nullptr)
        return;

    map<const char*, BMP>::iterator it;
    it = bmp_map.find(key);
    if (it == bmp_map.end())
        return;

    BMP bmp = it->second;
    for (int i = 0; i < bmp.h; i++) {
        for (int j = 0; j < bmp.w; j++) {

            if (bmp._map[j + i * bmp.w] != 0)
                client[y * ww + x] = bmp._map[j + i * bmp.w];
            x++;
        }
        y++;
        x -= bmp.w;
    }
}


void CGameDraw::End()
{

    int pos = cx + cy * ww;
    int size = 0;
    for (int i = 0; i < ch; i++) {
        for (int j = 0; j < cw; j++) {
            if (client[pos + i * ww + j] == 0) {
                print[size++] = _ts[client[pos + i * ww + j]];
                
            }
            else {
                print[size++] = _ts[client[pos + i * ww + j] * 2];
                print[size++] = _ts[client[pos + i * ww + j] * 2 + 1];
            }

        }
        print[size++] = '\n';
    }
    print[size] = 0;
    system("cls");
    std::cout << print;
}




bool CGameDraw::AddBmp(const char* key, int w, int h, const char* map)
{

    if (key == nullptr)
        return false;
    BMP bmp;
    bmp.w = w;
    bmp.h = h;
    bmp._map = (char*)malloc(w * h);
    for (int i = 0; i < w * h; i++) {
        bmp._map[i] = map[i];
    }


    std::map<const char*, BMP>::iterator it;
    it = bmp_map.find(key);

    if (it == bmp_map.end()) {
        bmp_map.insert(pair<const char*, BMP>(key, bmp));
        return true;
    }
    else
        return false;
}

抽象类

Barrier.h

cpp 复制代码
#pragma once
#include"MyRect.h"
#include"GameDraw.h"

class CHero;

class CBarrier {
public:
	const char* m_key;//名字
	
	int m_x, m_y, m_w, m_h;
	char* m_map;

public:
	virtual ~CBarrier();
	//要先设置了w h  再设置bmp  里面会往gd里构造好一个BMP
	void SetBmp(const char* key, char* map);
	void setPos(int x, int y);
	void setWH(int w, int h);
	int getX();
	int getY();
	CMyRect getRect();//这里我没用虚函数 我认为障碍物的碰撞体积和实际体积一直 不需要子类来实现

	//这三个函数 我一直觉得抽象 init run 好理解 这里end 拿来干什么? 总感觉和构函数功能重复了
	//个人理解是 可能有的障碍物 需被吃掉  变身第二阶段  吃道具改皮肤? 
	virtual void Run();
	virtual void Init();
	virtual void End();
	virtual void ColliderFun(CHero* hero, int fx);
};

Barrier.cpp

cpp 复制代码
#include "Barrier.h"
#include "Hero.h"
#include<iostream>
using namespace std;

CBarrier::~CBarrier()//虚析构函数 子类去实现
{
}

void CBarrier::SetBmp(const char* key,char* map)
{
    m_key = key;
    m_map = map;
    g_gd.AddBmp(key, m_w, m_h, map);
}

void CBarrier::setPos(int x, int y)
{
    m_x = x;
    m_y = y;
}

void CBarrier::setWH(int w, int h)
{
    m_w = w;
    m_h = h;
}

int CBarrier::getX()
{
    return m_x;
}

int CBarrier::getY()
{
    return m_y;
}

CMyRect CBarrier::getRect()
{
    //我们的碰撞函数都是基于矩形实现的 无论是英雄还是障碍物都要先构造矩形
    //然后再调用碰撞函数
    CMyRect barRect;
    barRect.left = m_x;
    barRect.right = m_x + m_w - 1;
    barRect.top = m_y;
    barRect.bottom = m_y + m_h - 1;
    return barRect;
}


//这四个都是虚函数
void CBarrier::ColliderFun(CHero* hero, int fx)//碰撞的对象不同 子类去实现
{
}

void  CBarrier::Run() {

}
void CBarrier::Init() {

}
void  CBarrier::End() {

}

Hero.h

cpp 复制代码
#pragma once
#include "MyRect.h"

enum EHeroAction {
	H_IDLE = 0,
	H_MOVE = 1,
	H_UP = 2,
	H_DOWN = 3,
};

struct SX {
	int x, y;
	int w, h;
	int jumpPower;
	int curJumpPower;

	int toward; //朝向
	int physicsState;//2 5 8
	int curAction;
};

class CHero {
public:
	SX  m_sx;
	const char* m_BMP_nameKey;

	virtual void Idle();
	virtual void Move();
	virtual void Up();
	virtual void Down();
public:
	~CHero();
	virtual void Init();
	virtual void Run();
	virtual void End();//暂时不用 没写英雄死亡
	SX* GetSx();
	CMyRect getRect();
	void SetNameBMP(const char* BMP_nameKey);
};

Hero.cpp

cpp 复制代码
#include "Hero.h"

//只有 设置图片索引名称  get属性   其他都在子类中实现

void CHero::Idle()
{
}

void CHero::Move()
{
}

void CHero::Up()
{
}

void CHero::Down()
{
}

void CHero::Run()
{

}

void CHero::Init()
{
}

void CHero::End()
{
}

SX* CHero::GetSx()
{
	return &m_sx;
}



void CHero::SetNameBMP(const char* BMP_nameKey)
{
	m_BMP_nameKey = BMP_nameKey;
}
CMyRect CHero::getRect()
{
    //我们的碰撞函数都是基于矩形实现的 无论是英雄还是障碍物都要先构造矩形
    //然后再调用碰撞函数
    CMyRect barRect;
    barRect.left = m_sx.x;
    barRect.right = m_sx.x;
    barRect.top = m_sx.y;
    barRect.bottom = m_sx.y;
    return barRect;
}

CHero::~CHero()
{
	//子类来释放,如果子类没有开堆 子类可以不写这个函数
}

Item.h

cpp 复制代码
#pragma once
#include"MyRect.h"
#include"GameDraw.h"

class CHero;

class CItem {
protected:
	const char* m_key;
	int m_x, m_y;
	int m_w, m_h;
	bool m_act;
public:
	void SetBmp(const char* key, char* map);//设置好大小 map 之后再调用
	void SetPos(int x, int y);
	void SetWH(int w, int h);
	int GrtX();
	int GrtY();
	void SetActive(bool act);//true 存在 calse消失
	virtual void Run();

	virtual ~CItem();
	virtual void ColliderFun();
	virtual CMyRect GetRect();
};
cpp 复制代码
#include "Item.h"

CMyRect CItem::GetRect()
{
    CMyRect rect;
    rect.left = m_x;
    rect.top = m_y;
    rect.right = m_x + m_w -1;
    rect.bottom = m_y + m_h -1;
    return rect;
}

void CItem::SetBmp(const char* key,char* map)
{
    m_key = key;
    g_gd.AddBmp(key, m_w, m_h, map);
}

void CItem::SetPos(int x, int y)
{
    m_x = x;
    m_y = y;
}

void CItem::SetWH(int w, int h)
{
    m_w = w;
    m_h = h;
}

int CItem::GrtX()
{
    return m_x;
}

int CItem::GrtY()
{
    return m_y;
}

void CItem::SetActive(bool act)
{
    m_act = act;
}

void CItem::Run()
{
}



CItem::~CItem()
{
}

void CItem::ColliderFun()
{
}

Item.cpp

cpp 复制代码
#include "Item.h"

CMyRect CItem::GetRect()
{
    CMyRect rect;
    rect.left = m_x;
    rect.top = m_y;
    rect.right = m_x + m_w -1;
    rect.bottom = m_y + m_h -1;
    return rect;
}

void CItem::SetBmp(const char* key,char* map)
{
    m_key = key;
    g_gd.AddBmp(key, m_w, m_h, map);
}

void CItem::SetPos(int x, int y)
{
    m_x = x;
    m_y = y;
}

void CItem::SetWH(int w, int h)
{
    m_w = w;
    m_h = h;
}

int CItem::GrtX()
{
    return m_x;
}

int CItem::GrtY()
{
    return m_y;
}

void CItem::SetActive(bool act)
{
    m_act = act;
}

void CItem::Run()
{
}



CItem::~CItem()
{
}

void CItem::ColliderFun()
{
}

工具类

MyRect.h

cpp 复制代码
#pragma once
class CMyRect {
public:
	int left, top, right, bottom;

	bool collider(CMyRect* other);
	bool setRect(int x, int y, int w, int h);
};

MyRect.cpp

cpp 复制代码
#include "MyRect.h"

bool CMyRect::collider(CMyRect* other)
{
    if(right < other->left || left > other->right || bottom < other->top || top > other->bottom)
        return false;
    return true;
}

bool CMyRect::setRect(int x, int y, int w, int h)
{
    left = x;
    top = y;
    right = x + w - 1;
    bottom = y + h - 1;
    return true;
}

派生类

Box.h

cpp 复制代码
class CBox : public CBarrier {
public:
	const char* m_bmpKey[2];
	int m_state;
	CMoney* m_money;
public:
	virtual void Run();
	virtual void Init();
	virtual void End();
	virtual void ColliderFun();
	bool Collider(CHero* hero);
};

Box.cpp

cpp 复制代码
#include "Box.h"
#include"Hero.h"
#include"GameDraw.h"
#include "Mario.h"
#include "Money.h"

void CBox::Init()
{
	m_bmpKey[0] = "?box";
	m_bmpKey[1] = "metelBox";
	m_state = 0;
	m_w = 1;
	m_h = 1;
}

void CBox::Run(){
	if (m_state == 0) {
		g_gd.Draw(m_bmpKey[0], m_x, m_y);
	}
	else if (m_state == 1) {
		g_gd.Draw(m_bmpKey[1], m_x, m_y);
		m_money->Run();
	}
	
}
void CBox::End(){}
void CBox::ColliderFun(){
	//爆金币
	if(m_state == 1)
		return;
	m_state = 1;
	//创建金币类 然后出现在游戏中
	m_money = new CMoney();
	m_money->Init();
	m_money->SetPos(m_x, m_y-1);
}

bool CBox::Collider(CHero* hero) {
		CMyRect rect = hero->getRect();
		if (this->getRect().collider(&rect)) {
			ColliderFun();
			return true;
		}
	
	return false;
}

Mario.h

cpp 复制代码
#pragma once
#include "Hero.h"
#include"GameDraw.h"
#include"Hero.h"
#include"HeroManager.h"
#include"BarrierManager.h"
#include"MyRect.h"
#include"Wall.h"

class CMario : public CHero {
	const char* m_BMPkey[3];//用于存放3个状态的 的英雄图片
    //相当于父类提供的 是静止的图片
    int jumpTemp;//跳跃时每帧会衰减
    //char m_map_empty[1] = { 0 };

    //重写父类的虚函数  没用用堆 自动重写空虚构
    virtual void Idle();
    virtual void Move();
    virtual void Up();
    virtual void Down();

public:
    CMyRect m_rect;
    virtual void Init();
    virtual void Run();
    virtual void End();//空的 没写死亡

};

Mario.cpp

cpp 复制代码
#include "Mario.h"
#include <windows.h>
#include "GameDraw.h"
#include "BarrierManager.h"
#include"BoxManager.h"
//管理类的碰撞函数 只判断是否碰撞  墙的碰撞函数 会让英雄归位

void CMario:: Idle(){
	//左右移动 跳跃 重力下落四种方式可以切换状态
	//先左右移动打断 重力写在最后 可以移动后 自动切换为下落
	m_sx.toward = 5;
	if (GetAsyncKeyState('A') ){
		m_sx.toward = 4;
		m_sx.curAction = H_MOVE;
	}
	if (GetAsyncKeyState('D') ){
		m_sx.toward = 6;
		m_sx.curAction = H_MOVE;
	}


	//重力 切换为下落
	//因为碰撞判断 要遍历所有障碍物 所以要写完 障碍管理类 再写
	m_sx.y += 1;
	//碰撞函数
	if (g_BarrierManager.HeroBarCld(this, 2) == false) {
		m_sx.curAction = H_DOWN;
		m_sx.physicsState = 2;
		return;//直接返回 不能跳跃
	}
	else { m_sx.y -= 1; }

	//跳跃 
	if (GetAsyncKeyState('J')) {
		//必须在静止和移动状态才能跳跃
		m_sx.curAction = H_UP;
		m_sx.physicsState = 8;
		//跳跃力更新
		m_sx.curJumpPower = m_sx.jumpPower;
	}
}
void CMario::Move() {
	//切换朝向 移动位置左右平移
	m_sx.toward = 5;
	if (GetAsyncKeyState('A')) {
		m_sx.toward = 4;
		m_sx.x -= 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x += 1;
		}
	}
	if (GetAsyncKeyState('D')) {
		m_sx.toward = 6;
		m_sx.x += 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x -= 1;
		}
	}
	//左右碰撞检测
	/*if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
		m_sx.curAction = H_IDLE;
	}*/

	//重力下落碰到东西 就切换为静止 
	m_sx.y += 1;
	if (g_BarrierManager.HeroBarCld(this, 2) == false) {
		m_sx.curAction = H_DOWN;
		m_sx.physicsState = 2;
		return;//直接返回 不能跳跃
	}
	else { m_sx.y -= 1; }



	//跳跃切换空中
	if (GetAsyncKeyState('J')) {
		m_sx.curAction = H_UP;
		m_sx.physicsState = 8;
		m_sx.curJumpPower = m_sx.jumpPower;
	}


}
void CMario::Up() {
	//跳跃力用完 边下落 空中也可以切换方向 向上碰撞检测、
	//这个状态 不受重力
	m_sx.toward = 5;
	if (GetAsyncKeyState('A')) {
		m_sx.toward = 4;
		m_sx.x -= 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x += 1;
		}
	}
	if (GetAsyncKeyState('D')) {
		m_sx.toward = 6;
		m_sx.x += 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x -= 1;
		}
	}
	//g_BarrierManager.HeroBarCld(this, m_sx.toward);
	//左右碰撞检测



     //上升 每帧 上升当前跳跃力格
	for (int i = 0; i < m_sx.curJumpPower; i++) {
		m_sx.y -= 1;
		//碰撞检测 如果碰撞 就开始下落 当前跳跃力为0
		if (g_BarrierManager.HeroBarCld(this, 8)) {
			m_sx.curAction = H_DOWN;
			m_sx.physicsState = 2;
			m_sx.curJumpPower = 0;
			
			//金币箱子
			for (auto pBox : g_CBoxManager.m_boxList) {
				pBox->Collider(this);
			}

			m_sx.y += 1;
		}
	}

	//跳跃力为0 就开始下落
	m_sx.curJumpPower--;

	if (m_sx.curJumpPower == 0) {
		m_sx.curAction = H_DOWN;
		m_sx.physicsState = 2;
	}
}
void CMario::Down() {
	// 左右碰撞  重力碰撞
	m_sx.toward = 5;
	if (GetAsyncKeyState('A')) {
		m_sx.toward = 4;
		m_sx.x -= 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x += 1;
		}
	}
	if (GetAsyncKeyState('D')) {
		m_sx.toward = 6;
		m_sx.x += 1;
		if (g_BarrierManager.HeroBarCld(this, m_sx.toward)) {
			m_sx.curAction = H_IDLE;
			m_sx.x -= 1;
		}
	}
	//左右碰撞
	//g_BarrierManager.HeroBarCld(this, m_sx.toward);

	//重力下落 碰撞检测
	m_sx.y += 1;
	if (g_BarrierManager.HeroBarCld(this, 2)) {
		if (m_sx.toward == 4 || m_sx.toward == 6){
			m_sx.curAction = H_MOVE;
			m_sx.y -= 1;
		}
		else {
			m_sx.curAction = H_IDLE;
			m_sx.y -= 1;
		}
			
		m_sx.physicsState = 5;
		return;
	}

}
extern CGameDraw g_gd;
void CMario::Init() {
	//字体库的原因 这里只搞三种图片 根据物理状态来的,上升 下降 水平
	//设置好 main函数里的图素 再来写
	//int x, y;
	//int w, h;
	//int jumpPower;
	//int curJumpPower;

	//int toward; //朝向
	//int physicsState;
	//int curAction;

	m_sx.x = 0;
	m_sx.y = 0;
	m_sx.w = 1;
	m_sx.h = 1;
	m_sx.jumpPower = 3;
	m_sx.curJumpPower = 0;

	m_sx.toward = 5;
	m_sx.physicsState = 2;
	m_sx.curAction = H_DOWN;
	{
		/*BMP bmptemp;
		bmptemp._map = (char*)malloc(sizeof(char) * 1);
		*bmptemp._map = Star;
		bmptemp.h = 1;
		bmptemp.w = 1;*/
		char map[1] = { Star };
		g_gd.AddBmp("groundHero",1,1,map);
	}

	{
		/*BMP bmptemp;
		bmptemp._map = (char*)malloc(sizeof(char) * 1);
		*bmptemp._map = TriangleUp;
		bmptemp.h = 1;
		bmptemp.w = 1;*/
		char map[1] = { TriangleUp };
		g_gd.AddBmp("upHero",1,1, map);
	}

	{
		/*BMP bmptemp;
		bmptemp._map = (char*)malloc(sizeof(char) * 1);
		*bmptemp._map = TriangleDown;
		bmptemp.h = 1;
		bmptemp.w = 1;*/
		char map[1] = { TriangleDown };
		g_gd.AddBmp("downHero", 1,1,map);
	}
	//这里不要释放 AddBmp函数中的 map 创建的时候 是浅拷贝,释放了资源加载不出来。
}
void CMario::Run() {
	//根据当前状态来运行
	switch (m_sx.curAction) {
	case H_IDLE:Idle(); break;
	case H_MOVE:Move(); break;
	case H_UP:Up(); break;
	case H_DOWN:Down(); break;
	}
	
	
	//根据物理状态来切换图片
	if (m_sx.physicsState == 2) {
		m_BMP_nameKey = "downHero";
	}
	else if (m_sx.physicsState == 8) {
		m_BMP_nameKey = "upHero";
	}
	else {
		m_BMP_nameKey = "groundHero";
	}


	//给client赋值 
	g_gd.Draw(m_BMP_nameKey, m_sx.x, m_sx.y);
}

void CMario::End() {//
}
	

Money.h

cpp 复制代码
#pragma once
#include"Item.h"
class CMoney : public CItem {
public:
	void Run();
	void Init();
	void ColliderFun(CHero* hero, int toward);
};
cpp 复制代码
#include"Money.h"
#include"HeroManager.h"
#include"Hero.h"
class CHero;
class HeroManager;

void CMoney::Run() {
	if (m_act == false)
		return;

	g_gd.Draw(m_key, m_x, m_y);


	//吃蘑菇判断
	for (auto pHero : g_CHeroManager.m_HeroList) {
		CMyRect rect = pHero->getRect();
		if (this->GetRect().collider(&rect)) {
			m_act = false;
			g_gd.money++;
		}
	}
}

Mushroom.h

cpp 复制代码
#pragma once
#include"Item.h"

class CMushroom : public CItem {
	int m_toward;
public:
	void Run();
	void Init();
	void ColliderFun(CHero* hero, int toward);
};

Mushroom.cpp

cpp 复制代码
#include "Mushroom.h"
#include "BarrierManager.h"
#include "HeroManager.h"
#include"Barrier.h"
#include"Hero.h"


class HeroManager;

void CMushroom::Run() {
	if(m_act == false)
		return;

	g_gd.Draw(m_key, m_x, m_y);
	
	//吃蘑菇判断
	for (auto pHero : g_CHeroManager.m_HeroList) {
		CMyRect rect = pHero->getRect();
		if (this->GetRect().collider(&rect)) {
			m_act = false;
			pHero->m_sx.jumpPower += 1;
		}
	}

	if (m_toward == 4) {
		m_x -= 1;
		for (auto pBar : g_BarrierManager.m_BarrierList) {
			CMyRect Rect = pBar->getRect();
			if (this->GetRect().collider(&Rect)){
				m_toward = 6;
				m_x += 1;
			}
		}
	}
	else if (m_toward == 6) {
		m_x += 1;
		for (auto pBar : g_BarrierManager.m_BarrierList) {
			CMyRect Rect = pBar->getRect();
			if (this->GetRect().collider(&Rect)) {
				m_toward = 4;
				m_x -= 1;
			}
		}
	}

	m_y += 1;//重力
	for (auto pBar : g_BarrierManager.m_BarrierList) {
		CMyRect Rect = pBar->getRect();
		if (this->GetRect().collider(&Rect)) {
			m_y -= 1;
		}
	}

	//吃蘑菇判断
	for (auto pHero : g_CHeroManager.m_HeroList) {
		CMyRect rect = pHero->getRect();
		if (this->GetRect().collider(&rect)) {
			m_act = false;
			pHero->m_sx.jumpPower += 1;
		}
	}
}


void CMushroom::Init() {
	m_act = true;
	m_toward = 4;
}
//感觉不好用 直接在run里判断就好 
// 以防万一 蘑菇动之前判断一次吃掉没 动之后判断一次吃掉没
void CMushroom::ColliderFun(CHero* hero, int toward)
{
	SX* sx = hero->GetSx();
	sx->jumpPower += 1;
	m_act = false;
}

Pipe.h

cpp 复制代码
#pragma once
#include"Barrier.h"
#include"Hero.h"
#include"GameDraw.h"
#include "Mario.h"
#include "BarrierManager.h"
#include"Wall.h"

class Cpipe : public CBarrier {
public:
	//这里感觉 init 和 构造函数又没啥区别 写一个就行
	//感觉老师喜欢写 init 函数 
	void Run();//调用 gd 绘制图片
	void Init();//没用
	void End();//没用
	void CollierFun(CHero* hero, int fx);

};

Pipe.cpp

cpp 复制代码
#include "Pipe.h"
#include"Hero.h"
#include"GameDraw.h"
#include "Mario.h"
#include"Wall.h"
#include"BarrierManager.h"

void Cpipe::Init()
{
	m_key = 0;
}

void Cpipe::End() {
}

void Cpipe::Run() {
	g_gd.Draw(m_key, m_x, m_y);
}

void Cpipe::CollierFun(CHero* hero, int fx)
{
	SX* sx = hero->GetSx();

	int left = m_x;
	int right = m_x + m_w - 1;
	int top = m_y;
	int bottom = m_y + m_h - 1;

	//这里 因为我们英雄 只有1*1的大小 所以直接用1代替了w h,如果英雄有体积的话,就要用w h来代替
	if (fx == 4) {
		sx->x = right + 1;
	}
	else if (fx == 6) {
		sx->x = left - 1;
	}
	else if (fx == 8) {
		sx->y = bottom + 1;
		
	}
	else if (fx == 2) {
		sx->y = top - 1;
	}
}

Wall.h

cpp 复制代码
#pragma once
#include"Barrier.h"

class Cwall : public CBarrier {
public:
	//这里感觉 init 和 构造函数又没啥区别 写一个就行
	//感觉老师喜欢写 init 函数 
	void Run();//调用 gd 绘制图片
	void Init();//没用
	void End();//没用
	void CollierFun(CHero* hero,int fx);
};

Wall.cpp

cpp 复制代码
#include "Wall.h"
#include"Hero.h"
#include"GameDraw.h"
#include "Mario.h"

void Cwall::Init()
{
	m_key = 0;
}

void Cwall::End() {
}

void Cwall::Run() {
	g_gd.Draw(m_key, m_x, m_y);
}

void Cwall::CollierFun(CHero* hero, int fx)
{
	SX* sx = hero->GetSx();

	int left = m_x;
	int right = m_x + m_w - 1;
	int top = m_y;
	int bottom = m_y + m_h - 1;

	//这里 因为我们英雄 只有1*1的大小 所以直接用1代替了w h,如果英雄有体积的话,就要用w h来代替
	if (fx == 4) {
		sx->x = right + 1;
	}
	else if (fx == 6) {
		sx->x = left - 1;
	}
	else if (fx == 8) {
		sx->y = bottom + 1;
	}
	else if (fx == 2) {
		sx->y = top - 1;
	}
}
相关推荐
今夕资源网10 分钟前
从夯到拉模拟器RankPix windows本地版 exe
windows·exe·从夯到拉·从夯到拉模拟器·rankpix·本地版
kakakahahahaha44 分钟前
Windows系统时间校准指南:time命令、date命令、w32tm /resync与CMOS排查
windows·笔记本电脑·软件需求
一技安身1 小时前
【mysql】Windows MySQL 8.4.10 绿色免安装喂饭教程
windows·mysql·adb
传奇开心果编程2 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
sukalot3 小时前
Windows 驱动实例分析系列:libwdi 驱动分析 - 应用篇(一)
windows·驱动开发
小道士写程序3 小时前
Windows Rust 环境安装指导
开发语言·windows·rust
传奇开心果编程3 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
Tisfy4 小时前
两台旧电脑修复 —— 绕过WinXP密码登录、备份和恢复Win7数据、安装Win10
windows·数据恢复·系统重装
传奇开心果编程4 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
supabc1234 小时前
Celium:连接 Windows、Mac、Linux 与 Android,让远程访问和设备管理更简单
android·linux·windows·macos·远程访问·网络管理·celium