第一课Bresenham直线绘制算法

Reference

Lesson 1: Bresenham’s Line Drawing Algorithm · ssloy/tinyrenderer Wiki (github.com)
从零构建光栅器,tinyrenderer笔记(上) - 知乎 (zhihu.com)

课前准备

model.cpp model.h tgaimage.cpp tgaimage.h geometry.h 从第一课的代码快照(WIKI中的here)中找到并且复制到一个空的C++项目中。

开始上课

现在,掠过一遍老师的代码,我们可以发现,本课程的渲染是画在一张TGA图片中。

并且可以知道如何创建一张TGA图片:

1
TGAImage* image = new TGAImage(800, 800, TGAImage::RGB);

Read More

CSharp的协程实现与原理

Reference

【迭代器模式】深入理解协程 - 知乎 (zhihu.com)
Unity协程的原理与应用 - 知乎 (zhihu.com)
[C#进阶]C#实现类似Unity的协程 - 知乎 (zhihu.com)

概述

引用自:Unity协程的原理与应用 - 知乎 (zhihu.com)

函数调用的本质是压栈,协程的唤醒也一样,调用IEnumerator.MoveNext()时会把协程方法体压入当前的函数调用栈中执行,运行到yield return后再弹栈。

Read More

简单常规图形的碰撞检测

Reference

[算法][包围盒]球,AABB,OBB - 南水之源 - 博客园 (cnblogs.com)

碰撞检测算法之分离轴定理 - 知乎 (zhihu.com)
Separating Axis Theorem (SAT) Explanation – sevenson.com.au — 分离轴定理 (SAT) 解释 – sevenson.com.au

圆 * 圆

圆与圆的碰撞检查,只需要检查两个圆心的距离和两个圆半径和的关系,用分离轴算法相当于两个圆心在xy任意坐标轴上的投影坐标,再加减各自半径,得出两个圆各自投影线段的最大点和最小点,进行线段相交判断。

常规矩形 * 常规矩形(AABB,axis-aligned bounding box,即轴对其包围盒)

只需要检查两个矩形各自的长度坐标表范围宽度坐标范围是否同时有相交,用分离轴算法相当于就是在这判断投影相交,而且因为矩形对边平行的原因,每个矩形只需要检查两条轴。

Read More

实现物理引擎的网络同步方案

Reference

浅谈物理引擎的网络同步方案 - 知乎 (zhihu.com)
【火箭联盟物理系统、网络同步讲解(含字幕)】It IS Rocket Science!The Physics of Rocket League Detailed_哔哩哔哩_bilibili
网络同步在游戏历史中的发展变化(五)—— 物理同步 - GameRes游资网

Unity可确定性定点数(软浮点)物理引擎 - JeasonBoy - 博客园 (cnblogs.com)
Unity基于定点数的3D物理系统,可以用于帧同步 - 知乎 (zhihu.com)

图形学物理模拟领域资源整理 - 知乎 (zhihu.com)

好烦,让Unity物理引擎根据给定的Delta来Tick无法做到,只能实现一个简易的物理引擎来做,或者实现一个简易的碰撞检测系统。

Read More

浅入浅出帧同步

Reference

六:帧同步联机战斗(预测,快照,回滚) - 知乎 (zhihu.com)

关于帧同步的想法(预测和回退) - 知乎 (zhihu.com)

Deterministic Lockstep | Gaffer On Games — 确定性锁步 |灯光师谈游戏

帧同步优化难点及解决方案 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 (uwa4d.com) 这一篇是写的最好的

云风的 BLOG: lockstep 网络游戏同步方案 (codingnow.com)

Read More

转载-帧锁定同步算法

教程出自帧锁定同步算法
大佬的思想让我叹为观止
今日膜拜skywind大佬,并开始写一个帧同步的Demo
顺带把评论也copy下来了(●’◡’●)

帧锁定算法解决游戏同步

早期 RTS,XBOX360 LIVE游戏常用同步策略是什么?格斗游戏多人联机如何保证流畅性和一致性?如何才能像单机游戏一样编写网游?敬请观看《帧锁定同步算法》

Read More

TCP网络通信框架的讲解与使用

客户端

1.消息基类BaseMessage

在消息基类中定义了得到消息ID消息长度的函数,以便于我们后续解析消息,处理分包与粘包。

派生类BaseMessage<T>

这个类的T泛型被约束为Google.Protobuf.IMessage,是Protobuf的基本消息类型,我们的BaseMessage<T>中保存着一个dataT类型用于承载数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public abstract class BaseMessage
{
public abstract int GetByteLength();

public abstract byte[] GetBytes();

public abstract int GetMessageID();

public abstract void WriteIn(byte[] buffer, int beginIndex,int length);
}

public abstract class BaseMessage<T> : BaseMessage where T : Google.Protobuf.IMessage,new()
{
public T data = new T();

public override int GetByteLength()
{
return 8 + (data == null ? 0 : data.CalculateSize());
}

public override byte[] GetBytes()
{
byte[] buffer = new byte[GetByteLength()];
BitConverter.GetBytes(GetMessageID()).CopyTo(buffer, 0);
BitConverter.GetBytes(GetByteLength()).CopyTo(buffer, 4);
if (buffer.Length > 8)
data.ToByteArray().CopyTo(buffer, 8);
return buffer;
}

public override int GetMessageID()
{
throw new NotImplementedException();
}

public override void WriteIn(byte[] buffer, int beginIndex,int length)
{
throw new NotImplementedException();
}
}

2.NetAsyncMgr网络管理器

这个类的作用是用来建立对服务器的TCP连接。

Read More

编程感悟

写简单的代码而不追求性能

很多能力都重要,近两年我认为,比较重要的能力是抓住问题的本质。就是可以用足够简单的方法去解决根源问题,抛开中间的一些枝节干扰。

为什么我会强调用简单的方法?Keep it Simple and Stupid,即KISS原则。在20年前,我不完全理解这个道理,比如,我在大学期间以及刚毕业的时候,比较喜欢做程序的优化,让自己写的代码比别人写的代码跑得快。很多年轻程序员和我一样,都喜欢炫技。但我现在看来,这些事不是解决问题的本质。这与把事情做简单有什么关系?以前我认为写出复杂的程序并且不出错是一种出色的能力,可随着时间的推移,我的代码需要被别人维护,可能还要和其他人合作,这时我们需要在这群人之间找到一个共同的基点,让代码更容易理解。所以我们需要让代码足够简单,让别人一看就明白。什么样的代码是好代码?并不是看上去好像没有问题的代码,而是看上去所有东西都清清楚楚,断定它肯定不会出问题的代码。

最近几年,我写程序很少炫技。炫技在短时间内看,是用一个很巧妙的方法把问题解决掉了,但经不起时间的检验。把复杂的问题简单化,对程序员而言是一项非常重要的能力。
—–云风

Read More