Iphone客户端程序员半年工作总结

2023-05-16

  来公司四个半月了,从对客户端游戏编程的小白慢慢的也能写一些东西了,当然了这里最感谢的人就是九天了,对于九天其它的好我就不说了,就是感觉九天为了团队,为了项目,他在很用心的做每一件事情。就如武侠小说里的人物,有的练习功夫强身健体,有的为了取得江湖地位,有的为了报仇雪恨,当然有很少一部分当做兴趣爱好研究,比如说周伯通,他就是个武痴,对什么功夫都感兴趣。可是这些人里没有一项符合九天的,我认为九天喜欢将事情做的比较完美已经成为一种习惯,无论是代码方面还是说管理方面,处处为大家考虑,为公司考虑。到是他自己的事情考虑的很少,这里我就不举例子了,大家都懂得,:-D。要写总结,就忍不住感谢下九天,来公司这么长时间了,还没感谢过他。

    刚开始接触客户端游戏,我只是本能的处于接受任务,完成任务。由于没有认真仔细的去思考这些任务,犯了很多低级的错误。其实这就是一种不负责任的表现方式,只是把任务当做任务完成了,但并没想这个东西是干什么用的,怎么用?用术语说的话,要实现什么功能,这个功能在什么地方要用?这里举个我第一次接收的一个小任务的例子:实现一个函数,这个函数实现的功能是设置不同语言,来实现多语言加载。当时我也没仔细想,就将这个函数写成了一个全局函数,放在config文件里。config文件是用来存储工程设置还有一些通用的全局变量的东西,我写在这里,一个是设置不方便,在一个也不符合config文件的性质。别看这是一个小小的函数,通过这个函数,程序里实现了不同国家语言的分离,只通过修改材质的后缀名就可以方便的切换不同国家的材质。

const string ConfigManager::GetResourceTextureName( const char* res_name ) {
  std::string full_name(res_name);

  switch (language_) {
    case LAN_EN:
      full_name += "_en.png";
      break;
    case LAN_CN:
      full_name += "_cn.png";
      break;
    case LAN_KR:
      full_name += "_kr.png";
      break;
    case LAN_JP:
      full_name += "_jp.png";
      break;
    default:
      CCAssert(0,"wrong language");
      break;
  }
  return full_name;
}
故事代码1

   第二个比较典型的任务是金币仪表,截图如下:

   

   图片1

    这个刚开始认为比较简单的一个任务,就是说根据当前玩家的分数移动每个位数的数字材质,表现出一个数字。分析下需求大概有以下几点要求:

   1、玩家数据加载时算好每个素材的位置

   2、监测到玩家数据有变化时材质根据数值变化,播放动作

   3、数字变化动作就如滚轮效果,0——9,9——0实现平滑过度

   4、数字不能同是播放所有位数的效果

    刚开始做的时候美术给出的是一个横版的材质,要做出竖版的效果,这可如何是好,经过和九天的讨论得出通过裁剪出每个小的数字材质,然后去控制小的数字材质,这期间遇到了很多问题。刚开始对cocos2d-x动作那套不是太懂,基本就会用个MoveTo(),对ccnode那套也不是很熟,对这些概念都不是很理解。所以每次要表现数字变化时,都先生成一个材质数组,然后算出每个小的材质到目标位置的相对的距离。在动画播放过程中,假如有新的动画,则先将数字变化存放在数组里,当然了一个是先进先出的模型。通过一周的折腾基本功能是实现了,但是效果不是很好,尤其0——9,9——0的突变没有处理好。并且还用的是单间模式,岂不知金币仪表只是ui层的一个功能模块,根本没有必要用单间,所以这个也是对功能没有想清楚。后来经过一周的折腾,发现这种方法太扭曲了,问题很多,经过和lyc,九天的商讨改变了材质,由横条改为竖条,就是这么简单的一改,问题一下简单化了很多,首先我们都知道圆柱面展开后是一个矩形,这样通过竖条的矩形就能很好的实现圆柱的功能,只要简单的在矩形9后面再补个0,就可以了。因为9之后就是0,0之前就是9,为了让动作的连贯性,动作播放完,立马调用setposition将材质设置一个位置。就简单的实现了滚动效果。功能实现了,效果还的慢慢调,游戏不就是要个感觉嘛,通过对动作的时间调整,最后实现了这个功能。回想起来这中间又很多值得学习的地方:

    1、在做任务的时候一定要想清楚功能,心里基本要明白通过什么方式去实现这个功能

    2、将一些常用的算数归纳为数学公式,大大方便运算。

    3、多和自己的同事交流,三人行必有我师,咱们这个团队都是很朴实的技术青年,对每个人的问题都很热心的。

    4、只有通过多做,对这个东西熟悉了,理解了,才能做出如工艺品的东西

    sky项目的加密解密程序还是比较有意思的,这个程序是通过一套叫tea的算法,将程序的配置文件加密成为2进制文件,在程序启动的时候再进行解密。首先来看下加密算法:

    

void TEA::encrypt(const ulong *in, ulong *out) {

	ulong *k = (ulong*)_key;
	register ulong y = in[0];
	register ulong z = in[1];
	register ulong a = k[0];
	register ulong b = k[1];
	register ulong c = k[2];
	register ulong d = k[3];
	register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
	register int round = _round;
	register ulong sum = 0;

	while (round--) {	/* basic cycle start */
		sum += delta;
		y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
		z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
	}	/* end cycle */
	out[0] = y;
	out[1] = z;
}
故事代码2

    在这过程中首先的看懂这个加密函数,由于网上的例子是直接加密解密一个很短的字符串,我就天真的认为加密算法是传入一个char*,然后通过加密传出一个char*,这样就加密好了。导致花了很多时间在查找为什么程序加密不对。再一个字符串都是以‘/0’结尾的,由于对概念理解的不是很清楚,程序总是出现一些比较奇怪的问题。

const string TEA::SaveFile(const char* content)
{
  int file_size = strlen(content);
  byte *plain = new byte[file_size + 1];
  CharToByte((char*)content, plain, file_size);
  byte *new_plain = new byte[file_size*8 + 1];
  int k = 0;
  for (int i = 0; i < file_size; ++i)
  {
    encrypt(plain + i, new_plain + k);
    k += 8;
  }
  char *out = new char[file_size*8 + 1];
  ByteToChar(new_plain, out, file_size * 8);
  string crypt_str(out, file_size * 8);
  delete []plain;
  delete []new_plain;
  delete []out;
  return crypt_str;
}

故事代码3

最后通过做这个功能模块得到三点:

    1、申请内存的时候,要多申请一位,用来存储,结尾符号

    2、读取字符串的时候都是以‘/0’结尾的,所以说对与2进制的数据流用strlen就不对了。

    3、strlen函数其实就是遍历数组每个字符,只到只到'/0'的时候返回遍历次数。

    4、要有勇气和渴望多看看代码,明白了远离问题也就不难了。

    这里大概说说程序里遇到一些问题,以及解决方案,增强自己的自备知识。


1、游戏程序的运行机理

    游戏程序的main函数是一个while函数,只到玩家退出程序,while循环结束

int main()
{
    while(1)
    {
         if(g_run)
         {
              Tick(ts);
              DrawScene();
          }
         else
         {
            break;
          }
     }
    return 0;
}

伪码1
    游戏程序和应用软件最大的区别就是,应用软件一直在等待着用户的输入,来相应用户的请求,而游戏程序就不同了,随着程序时间的配置,游戏通过drawscene不断的去渲染新的画面,说的通俗点就是输出一张张材质。材质本质上就是点的属性集合。比如一个顶点颜色属性颜色函数是通过color(uchar red, uchar green, uchar blue, uchar alpfa)。材质的像素就是来描述顶点数量的变量。像素越高表明材质越细腻。而游戏画面就是通过每秒播放材质的数量来描述的。这就是帧的概念,玩过flash的都懂得,如何通过设置没帧材质来实现简单的动画。说这么多就是要表达,游戏程序就是通过在合适的时间输出不同的材质。注意,我这里说的是游戏程序,而不是游戏。因为游戏是技术,美术,创意,音乐的集合体。就拿猎鸟里宠物馆里一个弹出对话框来说,这个lyc实现的,说个真心话,这一点我非常佩服lyc,他做游戏不是简简单单的去完成任务,而是通过一种审美的意识去看待每个模块的实现。虽说程序不能对整个游戏的整体表现有太大的决定权,但在细节的处理上加上自己的理解和爱,局部还是会非常出彩的。
void PetInfoDialog::Show() {
  this->setScale(0.0f);
  
  CCScaleTo* scale = new CCScaleTo;
  scale->initWithDuration(0.5f,1.0f);

  CCEaseBackOut* ease = new CCEaseBackOut;
  ease->initWithAction(scale);
  scale->release();

  runAction(ease);
  ease->release();
}

void PetInfoDialog::Hide() {
  CCScaleTo* scale = new CCScaleTo;
  scale->initWithDuration(0.5f,0.0f);

  CCEaseBackIn* ease = new CCEaseBackIn;
  ease->initWithAction(scale);
  scale->release();

  CCCallFunc* call_func = new CCCallFunc;
  if(!call_func->initWithTarget(this, callfunc_selector(PetInfoDialog::DestoryCallback) ) ) {
    CCLog("call fun selector wrong");
    return;
  }

  CCSequence* seq = new CCSequence;
  seq->initOneTwo(ease, call_func);
  ease->release();
  call_func->release();

  runAction(seq);
  seq->release();
}
示例代码1

2、内存管理

    学过c/c++的人都知道指针和内存管理是最难理解的,这里我就不详细说明内存管理的话题,只是说说在cocos2d-x里如何管理好自己的内存。

cocos2d-x里的精灵都继承自CCobject类,先看看CCobjec自己申请和释放内存的原理。

CCObject::CCObject(void)
{
	static unsigned int uObjectCount = 0;

	m_uID = ++uObjectCount;

	// when the object is created, the refrence count of it is 1
	m_uReference = 1;
	m_bManaged = false;
}

void CCObject::release(void)
{
	assert(m_uReference > 0);
	--m_uReference;

	if (m_uReference == 0)
	{
		delete this;
	}
}

示例代码2
    再来看看父类,我说的这个父类不是继承关系的父类,而是说装配层次的关系。父类调用addchild发生了什么。
void CCNode::addChild(CCNode *child, int zOrder, int tag)
{	
	CCAssert( child != NULL, "Argument must be non-nil");
	CCAssert( child->m_pParent == NULL, "child already added. It can't be added again");

	if( ! m_pChildren )
	{
		this->childrenAlloc();
	}

	this->insertChild(child, zOrder);

	child->m_nTag = tag;

	child->setParent(this);

	if( m_bIsRunning )
	{
		child->onEnter();
		child->onEnterTransitionDidFinish();
	}
}
void CCNode::insertChild(CCNode* child, int z)
{
    unsigned int index = 0;
    CCNode* a = (CCNode*) m_pChildren->lastObject();
    if (!a || a->getZOrder() <= z)
    {
        m_pChildren->addObject(child);
    }
    else
    {
        CCObject* pObject;
        CCARRAY_FOREACH(m_pChildren, pObject)
        {
            CCNode* pNode = (CCNode*) pObject;
            if ( pNode && (pNode->m_nZOrder > z ))
            {
                m_pChildren->insertObject(child, index);
                break;
            }
            index++;
        }
    }

    child->setZOrder(z);
}

示例代码3
     通过源代码,得到结论如下:
    1、精灵创建时,它的reference加1,relese的时候reference减1。
    2、将精灵安装到父类的时候,父类会调用addobject,这样父类就会使精灵reference数加1,这就意为着精灵的生命周期又它的父类管理了。
    3、如果不能一一对应的使reference的值加1和减1的话就会造成内存泄漏。
    4、从程序里看出,每个sprite只能添加到一个父类上。
3、状态机
void BackgroundAncientLayer::Update(cocos2d::ccTime ts)
{
  if ((torch_num_ < kTorchCount) && (torch_time_ += ts) > 1.0f)
  {
    SetTorchGui();
    torch_time_ = 0;
  }
  switch(state_)
  {
  case STATE_START:
    SetState(STATE_CLOUD_OUT);
    break;
  case STATE_CLOUD_OUT:
#ifdef TARGET_IPHONE
   PlayCloudAciton(ccp(1522.0f * kIphoneScaleFactor, 210.0f * kIphoneScaleFactor), 
     ccp(-420.0f * kIphoneScaleFactor, 850.0f * kIphoneScaleFactor), 80.0f, 15.0f);  
#else
   PlayCloudAciton(ccp(1707.0f, 0), ccp(-568.0f, 895.0f), 80.0f, 15.0f);  
#endif
   SetState(STATE_END);
  case STATE_END:
    break;
  default:
    break;
  }
}

示例代码4
    通过状态来标记程序运行的不同阶段,有以下几点好处:
    1、思路比较清晰,在本例子中,很清晰的表明了要干的事情,这个例子比较简单,遇到复杂的状态很大程度上可以降低程序的出错率。
    2、可以很容易的跳跃到不同的状态上。

4、简单的设计模式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Iphone客户端程序员半年工作总结 的相关文章

  • 写给我的2013

    前沿 xff1a 代码看的累了 xff0c 在新的一年终于可以找点时间来回忆我的2013 想着要写点什么 xff0c 可是又没有什么可以写 因为回忆无非就是夹杂着些许痛苦与欢乐 写给我的2013 家 生活 xff1a 2013年 xff0c
  • 写给我的2014——也写给我即将逝去的研究生生涯

    前言 xff1a 2014 1在写着代码的时写下了回忆 xff0c 2015 1在码着论文的时候开始写起消逝的2014 细细回忆 xff0c 真是又是那句老话 xff0c 时间过得真快 xff0c 1年过去了 xff1b 更快的是竟然都要毕
  • Oracle官网下载历史版本软件

    一 分享一个Oracle官网下载各种软件的网址 https edelivery oracle com osdc faces SoftwareDelivery 这个网址是Oracle官网专门下载软件的地址 xff0c 下载软件过程如下 xff
  • 技术盘点:消息中间件的过去、现在和未来

    作者介绍 xff1a 林清山 xff08 花名 xff1a 隆基 xff09 操作系统 数据库 中间件是基础软件的三驾马车 xff0c 而消息队列属于最经典的中间件之一 xff0c 已经有30多年的历史 其发展主要经历了以下几个阶段 xff
  • C语言小游戏——扫雷

    上次我们用C语言实现了一个三子棋的小游戏 xff0c 这次我们同样使用C语言来实现扫雷这个经典的小游戏 首先 xff0c 在开始编程之前还是先整理一下我们的编程思路 xff1a 一 菜单打印 xff1a 和上次实现三子棋的操作类型 xff0
  • 缺省参数讲解

    缺省参数 缺省参数定义缺省参数分类1 全缺省参数 xff1a 2 半缺省参数 xff1a 注意事项 缺省参数定义 缺省参数作为C 43 43 不同于C语言新增的一种语法功能 xff0c 他的作用是在声明或定义函数时为参数指定的一个默认值 x
  • Linux下的权限

    Linux下的权限 用户分类文件类型具体文件类型 基本权限root用户 xff1a 修改权限使用方法 xff1a 通过8进制数字更改权限 对于文件 xff0c 权限的意义读权限写权限运行权限 对于目录权限的意义 更改文件拥有者 所属组cho
  • 类和对象初识

    类和对象初识 类的由来类的定义类的特性封装访问限定符 类的定义方法声明和定义全部放在类体中声明放在 h文件中 xff0c 类的定义放在 cpp文件中类对象的大小 内存对齐规则 类的由来 在C语言中我们有自定义类型的struct xff0c
  • 类的默认成员函数——上

    类的默认成员函数 默认成员函数构造函数构造函数由来构造函数特征默认构造函数特征总结 xff1a 析构函数特征 拷贝构造默认拷贝构造总结 C 43 43 中如果一个类中什么成员都没有 xff0c 简称为为空类 空类中什么都没有吗 xff1f
  • 进程控制块

    进程控制模块 查看进程PCB内部构成标识符ppid 状态优先级查看优先级方式优先级确定原理调整优先级nice值范围 程序计数器内存指针上下文数据时间片上下文数据 I xff0f O状态信息记账信息 查看进程信息 进程 xff1a 加载到内存
  • 模拟实现stack/queue

    模拟实现stack queue stack大体框架接口函数实现 queue大体框架接口函数 stack 之前的博客中介绍了栈和队列的相关功能 xff0c 这里我们模拟实现一个栈和队列 大体框架 由于栈的特殊性 xff0c 栈不支持迭代器访问
  • 进程间通信——命名管道

    命名管道 命名管道定义命名管道创建命令行上创建程序内创建 命名管道间通信匿名管道和命名管道区别 命名管道定义 上一篇博客中介绍了匿名管道的用法以及他的特点 xff0c 但是它存在一定的限制 xff0c 例如他只能在两个具有公共祖先的进程间进
  • Altium Designer一些好用的系统设置

    AD软件系统设置 系统参数设置GeneralNavigationDesign InsightFile Types 原理图参数设置GeneralCross Overs位号自动增加设置原理图大小设置 Graphical Editing单一 39
  • 哈希——开散列

    哈希 开散列 开散列概念开散列的简单实现HashFunc开散列的构成插入去重扩容插入 测试 开散列概念 上一篇博客中介绍了解决哈希冲突的一种方法 xff1a 闭散列 但是闭散列中不管是线性探测还是二次探测 xff0c 解决哈希冲突问题都不够
  • 开发者七问七答:什么是产品化?

    简介 xff1a 之前参加了企业智能部门如何做产品化的讨论 xff0c 大家对产品化的定义和过程都有各自不同的见解 我觉得这个话题其实可以扩展下 xff0c 想站在一个开发人员的视角尝试探讨一下产品化 下面以自问自答的方式来展开 1 当我们
  • 用哈希简单封装unordered_map和unordered_set

    哈希表的改造 哈希表的改造unordered map和unordered set的基本结构哈希表改造节点结构体迭代器哈希表改造 unordered map和unordered set封装unordered map封装以及测试代码unorde
  • 位图的基本原理以及应用

    位图 位图的应用场景位图的基本概念位图 位图的应用场景 假设生活中有以下这种应用场景 xff1a 有未排序的40亿个数 xff0c 需要在其中查找一个数字是否存在 如果直接使用数组来存放这些数 xff0c 那么一个整型的数占4个字节 xff
  • Retrofit 结合 Lifecycle, 将 Http 生命周期管理到极致

    code小生 一个专注 Android 领域的技术平台 公众号回复 Android 加入我的安卓技术群 作者 xff1a xcheng 链接 xff1a https www jianshu com p 07fe489a53f2声明 xff1
  • 实践App内存优化:如何有序地做内存分析与优化

    code小生 一个专注Android领域的技术平台 作者 xff1a 舒大飞 地址 xff1a https www jianshu com p f3e8c34d0803 声明 xff1a 本文已获 舒大飞 授权 xff0c 转发等请联系原作
  • Android 面试题集(2019-04-04总结)

    作者 xff1a ClAndEllen 链接 xff1a https www jianshu com p 98255550b41e 一份Android面试题集 xff0c 适应于实习 amp 初级工程师 amp 中级工程师 xff0c 高级

随机推荐

  • 虚拟主机和服务器之间的区别

    很多人都容易将云服务器与虚拟主机混为一谈 xff0c 大致因为他们性能及安全性方便有不少相似的地方 xff0c 那么云服务器与虚拟主机究竟有哪些明显区别呢 xff1f 概念区分 xff1a 云服务器是一种简单高效 安全可靠 处理能力可弹性伸
  • MySQL编码详解及中文乱码问题解决方案

    最近 xff0c 在项目组使用的MySQL数据库中 xff0c 插入数据出现乱码问题 xff0c 出现诸如 或者 等字符 为了防止在 今后项目中再次出现相类似问题 在这里对于MySQL编码问题做 一个详细的介绍并对于乱码问题提出一些解决方案
  • XCOM V2.6 串口打印出来中文乱码,字体格式错乱的一种原因(设置没问题,突然乱码)

    一 问题重现 XCOM V2 6里 xff0c 完全一样的设置 xff0c 之前显示的好好的 xff0c 后来突然中文出现乱码 xff0c 字体格式也大变 xff0c 如下图 xff1a 二 解决方案 一般这种乱码 xff0c 往往都是因为
  • 生产者与消费者模型

    1 三种关系 1 生产者和生产者互斥关系 2 消费者和消费者互斥关系 3 生产者和消费者同步互斥关系 2 生产者和消费者模型 生产者消费者模型就是通过一个容器来来解决强耦合问题的 耦合 xff1a 2个或2个以上事物相互作用 xff0c 相
  • Windows server 2016基本设置

    windows server 2016相比较而言具有更加稳定的特性 xff0c 但不免有些繁琐 xff0c 可以通过一些设置可以使其更加易用 一 组策略 WIN键 43 R键 xff0c 输入gpedit msc xff0c 进入组策略设置
  • 收藏 | 阿里程序员常用的 15 款开发者工具(2020 版)

    简介 xff1a 本文精选了一些阿里经济体内部最受开发者欢迎的开发者工具 xff0c 筛选出一些带有普适性同样适合外部开发者的 xff0c 希望能助力开发者们提高开发效率 来源 阿里巴巴云原生公众号 本文精选了一些阿里经济体内部最受开发者欢
  • root登录卡在tty,登入root

    ubuntu桌面使用root直接登录的方法 Linux系统下文件的权限十分重要 xff0c 大多数操作都需要一定的权限才可以操作 xff0c Ubuntu18 04默认安装是没有设置root账户的 xff0c 因此想要获得root账户登录可
  • 使用Python做一个语音播报温湿度系统,元气满满的一天从听到他开始

    来这里发现更多有趣案例 HaaS开发框架 HaaS积木方案 xff0c 赋能生态开发者 xff0c 让您快速找到自己需要的解决方案 xff0c 硬件主板与外设 xff0c 以及各种应用组件 https haas iot aliyun com
  • 基于MVC模式实现用户注册和登录功能

    目录 1 实验简介2 具体细节分析3 实验工具4 整体框架截图5 代码实现1 login jsp2 ok jsp3 register jsp4 list jsp5 edit jsp6 DBConn java7 User java8 User
  • 十大远程控制软件(远程控制软件推荐)

    远程控制软件可以跨空间的操控对方电脑 xff0c 被广泛用于远程办公 远程教育 远程指挥 远程协助 远程维护 xff0c 已成为电脑必备应用 xff1b 那么纵观全网 xff0c 有哪些好用的远程软件 xff1f 这些远程控制软件有什么优势
  • 程序员永远的痛之字符编码的奥秘

    字符编码相信是每个程序员的噩梦 xff0c 只要是有中文的地方 xff0c 总是会遇到各种编码的问题 xff0c 并且这种问题还非常难缠 xff0c 尤其在linux上 xff0c 因为上面很多软件都是针对英语国家开发的 xff0c 是不会
  • C++11 之for 新解

    前言 C 43 43 11这次的更新带来了令很多C 43 43 程序员期待已久的for range循环 xff0c 每次看到javascript xff0c lua里的for range xff0c 心想要是C 43 43 能有多好 xff
  • c++11之初始化列表

    一 前言 C 43 43 的学习中 xff0c 我想每个人都被变量定义和申明折磨过 xff0c 比如我在大学笔试过的几家公司 xff0c 都考察了const和变量 xff0c 类型的不同排列组合 xff0c 让你区别有啥不同 反正在学习C
  • Unity Update 详解

    0x01 简介 Unity的脚本继承了Monobehaviour类 xff0c 在脚本中定义函数 xff1a void FixedUpdate span class hljs list span void span class hljs k
  • 2016总结

    欲言又止 xff1a 每年的年终总结是要在新年之前发表在博客上 xff0c 今年的年终总结拖到现在完成 xff0c 我也是服自己 这里要感谢我的高中好友 64 万学清同学 xff0c 在我去年微信发表的有关年终总结的朋友圈下 xff0c 催
  • 阅读代码和修改别人代码的一些技巧以及注意事项

    作为刚刚走上工作岗位的fish xff0c 都要熟悉前辈们留下来的代码 这段时间是fish最痛苦的时间同时也是最轻松的时间 痛苦是因为要看大量的代码 xff0c 同时要慢慢从学生到社会人士的转变 xff08 xff0c 再不能睡懒觉了 xf
  • ESP32控制TDC-GP22测量超声传播时间(超声流量计)

    TDC GP22控制的资料 xff0c 网上的资源都是基于STM32或者MSP430主控的 xff0c 但现在这两款芯片都太贵了 xff0c 因此就想用便宜点的ESP32 xff0c 折腾了快一周 xff0c 终于弄好了 工程源码和参考资料
  • WIN10远程连接WIN10报错:你的凭据不工作

    很多用户在升级到win10系统之后 xff0c 连接远程桌面功能的时候遇到这样一个错误 xff0c 就是远程桌面提示 你的凭据不工作 xff0c 导致无法连接远程桌面 xff0c 该怎么解决呢 xff0c 下面为大家讲解一下Win10无法连
  • 一个分号引发的血案

    最近在看 Data Structures and Algorithms 这本书 xff0c 书里对数据结构和算法进行了简单的描述 xff0c 并且用伪码进行了实现 伪码毕竟和代码还是有很大不同的 xff0c 书的说明里说有C 写的源码 xf
  • Iphone客户端程序员半年工作总结

    来公司四个半月了 xff0c 从对客户端游戏编程的小白慢慢的也能写一些东西了 xff0c 当然了这里最感谢的人就是九天了 xff0c 对于九天其它的好我就不说了 xff0c 就是感觉九天为了团队 xff0c 为了项目 xff0c 他在很用心