typescript工程

Chapter III in the series of tutorials on how to build a game from scratch with TypeScript and native browser APIs

本系列教程的第三章,介绍如何使用TypeScript和本机浏览器API从头开始构建游戏

Hello there, and welcome back! This is the series of articles where we discuss how to build a simple turn-based game with TypeScript and native browser APIs! Chapter III is dedicated to building a grid for this game, other Chapters are available here:

您好,欢迎回来! 这是系列文章,我们讨论如何使用TypeScript和本机浏览器API构建简单的回合制游戏! 第三章致力于为该游戏构建网格,其他章节也可以在此处找到:

  • Introduction

    介绍

  • Chapter I. Entity Component System

    第一章实体组件系统

  • Chapter II. Game loop (Part 1, Part 2)

    第二章 游戏循环( 第1 部分 , 第2部分 )

  • Chapter III. Drawing Grid (Part 1, Part 2, Part 3, Part 4, Part 5)

    第三章 工程图网格( 第1部分 ,第2部分,第3部分,第4部分,第5部分)

  • Chapter IV. Drawing ships第四章 绘图船
  • Chapter V. Interaction System第五章互动系统
  • Chapter VI. Pathfinding第六章 寻找路径
  • Chapter VII. Moving ship第七章 搬船
  • Chapter VIII. State Machina第八章 国家机械工业
  • Chapter IX. Attack System: Health and Damage第九章 攻击系统:生命与伤害
  • Chapter X. Winning and Losing the Game第十章。输赢
  • Chapter XI. Enemy AI第十一章 敌人AI

In the first part of this chapter, we successfully drew the grid. Canvas API was in great help for us then. However, the solution was rather dirty and not flexible. We simply put all the code into the single place: Game Entity. If we continue going this path, soon enough, our game script becomes enormously large and hard to maintain. Moreover, we wrote no tests last time, leaving ourselves without any insurance. In this post, we are going to improve our code and make it more maintainable and extendable.

在本章的第一部分中,我们成功绘制了网格。 那时,Canvas API对我们有很大帮助。 但是,该解决方案相当脏,而且不灵活。 我们只需将所有代码放在一个位置: Game实体。 如果我们继续走这条路,很快,我们的游戏脚本将变得非常庞大且难以维护。 此外,我们上次没有编写测试,因此没有任何保险。 在本文中,我们将改进代码,使其更易于维护和扩展。

There is something else we have to think about, aside from the code quality. At this point, all we did is drew a static image of the Grid. It has no functionality what’s so ever. In fact, the only dynamic part of the grid now is its size and color. But as we’ll see in future Chapters, Grid is much more than just an image. It is a vital part of the gameplay, and we need it to be ready to fulfill our growing needs. The Grid should become an Entity.

除了代码质量,我们还有其他需要考虑的问题。 至此,我们所做的只是绘制了 Grid 的静态图像 。 它没有任何功能。 实际上,网格的唯一动态部分就是它的大小和颜色。 但是,正如我们将在以后的章节中看到的那样,Grid不仅仅是一个图像。 这是游戏玩法中至关重要的一部分,我们需要它做好准备以满足不断增长的需求。 网格应成为实体。

Feel free to switch to the drawing-grid-1 branch of the repository. It contains the working result of the previous posts and is a great starting point for this one.

随时切换到存储库的drawing-grid-1分支。 它包含了以前的帖子的工作结果,是此帖子的一个很好的起点。

目录 (Table of Contents)

  1. The Grid Entity网格实体
  2. Testing Game Entity with the Grid用网格测试游戏实体
  3. Introducing Node Entity节点实体介绍
  4. Writing our First Component编写我们的第一个组件
  5. Testing Node Entity测试节点实体
  6. Conclusion结论

网格实体 (The Grid Entity)

Background vector created by pikisuperstar由pikisuperstar创建的背景矢量

We coupled the grid code with the game entity. While the grid is indeed important for the game, it doesn’t mean they have to live together. It is time for us to define our very first child entity:

我们将网格代码与游戏实体结合在一起。 尽管网格对于游戏确实很重要,但这并不意味着它们必须生活在一起。 现在是时候定义我们的第一个子实体了:

// src/grid/grid.ts
import { Entity } from '@/utils'export class Grid extends Entity { }

And add a barrel file for it:

并为其添加一个桶文件:

// src/grid/index.ts
export * from './grid'

We can now add this new entity as a child to the Game. Also, let’s ensure only game has write access to its children by making entities private field with a public getter:

现在,我们可以将此新实体添加为游戏的子代。 另外,我们通过使用公共获取程序将entities设为私有字段,确保只有游戏对其子级具有写权限:

// game.ts
import { Entity } from '@/utils'
import { Settings } from '@/settings'
import { Grid } from '@/grid' // <--- ADDexport class Game extends Entity {// ... //public Entities: Entity[] = [] // <--- REMOVE// --- ADD --- //private _entities: Entity[] = []public get Entities(): Entity[] {return this._entities}// --- ADD --- //public Awake(): void {super.Awake()// --- ADD --- //// instantiate and Grid to the list of childrenthis._entities.push(new Grid())// --- ADD --- //// ... //}// ... //
}

And that’s all we have to do! The game will awake and update the Grid as we set up in previous posts.

这就是我们要做的! 游戏将按照我们先前文章中的设置唤醒并更新Grid。

用网格测试游戏 (Testing Game with Grid)

Background vector created by freepikFreepik创建的背景矢量

Before we go any further, let’s update the Game’s test a bit. When we setup game.spec.ts, we also created a bunch of fake Entities:

在继续进行之前,让我们先更新一下游戏的测试。 设置game.spec.ts ,我们还创建了一堆假实体:

// game.spec.ts
// ... //
class E1 extends Entity { }
class E2 extends Entity { }
class E3 extends Entity { }     describe('>>> Game', () => {// ... //
})

They served us well, but now we can make a step further. We know exactly what entity is a child of the Game: it’s the Grid. We don’t need a fake children anymore. This approach allows us to verify both:

他们为我们服务很好,但现在我们可以再进一步。 我们确切地知道哪个实体是Game的子Game :它是Grid 。 我们不再需要孩子了。 这种方法使我们可以验证两个:

  • The game works properly with its entities游戏与其实体正常工作
  • It works appropriately specifically with the Grid

    特别适用于Grid

I start by removing all fake entities from the spec:

首先,从规范中删除所有假实体:

// game.spec.ts
import { Game } from '@/game'
import { IComponent } from '@/utils' // <--- CHANGE
// ... //
// --- REMOVE --- //
class E1 extends Entity { }
class E2 extends Entity { }
class E3 extends Entity { }
// --- REMOVE --- //describe('>>> Game', () => {// ... //// --- REMOVE --- //const e1 = new E1()const e2 = new E2()const e3 = new E3()// --- REMOVE --- //beforeEach(() => {// ... //game.Entities.push(e1, e2, e3) // <--- REMOVE// ... //})// ... //// --- REMOVE --- //it('should awake all children', () => {const spy1 = jest.spyOn(e1, 'Awake')const spy2 = jest.spyOn(e2, 'Awake')const spy3 = jest.spyOn(e3, 'Awake')expect(spy1).not.toBeCalled()expect(spy2).not.toBeCalled()expect(spy3).not.toBeCalled()game.Awake()expect(spy1).toBeCalled()expect(spy2).toBeCalled()expect(spy3).toBeCalled()})it('should update all children', () => {const spy1 = jest.spyOn(e1, 'Update')const spy2 = jest.spyOn(e2, 'Update')const spy3 = jest.spyOn(e3, 'Update')expect(spy1).not.toBeCalled()expect(spy2).not.toBeCalled()expect(spy3).not.toBeCalled()game.Update()expect(spy1).toBeCalled()expect(spy2).toBeCalled()expect(spy3).toBeCalled()})// --- REMOVE --- //
})

Then, I add a new test to check all children are awakened and updated. Even though now we have only one child, the Grid, in future we can update the test when we introduce more children:

然后,我添加了一个新测试以检查所有孩子是否都被唤醒和更新。 即使现在只有一个孩子,即Grid,将来我们可以在引入更多孩子时更新测试:

// game.spec.ts
// ... //
describe('>>> Game', () => {// ... //it('should awake and update all children', () => { }) // <--- ADD
})

The test works similarly to the way fake entities test worked. First, I spy on Awake and Update method of the Grid. And then, I ensure they are called only after game.Awake and game.Update are executed respectively:

该测试的工作方式类似于假实体测试的工作方式。 首先,我监视Grid Awake and Update方法。 然后,确保它们仅在game.Awakegame.Update之后game.Awake调用:

// game.spec.ts
// ... //
import { Grid } from '@/grid' // <--- ADDdescribe('>>> Game', () => {// ... //it('should awake and update all children', () => {// --- ADD --- //const spyGridAwake = jest.spyOn(Grid.prototype, 'Awake')const spyGridUpdate = jest.spyOn(Grid.prototype, 'Update')expect(spyGridAwake).not.toBeCalled()expect(spyGridUpdate).not.toBeCalled()game.Awake()expect(spyGridAwake).toBeCalled()game.Update()expect(spyGridUpdate).toBeCalled()// --- ADD --- //})
})

Note, I don’t have access to Grid instance since it’s created and encapsulated by the Game. But I can rely on Grid.prototype to access Grid methods without an actual instance.

注意,由于它是由游戏创建和封装的,因此我无权访问Grid实例。 但是我可以依靠Grid.prototype来访问Grid方法,而无需实际实例。

The code now should compile without errors if you run npm start. All test should pass if you run npm t

如果您运行npm start那么代码现在应该可以正确编译。 如果您运行npm t则所有测试均应通过

节点介绍 (Introducing Node)

We created a dedicated entity for the Grid.

我们为网格创建了一个专用实体。

Rendering the entire grid as a whole monolithic thing was a simple endeavor. Unfortunately, it’s not sufficient for us. We have to keep track of the individual rectangles of the Grid for different purposes: to highlight them and indicate where players can move their ships, to store information about the nearby nodes to make pathfinding possible, and so on.

将整个网格渲染为整体是一件简单的事情。 不幸的是,这对我们来说还不够。 为了不同的目的,我们必须跟踪网格的各个矩形: 突出显示它们并指示玩家可以其船移动到哪里,存储有关附近节点的信息以使寻路成为可能,等等。

Business vector created by fullvector商业矢量由fullvector创建

We made the first step to make this tracking possible: we created an entity for the Grid. Now we should create an entity for every Node of the Grid:

我们迈出了第一步,以使这种跟踪成为可能:我们为Grid创建了一个实体。 现在,我们应该为Grid每个Node创建一个实体:

// src/node/node.ts
import { Entity } from '@/utils'export class Node extends Entity { }

And let’s not forget about the barrel file:

并且不要忘了桶文件:

// src/node/index.ts
export * from './node'

Like any other entity, it should take its place in the hierarchy of the game objects. It feels natural to make it a child of the Grid. We then can perform a bulk operations on all nodes within the Grid.

像任何其他实体一样,它应在游戏对象的层次结构中占据一席之地。 使它成为Grid的子代是很自然的。 然后,我们可以在Grid内的所有节点上执行批量操作。

The process of adding children to the Grid is the same we did for the Game. I define the private field and a public getter:

将子级添加到Grid的过程与我们在Game所做的相同。 我定义了私有字段和公共获取者:

// src/grid/grid.ts
import { Node } from '@/node' // <--- ADD
// ... //
export class Grid extends Entity {// --- ADD --- //private _nodes: Node[] = []public get Nodes(): Node[] {return this._nodes}// --- ADD --- //
}

The grid should awake and update all nodes:

网格应苏醒并更新所有节点:

// src/grid/grid.ts
// ... //
export class Grid extends Entity {// ... //// --- ADD --- //public Awake(): void {// awake componentssuper.Awake()// awake childrenfor (const node of this._nodes) {node.Awake()}}public Update(deltaTime: number): void {// update componentssuper.Update(deltaTime)// update childrenfor (const node of this._nodes) {node.Update(deltaTime)}}// --- ADD --- //
}

Note, we should call super.Awake() and super.Update() to allow abstract Entity to do its default work and awake and update components. We have none yet, but we will add some in future chapters.

注意,我们应该调用super.Awake()和super.Update()以允许抽象实体执行其默认工作以及唤醒和更新组件。 我们还没有,但是我们将在以后的章节中添加一些内容。

Great, but how would we draw the Node? Should we add drawing functionality to the Node Entity’s Awake method? We could, yet it wouldn’t be a flexible solution.

很好,但是我们将如何绘制节点? 我们是否应该向Node实体的Awake方法添加绘图功能? 我们可以 ,但它不是一个灵活的解决方案。

What if there are a few ways to draw a Node? Let’s say, some nodes would be circles instead of rectangles. Or maybe we do not even want to draw some nodes at all, make them invisible? To achieve that flexibility we could use conditions:

如果有几种绘制Node怎么办? 假设某些节点是圆形而不是矩形。 也许我们甚至根本不想画一些节点,使它们不可见? 为了实现这种灵活性,我们可以使用以下条件:

// pseudo code
if(this.isRect){this.drawRectNode()
} else if(this.isCircle){this.drawCircleNode()
} else { // do not draw at all?
}

That way, we have all drawing logic within Node: drawRectNode, drawCircleNode.

这样,我们在Node拥有所有绘制逻辑: drawRectNodedrawCircleNode

But we have a much more powerful tool under our belt: Components. We can define different components: RectangleDraw, CircleDraw, and attach only necessary ones. Or do not even assign any if we want to skip drawing. Moreover, we can do that in realtime! Following this approach, we decouple drawing logic from the core logic of the Node.

但是,我们拥有一个强大得多的工具: Components 。 我们可以定义不同的组件: RectangleDrawCircleDraw和仅附加必要的组件。 或者,如果我们要跳过绘图,甚至不分配任何内容。 而且,我们可以实时做到这一点! 按照这种方法,我们将绘制逻辑与Node的核心逻辑解耦。

编写我们的第一个组件 (Writing our First Component)

Business photo created by d3imagesd3images创建的商业照片

We will start small and add oneDraw Component to the node that will handle the drawing logic for us. Yet, we keep options open. If we need different drawing components, we can quickly create them without affecting the existing code.

我们将从小处开始,并将一个Draw Component添加到将为我们处理绘制逻辑的节点。 但是,我们保持选择开放。 如果我们需要不同的图形组件,则可以快速创建它们而不会影响现有代码。

Note how nicely this approach plays with SOLID ‘open-close’ principle: we keep our code open for extension.

请注意,这种方法与SOLID“打开-关闭”原理的配合效果非常好:我们保持代码开放以进行扩展。

Component is any class that conforms to IComponent:

Component是符合IComponent任何类:

// src/node/components/draw/draw.ts
import { IComponent } from '@/utils'
import { Node } from '@/node'export class NodeDrawComponent implements IComponent {public Entity: Nodepublic Awake(): void {// to implement}public Update(deltaTime: number): void {// to implement}
}

First, I defined a class that implements IComponent. The interface requires specifying which entity the component can be attached to. In this case, it’s the Node entity. We also have to implement Awake and Update per IComponent requirements.

首先,我定义了一个实现IComponent的类。 该接口要求指定组件可以附加到哪个实体。 在这种情况下,它是Node实体。 我们还必须根据IComponent要求实现AwakeUpdate

Don’t forget to add and update necessary barrel files:

不要忘记添加和更新必要的桶文件:

// src/node/components/draw/index.ts
export * from './draw'// src/node/components/index.ts
export * from './draw'// src/node/index.ts
export * from './components' // <--- ADD
export * from './node'

Note, I defined a dedicated folder for components and even a separate folder for draw component. This folder structure will keep going on throughout the series.

注意,我为组件定义了一个专用文件夹,甚至为绘图组件定义了一个单独的文件夹。 此文件夹结构将在整个系列中继续进行。

All is left for us is to add NodeDrawComponent to the Node:

我们剩下NodeDrawComponent就是将NodeDrawComponent添加到Node

// src/node/node.ts
import { Entity } from '@/utils'
import { NodeDrawComponent } from './components' // <--- ADDexport class Node extends Entity {// --- ADD --- //public Awake(): void {this.AddComponent(new NodeDrawComponent())super.Awake()}// --- ADD --- //
}

测试节点 (Testing Node)

The watercolor vector created by milano83milano83创建的水彩矢量

Before we wrap up this post, let me add some tests. NodeDrawComponent is empty now, so there is nothing yet to test. But we can test Node.

在结束这篇文章之前,让我添加一些测试。 NodeDrawComponent现在为空,因此尚无要测试的内容。 但是我们可以测试Node

// src/node/node.spec.ts
import { Node } from './node'describe('>>> Node', () => {let node: NodebeforeEach(() => {node = new Node()})
})

Node is rather modest in its functionality now. All it does is add NodeDrawComponent. Allow me to be a bit more generic and create a test suite for all components, even though we have only one now:

Node功能相当适中。 它所做的只是添加NodeDrawComponent 。 让我更通用一些,为所有组件创建一个测试套件,即使现在只有一个:

// src/node/node.spec.ts
// ... //
describe('>>> Node', () => {// ... //// --- ADD --- //it('should awake and update all Components', () => { })// --- ADD --- //
})

Testing communication with NodeDrawComponent should sound familiar. We don’t have access to the instance of a component, but we can spy on its prototype. We then use the spy to verify component indeed is awakened and updated when the entity is awakened and updated:

NodeDrawComponent测试通信NodeDrawComponent应该很熟悉。 我们无权访问组件的实例,但是我们可以监视其原型。 然后,当实体被唤醒和更新时,我们使用间谍来验证组件是否确实被唤醒和更新:

// src/node/node.spec.ts
// ... //
import { NodeDrawComponent } from './components' // <--- ADDdescribe('>>> Node', () => {// ... //it('should awake and update all Components', () => {// --- ADD --- //const spyDrawCompAwake = jest.spyOn(NodeDrawComponent.prototype, 'Awake')const spyDrawCompUpdate = jest.spyOn(NodeDrawComponent.prototype, 'Update')expect(spyDrawCompAwake).not.toBeCalled()expect(spyDrawCompUpdate).not.toBeCalled()node.Awake()expect(spyDrawCompAwake).toBeCalled()node.Update(0)expect(spyDrawCompUpdate).toBeCalled()// --- ADD --- //})// ... //
})

If you start your code with npm start, it should compile without errors. If you run tests with npm t, they should pass as well.

如果您使用npm start启动代码,那么它应该编译没有错误。 如果使用npm t运行测试,它们也应该通过。

You can find the complete source code of this post in the drawing-grid-2 branch of the repository.

您可以在存储库的drawing-grid-2分支中找到此文章的完整源代码。

结论 (Conclusion)

Awesome! We did a lot, but nothing changed on the screen: we still can only see the old “dirty” drawing of the Grid. But we accomplished a lot: we learned how to test the functionality of the class without creating the instance, we introduced two new entities: Grid and Node, decoupled them from the Game and even set up our very first component!

太棒了! 我们做了很多事情,但屏幕上没有任何变化:我们仍然只能看到Grid的旧“脏”图。 但是我们完成了很多工作:我们学会了如何在不创建实例的情况下测试类的功能,引入了两个新实体: GridNode ,将它们与Game分离,甚至建立了我们的第一个组件!

In Part 3, we will work closely with NodeRawComponent and get rid of the dirty draw once and for all. And we’ll meet a new friend who will help us with this (and keep helping a lot in the future!): Vector2D.

在第3部分中,我们将与NodeRawComponent紧密合作,并NodeRawComponent地摆脱脏污 。 我们将遇到一个新朋友,它将为我们提供帮助(并在将来继续提供帮助!): Vector2D

If you have any comments, suggestions, questions, or any other feedback, don’t hesitate to send me a private message or leave a comment below! Thank you for reading, and I’ll see you next time!

如果您有任何意见,建议,问题或其他反馈,请随时给我发送私人消息或在下面发表评论! 感谢您的阅读,下次再见!

This is Chapter III in the series of tutorials “Building a game with TypeScript”. Other Chapters are available here:

这是系列教程“ 使用TypeScript构建游戏 ”的第三章 其他章节可在此处找到:

  • Introduction

    介绍

  • Chapter I. Entity Component System

    第一章实体组件系统

  • Chapter II. Game loop (Part 1, Part 2)

    第二章 游戏循环( 第1 部分 , 第2部分 )

  • Chapter III. Drawing Grid (Part 1, Part 2, Part 3, Part 4, Part 5)

    第三章 工程图网格( 第1部分 ,第2部分,第3部分,第4部分,第5部分)

  • Chapter IV. Drawing ships第四章 绘图船
  • Chapter V. Interaction System第五章互动系统
  • Chapter VI. Pathfinding第六章 寻找路径
  • Chapter VII. Moving ship第七章 搬船
  • Chapter VIII. State Machina第八章 国家机械工业
  • Chapter IX. Attack System: Health and Damage第九章 攻击系统:生命与伤害
  • Chapter X. Winning and Losing the Game第十章。输赢
  • Chapter XI. Enemy AI第十一章。 敌人AI

翻译自: https://medium.com/javascript-in-plain-english/building-a-game-with-typescript-drawing-grid-2-5-206555719490

typescript工程


http://www.taodudu.cc/news/show-4189620.html

相关文章:

  • 钉钉企业邮箱smtp服务器
  • python 钉钉发邮件报警设置
  • 阿里云-钉钉-企业邮箱
  • JIRA消息通知打通钉钉群
  • php--api发送钉钉消息
  • java对接钉钉发送消息通知
  • 钉钉桌面版绑定其他邮箱
  • redmine邮箱配置
  • xxl-job集成钉钉群告警
  • Python爬虫监控(邮件和钉钉)
  • 钉钉机器人关键词应答_Gmail 邮件推送到钉钉群机器人(详细)教程|国内接收 Gmail 邮件...
  • java获取钉钉登录信息,JAVA maven项目使用钉钉SDK获取token、用户
  • python钉钉机器人发送excel附件_python调用钉钉机器人发送消息
  • 通过Alertmanager实现Prometheus的告警告警配置(邮箱加钉钉)
  • 钉钉一行代码_利用Python快速搭建钉钉和邮件数据推送系统
  • Python--发送邮件和钉钉消息
  • @Zabbix配置邮箱告警及钉钉告警
  • 钉钉邮箱登录入口_清博舆情钉钉小程序上线 ,五大优势三大亮点助力工作更高效...
  • python 发送带附件邮件到钉钉邮箱+邮件内容带有表格
  • 钉钉邮箱登录入口_钉邮的使用攻略②
  • 钉钉邮箱配置
  • 编写一个掷色子猜大小的游戏
  • shell脚本实现猜大小游戏
  • Python小游戏:猜大小
  • 随机生成数猜大小(java实现)
  • 用shell脚本猜大小
  • 猜大小游戏(条件判断)
  • 三个骰子猜大小
  • JAVA入门:猜大小程序
  • python 从大到小循环_Python循环小实例----猜大小

typescript工程_使用TypeScript构建游戏。 工程图网格2/5相关推荐

  1. typescript 静态_关于TypeScript静态成员的全部信息| TypeScript OOP

    typescript 静态 In Object-Oriented Programming, we write a lot of classes. 在面向对象编程中, 我们编写了许多类 . Classe ...

  2. 使用c#制作打字游戏_使用打字稿iii绘制网格构建游戏4 5

    使用c#制作打字游戏 Chapter III in the series of tutorials on how to build a game from scratch with TypeScrip ...

  3. typescript 使用_如何使用TypeScript轻松修改Minecraft

    typescript 使用 by Josh Wulf 通过乔什·沃尔夫(Josh Wulf) 如何使用TypeScript轻松修改Minecraft (How to modify Minecraft ...

  4. typescript项目_如何设置TypeScript项目

    typescript项目 by David Piepgrass 由David Piepgrass 如何设置TypeScript项目 (How to set up a TypeScript projec ...

  5. pico8 掌机_使用Pico-8构建自己的复古游戏

    pico8 掌机 An example of the kinds of pixel animations people make in Pico-8. 人们在Pico-8中制作的各种像素动画的示例. ...

  6. react和nodejs_如何使用React,TypeScript,NodeJS和MongoDB构建Todo应用

    react和nodejs In this tutorial, we will be using TypeScript on both sides (server and client) to buil ...

  7. 用 typescript 做一个贪吃蛇小游戏

    typescript 做一个贪吃蛇小游戏 搭建环境 创建 tscofig.json 文件 配置如下 {"compilerOptions": {"target": ...

  8. 使用打字稿绘图网格构建游戏3 5

    Chapter III in the series of tutorials on how to build a game from scratch with TypeScript and nativ ...

  9. mathcal 对应于什么库_如何快速构建React组件库

    前言 俗话说:"麻雀虽小,五脏俱全",搭建一个组件库,知之非难,行之不易,涉及到的技术方方面面,犹如海面风平浪静,实则暗礁险滩,处处惊险- 目前团队内已经有较为成熟的 Vue 技术 ...

最新文章

  1. caffe 的命令行训练与测试
  2. How can I pretty-print JSON in python?
  3. windows下安装awstats来分析apache的访问日志
  4. Netflix媒体数据库:媒体时间线数据模型
  5. MySQL的一些概念笔记
  6. Android 系统调试(2)---android debug 方法
  7. ssis合并连接链接键_在SSIS包中使用合并联接转换
  8. python邮件模块_Python收发邮件模块,用,来,发送,接收
  9. mysql 基础面试_面试必问之mysql基础
  10. Mac新手比较容易犯的一些错误
  11. 拓端tecdat|在PYTHON中进行主题模型LDA分析
  12. Nachos 用户进程地址分配
  13. FreeSWITCH折腾笔记5——G729转码支持
  14. 《从底层结构开始学习FPGA》目录与传送门
  15. Learn Git Branching 答案
  16. html桌面天干地支,天干地支-janlen-ChinaUnix博客
  17. Juc_无juc情况
  18. Servlet思维导图总结
  19. WordPress中文汉字用户名不能注册怎么办?
  20. @2-1 CCF 2020-12-01 期末预测之安全指数

热门文章

  1. java零基础学习第七天
  2. 运行Android Studio,一直提示:Error running app: Instant Run requires 'Tools | Android | Enable ADB integrat
  3. uniapp 自定义showToast样式
  4. showToast的使用
  5. 【工作笔记】004 tapestry框架
  6. Debian11安装MySql8
  7. RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增岗位管理-WinForm部分
  8. 看了《天道》,我买了这套书,据说有八卷
  9. AD16布局流程及注意事项
  10. 立体图形3D动画和绘制