当前位置: 首页 > news >正文

堆 动态内存 超级玛丽demo7

之前我们加入了BMP 里面有个量

 

这里我们 最开始写的400感觉有点大 写了100,假如我们的地图很大 10000往上,要画一个地面,那就完蛋了,BMP 要10000*10000,定义其他东西的时候 比如一个坦克 才3*3.

这时候堆就帮我们解决问题了。

终于学到堆了 前面提到了无数次 填坑了也算是,这玩意大一新手村大部分人还真就 只知道 勉强能看懂 不怎么用。

动态 静态 热 冷

运行时可以改变大小叫做热 或者 叫动态

运行时候不能改变   叫做  冷 或者 静态

我们总听说 热更新 动态内存 等词汇 就是这样来的

热更新

其实很早以前 我们玩的游戏 还可以冷更新

自己从官网 去 下载更新包放在指定位置

现在冷跟新 基本上 都是先打开游戏 然后提示你 有新版本可以更新,甚至可以一边运行一边更新,甚至一边玩一边更新。

以后我们汇重点学习 热更新知识,才开始填 堆 的坑,又挖一个新坑位。

用多少内存  开多少内存。

假如我们想定义一个 int buf[999999999999999999999]

肯定报错!!!


数组的内存在栈区,这个区域只有1MB,而且公用。

但是这里的公用 是每个线程都有 1MB

堆理论无限大小 只有内存 的物理大小限制。

malloc

这玩意 大一新手村天天用,当时书上写的是动态内存  其实就是堆内存。

int a;

int *p;

p = (int*)malloc(a);

a代表 字节个数 新手村的时候 书上写的是  个数*sizeof()

开辟了 a个字节 但是不知道是什么类型的数据,默认为void*

强转 计算机在识别内存的时候 才会按四字节 读取 然后 把2进制 按照整数的规则处理

[]的作用   数组的名字其实存放的是首地址  a[10]

a[0]  就是跳0次 然后 解引用

这就比 (*) 多了一个跳字节的功能

这里我们 malloc开内存的时候

int len;

int *p = (int*)malloc(sizeof(int)*len);

free(p);

配合刚刚我们说的 就可以

p[0] p[1] p[2] 直接访问了 

非常方便

free

释放地址中 开辟的所有内存 然后指针存的地址为空

指针的作用 随着 多态 函数 堆 的学习 含金量一直上升 这就是c++的魅力

记住 堆内存用多少开多少 不能开100个字节 只用50字节。

free的时候是全部释放,不用完也会浪费。

内存泄漏  100字节 在程序中再也用不了了。

土话 叫这个堆为 野堆

内存

大部分人大一新手村的时候这玩意就大概知道 没搞明白过

                         生命周期        读       写                特点

栈          定义---函数结束        可读    可写           1mb

堆         malloc---free             可读    可写            理论上无线大,理论上永久存在

 

常量                                        只读不可写          

         

静态   程序开始--程序结束      可读可                   永久性内存 直到程序结束之后才释放

栈内存 和 静态内存  

常量

下面代码哪里出错了?

p是形参,要二级指针 才能操作a

指令内存区   储存函数命令(代码)

下面这个代码有两个指令

没有被接收的变量 就是在缓存中 不在内存中

有了堆 我们就可以改进之前的 struct BMP  

之前那里的_map 放一个 char* 用来放 一个malloc 出来的地址就可以了。

还有一个可以改进的地方,因为在真实的游戏开发中 这个BMP资源有时候分辨率高,开销很大

以这里为例子,我们定义一个 坦克 图标 来当作我们的英雄

每次我们在 添加 使用AddBmp的时候 就是直接把这个 东西直接传进去 ,虽然我们使用了{}来释放了这个资源,但是函数中 编译又会重新在函数中创建一个 BMP的形参,来操作 然后函数里面

又有函数  insert 来弄这个Bmp 当作形参,导致一个图片要造成好几次的 内存开销。

我们可以 直接传入这个堆内存的 地址,这样每次都只 增加四字节的开销。

这里有点把我自己绕晕了

在 map中放数据的时候 进行的是解引用,意思是已经解引用存储在了 map中 才释放我们在 main函数定义的临时变量map。

而节约内存开销 我倒是理解对了,豆包是这样回答我的:

ai真的太厉害了!!!!有了ai之后 真的是学习编程的超级利器!!!!

有了堆之后 我们直接铺上地面 当作图片 搞个大图

项目源码:

MyRect.h

#pragma oncestruct MYRECT {int left, top, right, bottom;bool Sollider(const MYRECT& other);bool Set(int x, int y, int w, int h);
};

MyRect.cpp

#include "MyRect.h"bool MYRECT::Sollider(const MYRECT& other)
{if(right < other.left || left > other.right || bottom < other.top || top > other.bottom)return false;return true;
}bool MYRECT::Set(int x, int y, int w, int h)
{left = x;top = y;right = x + w - 1;bottom = y + h -1;return true;
}

GameDraw.h

#pragma once
#include <map>
using namespace std;struct BMP {int w, h;char* _map;
};struct GameDraw {int _max_w,_max_h;int _w, _h;int client[32 * 256];char print[(15 * 2 + 1)*16 +1];char _ts[128];int _tslen;int ww = 70, wh = 16;int cx = 0, cy = 0, cw = 15, ch = 16;map<const char*, BMP> bmp_map;void init();//初始化各个数据bool SetTs(const char* ts);//设置图素bool SetSize(int w, int h);//设置窗口大小void Begin();//把窗口大小中的client清零void Draw(const char* key,int x,int y);//给client 编码画图void End();//把client中的数据显示到窗口上bool AddBmp(const char* key,const BMP* bmp);
};

GameDraw.cpp

#include "GameDraw.h"
#include <iostream>
#include <map>void GameDraw::init()
{_max_w = 256;_max_h = 32;_ts[0] = "  "[0];_ts[1] = "  "[1];_tslen = 0;
}bool GameDraw::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;
}bool GameDraw::SetSize(int w, int h)
{if (w<1 || h<1 || w> _max_w || h> _max_h) {return false;}_w = w;_h = h;return true;
}void GameDraw::Begin()
{for (int i = 0; i < _h; i++) {for (int j = 0; j < _w; j++) {client[i * _w + j] =  0;}}
}void GameDraw::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 * _w + x] = bmp._map[j + i * bmp.w];x++;}y++;x -= bmp.w;}
}void GameDraw::End()
{int pos = cx + cy * _w;int size = 0;for (int i = 0; i < ch; i++) {for (int j = 0; j < cw; j++) {if (client[pos + i * _w + j] == 0) {print[size++] = _ts[client[pos + i * _w + j] ];}else {print[size++] = _ts[client[pos + i * _w + j] * 2];print[size++] = _ts[client[pos + i * _w + j] * 2 + 1];}}print[size++] = '\n';}print[size] = 0;system("cls");std::cout << print;
}bool GameDraw::AddBmp(const char* key,const BMP* bmp)
{if (key == nullptr) return false;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;}elsereturn true;
}

源.cpp

#include <iostream>
#include"GameDraw.h"
#include<windows.h>using namespace std;struct OBJ {int  x, y;/*int tsi;*/const char* key;
};void main() {GameDraw gd;OBJ hero = {0,0,"tank"};{BMP bmp_temp;bmp_temp.w = 3;bmp_temp.h = 3;int temp_map[9] = {0,2,0,5,4,5,5,0,5,};bmp_temp._map = (char*)malloc(sizeof(char) * 9);for (int i = 0; i < 9; i++) {bmp_temp._map[i] = temp_map[i];}gd.AddBmp("tank", &bmp_temp);}{BMP bmp_temp;bmp_temp.w = 4;bmp_temp.h = 5;int temp_map[20] = {5,5,5,5,5,5,5,5,0,5,5,0,0,5,5,0,0,5,5,0,};bmp_temp._map = (char*)malloc(sizeof(char) * 20);for (int i = 0; i < 20; i++) {bmp_temp._map[i] = temp_map[i];}gd.AddBmp("pipe", &bmp_temp);/*free(bmp_temp._map);bmp_temp._map = NULL;*/}{BMP bmp_temp;bmp_temp.w = 70;bmp_temp.h = 2;int temp_map[140];for (int i = 0; i < bmp_temp.h; i++) {for (int j = 0; j < bmp_temp.w; j++) {if((i * bmp_temp.w + j)%2 == 0)temp_map[i*bmp_temp.w + j] = 5;elsetemp_map[i*bmp_temp.w + j] = 4;}}bmp_temp._map = (char*)malloc(sizeof(char) * 140);for (int i = 0; i < 140; i++) {bmp_temp._map[i] = temp_map[i];}gd.AddBmp("ground", &bmp_temp);}/*OBJ hero = { 0,0,1,1,3 };OBJ ground = { 0,15,70,1,5 };OBJ brick1 = { 11,5,4,2,5 };OBJ brick2 = { 24,6,4,9,5 };*/while (1) {gd.init();gd.SetSize(70,16);gd.Begin();gd.SetTs("〓▲★●■");gd.Draw("tank",hero.x,hero.y);for (int i = 1; i <= 3; i++) {gd.Draw("pipe",i*20,9);}gd.Draw("ground",0,14);/*gd.Draw(hero.x, hero.y, hero.w, hero.h, hero.tsi);gd.Draw(ground.x, ground.y, ground.w, ground.h, ground.tsi);gd.Draw(brick1.x, brick1.y, brick1.w, brick1.h, brick1.tsi);gd.Draw(brick2.x, brick2.y, brick2.w, brick2.h, brick2.tsi);*/Sleep(30);gd.End();if (GetAsyncKeyState('W')) {hero.y -= 1;}if (GetAsyncKeyState('S')) {hero.y += 1;}if (GetAsyncKeyState('A')) {hero.x -= 1;}if (GetAsyncKeyState('D')) {hero.x += 1;}//卷轴gd.cx = hero.x - gd.cw/2;gd.cy = hero.y - gd.ch/2;if (gd.cx < 0) gd.cx = 0;if (gd.cy < 0) gd.cy = 0;if (gd.cx + gd.cw > gd.ww) gd.cx = gd.ww - gd.cw;if (gd.cy + gd.ch > gd.wh) gd.cy = gd.wh - gd.ch;}Sleep(30);
}

http://www.dtcms.com/a/420128.html

相关文章:

  • 空壳网站查询WordPress下拉菜单栏
  • 《高并发架构实战课》学习笔记
  • 网站备案 人工审核平面设计需要用到的软件
  • 网站301跳转怎么做的安阳市网站建设
  • 参考资料:Linux系统U盘拔出识别慢问题
  • 银川公司网站建设广州万安建设监理有限公司网站
  • 专业做鞋子网站苏州网站建设2万起
  • 19软件测试用例设计编写测试点-连接数据库服务器
  • 嵌入式科普(41)通过对比深刻理解CAN总线协议特性
  • 外综服网站开发专业设计网站公司
  • excel数据处理
  • 淄博网站建设 招聘对外贸易网站有哪些
  • 数据结构_ 二叉树线索化:从原理到手撕实现
  • 分享一个知识工程师单体智能体的简单提示词
  • 南宁伯才网络建站如何WordPress一键采集插件
  • 免费三网合一网站系统网站建设介绍书
  • 网站开发公司起名10分钟快速建网站
  • flink批处理-时间和窗口
  • 无锡有什么网站怎样免费注册个人网网址
  • SLAM | SLAM中松耦合与紧耦合技术对比分析
  • xtuoj 方程组
  • 重庆网站设计建设东莞微联建站
  • 北京医疗网站建设公司排名网站建设开票项目是什么
  • C#——方法的定义、调用与调试
  • 开源的容器化平台:Docker入门与核心概念解析
  • 手机网站价格小广告网页
  • 晋城市建设局网站国内编程培训机构排名
  • 08 线性回归 + 基础优化算法【动手学深度学习v2】
  • 创新为擎,绿色为基:新天力科技引领食品容器行业高质量发展新征程
  • 从 GDPR 到 ROI:一次评透海外影音数据抓取的合规与性价比