迁移-策略游戏(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/migration-strategy-game-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 11 分钟阅读 - 5114 个词 阅读量 0迁移-策略游戏(译文)
原文地址:https://www.codeproject.com/Articles/564534/Migration-Strategy-Game
原文作者:Terence Wallace
译文由本站 robot-v1.0 翻译
前言
A VB.NET implemenation of using delegates and threading for game loops.
使用委托和线程进行游戏循环的VB.NET实现.
- 下载必需资源(36875K)(Download Required Resources (36875K))
- 下载源(Download source)
- 下载支持文件(Download support files)
目录(Table of Contents)
技术(Technology)
介绍(Introduction)
迁移是一种模拟策略游戏.游戏的目的是建立一个工人社区,他们执行建立新殖民地的各项任务.游戏由鼠标操作的点击界面控制.玩家不能直接控制工人,而是下达命令建造建筑物,管理货物的制造和分配以及攻击对手.(Migration is a simulation strategy game. The goal of the game is to build a community of workers that perform individual tasks of building a new colony. The game is controlled by a mouse-operated point-and-click interface. The player cannot directly control workers, but instead places orders to construct buildings, manage the manufacture and distribution of goods and attack opponents.) 有32种建筑资源和11种移民.新建筑竣工后,将把空闲的移民招募到专门的职位.例如,铁匠一旦建造便会出现.一些移民需要特殊的工具来担任这些角色.工具制造商的建筑物可以创建其他工具,并且所创建的每个工具的比例都由玩家控制.(There are 32 kinds of building resources and 11 types of migrants. Idle migrants are recruited to specialized roles when new buildings are finished. For example, a blacksmith appears once a smithy is constructed. Some migrants require specific tools for these roles.A toolmaker’s building can create additional tools, and the proportions of each tool being created is controlled by the player.) 游戏开始时,玩家选择城堡的位置,这里存放了最初的定居者和仓库.如果没有仔细规划建筑物和道路的布置,可能会导致交通拥堵.如果不采取应对措施(重新路由货物,建造更多的仓库,更好地放置建筑物),则此类单一瓶颈会在整个网络中产生分布效应,导致短缺,因为货物无法足够快地到达目的地.(At the start of the game the player chooses the location of their castle, which houses the initial settlers and stockpiles. If placement of buildings and roads is not carefully planned it may lead to traffic congestion. If no counter action is taken (re-routing the goods, constructing more warehouses, better placement of buildings), such single bottlenecks can have a distributed effect across the network, leading to shortages because goods can not reach their destination fast enough.)
背景(Background)
家政(Housekeeping)
最终,首先也是最重要的是,我需要感谢该代码库的原始作者,(*Ultimately, first, and foremost, I need to acknowledge the original author of this codebase,*) Christoph Husse.(Christoph Husse.) 可以找到原始的C#代码(*The original C# code can be found*) 这里(here) [([) ^)^( ].它最初的名称为Monostrategy [(]. It was originally titled Monostrategy[) ^)^( ]他的项目旨在对世界上最好的多人实时战略游戏之一进行开源改造,"(*] His project was intended to be an OpenSource remake of one of the best multiplayer real time strategy games in the world, “*) 定居者”.(The Settlers".) [([) ^)^( ].(].)
动机(Motivation)
多年来,我一直喜欢Maxis的<模拟城市>和Sid Meier的<文明>等游戏.我花了无数个小时在这些游戏上进行游戏和制定策略.但是,我一直想对它们进行"微调".(For years I’ve admired games like Maxis' SimCity and Sid Meier’s Civilization�. I’ve spent countless hours playing and strategizing with those games. However, I have always wanted to ‘tweak’ them just a bit.) 我一直希望自己拥有这些标题的版本.我只是不知道从哪里开始.来自商业编程背景,我永远无法理解如何正确实现游戏循环.在我选择的VB中,从来没有任何好的例子.因此,我决定在VB.NET中将该游戏开源,以帮助他人,也许激发一些想法,并了解如何创建自己的Empire Strategy类型的游戏.(I have always desired to have my own version of these titles. I just never knew where to start. Coming from a business programming background I could never understand how to get the game loops right. There were never any good examples in VB which is my language of choice. Therefore, I decided to open source this game in VB.NET in an attempt to help others, and perhaps spur some ideas, and understanding about how to create your own Empire Strategy type game.)
范围(Scope)
本文的范围是游戏循环.特别是,我将讨论与VB.net相关的游戏循环.也许在后续文章中,我将讨论细节,类以及这些类之间的相互关系.(The scope for this article is Gaming Loops. In particular, I am going to talk about Game Loops as it relates to VB.net. Maybe in a follow up article I will talk about the details, classes, and the interrelationships between those classes.) 但是,就目前而言,我将坚持最大的努力来制作策略游戏.从编程的角度来看,任何游戏的核心都是游戏循环.游戏循环是允许游戏平稳运行的方法,而与用户的输入或缺少输入无关.(However, for now, I will stick to the biggest hiccup in creating strategy games. The central component of any game, from a programming standpoint, is the game loop. The game loop is what allows the game to run smoothly regardless of a user’s of a user’s input or lack thereof.) 当然,在商业软件编程中,我们从不需要真正担心这个概念.在大多数情况下,我们设计对用户事件"反应"的系统. (即按钮按下,输入文本框等.).大多数传统的商业软件程序都会响应用户输入,如果没有输入,则什么也不做.例如,文字处理器在用户键入时格式化文字和文本.如果用户未输入任何内容,则文字处理器不会执行任何操作.功能可能需要很长时间才能完成,但是它们都是由用户告诉程序"执行"操作来启动的.另一方面,不管用户的输入如何,游戏都可以继续运行.(Of course, in business software programming we never really have to worry much about this concept. For the most part we design systems that ‘React’ to user events. (i.e. Button push, text box entered, etc..). Most traditional business software programs respond to user input and do nothing without it. For example, a word processor formats words and text as a user types. If the user doesn’t type anything, the word processor doesn’t do anything. Functions may take a long time to complete, but they are all initiated by a user telling the program to ‘do’ something. Games, on the other hand, continue to operate regardless of a user’s input.) 这就是(This is what the) 游戏循环(game loop) 允许.对我来说,那是一个巨大的学习曲线.希望本文将有助于您在进入或考虑进入游戏编程时缓解学习曲线.(allows. That was a tremendous learning curve for me. Hopefully, this article will help to ease that learning curve for you as you move into or think about moving into game programming.) 注意:(Note:)请注意,这项工作还没有完成.还有很多工作要做.(Please note that this work is in no way complete. There is much work left to be done.) 书签:(Bookmark:)在修正某些错误的过程中,我将尝试更新本文.(I will try and update this article as I get around to fixing certain bugs.)
安装(Installation)
第1步(Step 1)
最初,一旦下载了迁移源并解压缩,最终将得到以下目录布局:(Initially once you download the Migration Source and unzip you will end up with the following directory layout:)
第2步(Step 2)
接下来,您需要确保(Next you need to make sure you*) 必填*资源(Download Required Resources)下载 和(and the) 支持文件.(support files.) 将两个文件的内容解压缩到" Build"目录中.(Unzip the content of both files into your “Build” directory.)
第三步(Step 3)
确保您的"构建"目录包含所有必需的文件.忽略"(Ensure that your “Build” directory has all of the files necessary. Ignore the “)textures.cache(textures.cache)“文件,它将在程序启动时重新生成.其外观应类似于下图:(” file it will be regenerated on program startup. It should look similar to the picture below:)
第4步(Step 4)
确保您的”(*Ensure that your “*)**资源资源(Resources*)**目录如下所示.如果不确定,(” directory looks like below. If not be sure and*) 必填资源(Download Required Resources)下载
工作原理-大图(How it works - The Big Picture)
代表们(Delegates)
迁移使用多个委托和指向委托的指针来完成其任务.基本上,委托充当事件的处理程序.那是程序员的话,对不对?让我举一个例子:假设我正在纽约的一家酒店登记入住.当我去前台时,前台人员通常会指派其他人将我的行李带到我的房间.行李处理人员是处理行李的指定代表. VB.NET中的委托也是如此.在迁移中,我们将为当前和将来的处理传递许多功能给其他类.(Migration uses several Delegates and Pointers to Delegates to accomplish it’s tasks. Basically, a Delegate acts as a handler for events. That’s programmer talk, right? Let me give you an example: Let’s say I am checking into a hotel in New York city. When I go to the front desk the front desk person will usually assign someone else to carry my bags to my room. The baggage handler person is the designated delegate for handling bags. The same is true with delegates in VB.NET. In Migration we are going to be handing off a lot of functions to other classes for current and future processing.) 有关更多信息(More information on) 代表(delegates) …(…)
穿线(Threading)
在进行"迁移"游戏时,游戏将确定何时解雇代表. (即何时执行).迁移使用线程来完成此任务.每次循环(即循环)时,游戏都会使用阈值来确定特定代表是否应立即解雇或稍后解雇.在周期内达到阈值后,将创建一个线程,游戏继续进行.另外,请注意,此新线程可以触发其他线程,依此类推.(During Migration game play, the game will determine when to fire off delegates. (i.e. when they will execute). Migration uses threads to accomplish this. Each time through the cycle (i.e. loop) the game determines -using a threshold, if a particular delegate should fire off now or later on. Once the threshold is met during the cycle a thread will be created and the game continues. Also, note that this new thread my fire other threads, so on, and so forth.) 有些代表需要异步触发,有些则需要同步触发.你问有什么区别?当您发送电子邮件时,通常不会期望立即得到答复,而是继续做其他事情.这就像一个异步操作.希望在一两天内收到回复,如果重要的是定期检查您的邮箱,可能会给自己发送提醒以选中您的邮箱.另一方面,当您单击网页上的链接时,您等待响应.这就是同步操作.(Some delegates need to fire Asynchronously and some Synchronously. What’s the difference you ask? When you send an email you usually don’t expect an immediate answer, but continue doing something else. That’s like an asynchronous operation. In a day or two, you will hopefully receive a reply, if it’s important you check your mailbox regularly, possibly sending yourself a reminder to check your box. On the other hand, when you click on a link on a web page, you wait for a response. That’s what a synchronous operation is.) 有关更多信息(More information on) 穿线(threading) …(…)
例子(Examples)
委托和线程的示例:(Example of delegates and threading:)
' Use of a Main thread to kickstart things off
' Run this thread in the background (i.e. Asynchronously)
'On the fly, anonymous Delegate ("Sub") used to call InitializeProgram
Dim thread As New System.Threading.Thread(Sub() InitializeProgram())
thread.IsBackground = True
thread.Start()
thread.Join()
初始化(Initialization)
一旦此主线程启动,它就不会停止,直到它以某种方式停止(即系统异常,关闭,游戏停止等)为止.请记住,该线程在后台线程上运行,因此它将运行,并且还允许其他系统继续运行.(Once this Main thread is started it doesn’t stop until its ‘told’ to stop somehow (i.e. System Exceptions, shut downs, game stop, etc…). Remember that this thread is running on a background thread so it will run and also allow other systems to continue chugging along.)
此方法进一步开始了启动新线程的过程,新线程也将受到监视,直到它们也被"告知"停止.(This method further begins the process of kick starting new threads which also get monitored until they also are ‘told’ to stop.)
' Once this Main thread is started it does not stop until its 'told' to stop somehow
Private Shared Sub InitializeProgram()
Game.Setup.Initialize()
Game.Setup.Renderer.WaitForTermination()
End Sub
...
Public Sub WaitForTermination()
Do While Not IsTerminated
Thread.Sleep(500)
Loop
End Sub
...
Class Setup
...
Public Shared Sub Initialize()
' setup renderer
Renderer = New Renderer(Language.Configuration)
AddHandler Renderer.OnRenderSprites, AddressOf Render_RenderSprites
AddHandler Renderer.OnMouseMove, AddressOf Render_MouseMove
AddHandler Renderer.OnMouseDown, AddressOf Render_MouseDown
AddHandler Renderer.OnMouseUp, AddressOf Render_MouseUp
AddHandler Renderer.OnKeyDown, AddressOf Renderer_OnKeyDown
AddHandler Renderer.OnKeyRepeat, AddressOf Renderer_OnKeyRepeat
Dim mPath As String = [Global].GetResourcePath("Animations")
AnimationLibrary.OpenFromDirectory(mPath)
InitializeGame()
End Sub
...
End Class
...
Private Shared Sub InitializeGame()
Map = New Migration.Game.Map(512, 59, New RaceConfiguration() { _
Loader.Open([Global].GetResourcePath("Configuration\Roman.Buildings.xml")) })
Renderer.AttachTerrain(Map.Terrain)
m_GUILoaderTimer = New Timer(AddressOf OnTimerCallback, Nothing, 1000, 1000) ' <---- Another thread
...
End Sub
游戏循环(Game Loop)
每个游戏都包含一系列获取用户输入,更新游戏状态,处理AI,播放音乐,音效以及渲染游戏的过程.此序列主要通过迁移的主要游戏循环(称为(Every game consists of a sequence of getting user input, updating the game state, handling AI, playing music, sound effects, and rendering the game. This sequence is handled primarily through the main game loop of Migration called the) SimulationLoop()
.这个游戏循环是游戏的心跳.这是大多数更新和事件发生的循环.这也是游戏保存到磁盘的位置.(. This game loop is the heartbeat of the game. This is the loop where most updates and events occur. This is also where the game gets saved to disk.)
Private Sub SimulationLoop()
Try
Dim watch As New Stopwatch()
Dim lastElapsed As Long = 0
Dim elapsedShift As Long = 0
Dim cycleMillis As Long = 0
If System.IO.File.Exists("GameLog.s3g") Then
AddOneCycle()
...
End Sub
周期经理(Cycle Managers)
迁移利用"周期管理员"来处理特定于游戏资源的项目(即动产管理员,建筑物管理员等).这些周期管理器不在本文讨论范围之内,但可能会在以后介绍.每个周期管理员将处理整个周期(Migration utilizes ‘cycle managers’ to handle game resource specific items (i.e. movables manager, buildings manager, etc.). These cycle managers are beyond the scope of this article but maybe covered at a later date. Each cycle manager will process a cycle through it’s) ProcessCycle()
方法.处理完成后,我们可以释放标记为释放或需要进行任何清理的资源.这些资源将根据(FIFO)顺序在队列中安排清理.(method. After processing is done we can then release resources that have been marked for release or whatever clean up is necessary. These resources will be scheduled for clean-up according to what’s in the queue in (FIFO) order.)
...
Friend Sub AddOneCycle()
If Not IsInitialized Then
Throw New InvalidOperationException()
End If
MovableManager.CurrentCycle += 1
BuildingManager.ProcessCycle()
ResourceManager.ProcessCycle()
MovableManager.ProcessCycle()
If m_UpdateConfig Then
m_UpdateConfig = False
Configuration.Update()
End If
End Sub
...
Public Sub Synchronize(ByVal inTask As Procedure)
MovableManager.QueueWorkItem(inTask)
End Sub
...
Public Sub Synchronize(ByVal inDueTimeMillis As Long, ByVal inTask As Procedure)
MovableManager.QueueWorkItem(inDueTimeMillis, inTask)
End Sub
概要(Summary)
游戏循环比您想象的要多.游戏循环是每个游戏的心跳,没有它就无法运行任何游戏.但是不幸的是,对于每个新游戏程序员来说,互联网上都没有很好的VB.NET文章提供有关此主题的信息.我们已经审查了在策略游戏中使用VB.NET中的委托和线程的实现.(A game loop has more to it than you think. The game loop is the heartbeat of every game, no game can run without it. But unfortunately for every new game programmer, there aren�t any good VB.NET articles on the internet that provide information on this topic. We’ve reviewed an implementation of using delegates and threading in VB.NET for a strategy game.) 希望本文激发了一些VB.NET编码人员的力量,并开始对下一代出色的游戏进行编码.(Hopefully, this article has inspired some VB.NET coders to go out and start coding that next generation fantastic game.)
版权(Copyrights)
除了以前所有的版权,我也感谢Ubisoft和BlueByte的图形/媒体贡献.(In addition to all previous copyrights I also acknowledge the graphic/media contributions of Ubisoft and BlueByte.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
VB10.0 VB.NET VB Windows Win7 WinXP GDI+ Dev 新闻 翻译