.NET程序员的游戏

原创 2004年08月30日 01:36:00

首先到http://www.terrariumgame.net下载环境。

实验1:创建一个草食动物
实验目的:
  这个实验的目的是为了打造一个功能十足的生物体给陆地动物饲养所。你可以从创建一
个简单的生物体开始再慢慢加些高级的功能进去。只要你觉得它走的路线可以满足要求了,
你就可以把它引入陆地动物生态系统,然后就可以跟其他参与者的动物进行对战。

练习1--创建一个简单的草食动物
  一只动物只是一个你自己写的类,这个类继承自Terrarium暴露出来的一个Animal类.
在这个练习中,你可以用c#创建一个简单的草食动物,可以使用Microsoft Visual Studio
2003来创建,编译和运行。
  ---开始了--
请用你的名字代替任何一个在以下看到的文本,<YOUR NAME>,因为每只引入.NET Terrarium
的动物都必须有一个唯一的名字。
1.1 在Visual Studio里创建一个新的Terrarium Animal 项目。(在下载安装之后会在项目选项里多出两个项目)
 >首先打击Visual Studioi .NET 2003
 >再点击文件-->创建一个新的类并选择C#作为开发语言。
 >为这个项目起一个名字。OK,开始吧。
1.2 给你的动物添加一个名字和邮箱地址。
用你的名字和邮箱来更新AuthorInformation 清单属性,如下:
[assembly: AuthorInformation("Your Name", "someone@microsoft.com")]
1.3设置Carnivore属性为false.
设置Carnivore属性为false表示你的动物是一只草食动物。如下:
[Carnivore(false)]
1.4 给你的动物选择一个皮肤。
AnimalSkin 属性定义了你的动物种类。如下:
[AnimalSkin(AnimalSkinFamily.Inchworm)]
1.5 给你的动物的特征属性分派一个值,所有属性的值的总和不能超过100.如下。
[MaximumEnergyPoints(20)]

[EatingSpeedPointsAttribute(0)]

[AttackDamagePointsAttribute(12)]

[DefendDamagePointsAttribute(12)]

[MaximumSpeedPointsAttribute(16)]

[CamouflagePointsAttribute(10)]

[EyesightPointsAttribute(20)]

1.6 给MyAnimal类添加一个目的场所。
因为你的动物是一只草食类的动物,它吃草,因此目的场所存储了你的动物要吃的植物,
把下面这个放在Initialize方法在里面。如下:
// The current plant we're going after 

PlantState targetPlant = null;
1.7 IdleEvent事件预定
空闲事件是每个回合最后一个触发的事件,这一行告诉游戏引擎每次IdleEvent被触发时
就去调用MyAnimal_Idle方法,把下面这行添加在初始化方法里,如,
Idle += new IdleEventHandler(MyAnimal_Idle);
1.8 添加IdleEvent handler(句柄)
这个方法提供了你的草食动物的大部分逻辑,首先,如果你的动物准备要复活,它提供了
一个复制循环(reproduction cycle),接着它拼命吃东西。如果它已经有一个目的场所了,
它就开始走向目的场所开始吃东西。如果它没有目的场所的话,它就尝试着去扫描它周围
环境,找出一个场所来。把下面这个方法添加到MyAnimal类里。
// Fired after all other events are fired during a turn

void MyAnimal_Idle (object sender, IdleEventArgs e)

{

    try

    {

        // Reproduce as often as possible

        if (CanReproduce)

            BeginReproduction(null);

 

        // If we can eat and we have a target plant, eat

        if (CanEat)

        {

            WriteTrace("Hungry.");

            if (!IsEating)

            {

                WriteTrace("Not eating: Have target plant?");

                if (targetPlant != null)

                {

                    WriteTrace("Yes, Have target plant already.");

                    if (WithinEatingRange(targetPlant))

                    {

                        WriteTrace("Within Range, Start eating.");

                        BeginEating(targetPlant);

                        if (IsMoving)

                        {

                            WriteTrace("Stop while eating.");

                            StopMoving();

                        }

                    }

                    else

                    {

                        if (!IsMoving)

                        {

                            WriteTrace("Move to Target Plant");

                            BeginMoving(new MovementVector(targetPlant.Position, 2));

                        }

                    }

                }

                else

                {

                    WriteTrace("Don't have target plant.");

                    if (!ScanForTargetPlant())

                    {

                        if (!IsMoving)

                        {

                            WriteTrace("No plant found, so pick a random point and move there");

 

                            int RandomX = OrganismRandom.Next(0, WorldWidth - 1);

                            int RandomY = OrganismRandom.Next(0, WorldHeight - 1);

 

                            BeginMoving(new MovementVector(new Point(RandomX, RandomY), 2));

                        }

                        else

                        {

                            WriteTrace("Moving and Looking...");

                        }

                    }

                }

            }

            else

            {

                WriteTrace("Eating.");

                if (IsMoving)

                {

                    WriteTrace("Stop moving while eating.");

                    StopMoving();

                }

            }

        }

        else

        {

            WriteTrace("Full: do nothing.");

            if (IsMoving)

                StopMoving();

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

 

// Looks for target plants, and starts moving towards

// the first one it finds

bool ScanForTargetPlant()

{

    try

    {

        ArrayList foundCreatures = Scan();

 

        if (foundCreatures.Count > 0)

        {

            // Always move after closest plant

            foreach (OrganismState organismState in foundCreatures)

            {

                if (organismState is PlantState)

                {

                    targetPlant = (PlantState)organismState;

                    BeginMoving(new MovementVector(organismState.Position, 2));

                    return true;

                }

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

    return false;

}

1.9 LoadEvent事件预定
LoadEvent是每回合第一个被调用的事件。这一行表示当每次LoadEvent事件被触发的时候
就去调用MyAnimal_Load方法(这个方法在1.7中已经定义)。把下面这行添加到Initialize
方法里面。
Load += new LoadEventHandler(MyAnimal_Load);
1.10 添加LoadEvent handler(句柄)
在LoadEvent事件里,你的动物一直在检查目的场所是否在存在(它可能消失或者被吃掉)
把下面这个方法添加到MyAniaml类里
// First event fired on an organism each turn

void MyAnimal_Load(object sender, LoadEventArgs e)

{

    try

    {

        if (targetPlant != null)

        {

            // See if our target plant still exists (it may have died)

            // LookFor returns null if it isn't found

            targetPlant = (PlantState)LookFor(targetPlant);

            if (targetPlant == null)

            {

                // WriteTrace is the best way to debug your creatures.

                WriteTrace("Target plant disappeared.");

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

1.11 生成 animal DLL
通过选择 生成---生成解决方案来生成 这个animal DLL。
1.12 把你的草食动物引入陆地动物饲养所。
Terrarium 支持两种游戏模式。陆地动物模式和生成系统模式。在生成系统模式里,你的
动物跟其它开发着的动物进行竞争比赛。
  陆地动物模式是一种陆地动物测试模式。在这种模式下,你可以在一个控制中的环境下
测试你的动物。
接着打开你下载并安装成功的.NET Terrarium 1.2环境, Terrarium 1.2客户端会在生态
系统模式下打开。
   Terrarium 1.2有两种模式可以运行,缺省模式是生态系统模式,这是所以参与者交互的
 地方。peers会彼此发觉,可以彼此用心灵沟通(这里不知道有没翻译错,呵呵)(原文:
 teleport organisms)并且通过服务器报告它们的状态。两个人在这种模式下会更好玩。
   另外一种模式叫Terrarium模式,这是一种可以测试你的动物的“离线”模式。在这种模式下,
你并没有跟其它peers进行交流,所以没有任何teleportation 发生,你也不会把你的状态报
告给服务器。在这种模式下任何时候都可以保存状态,创建一个新的生命,或者打开已存在的。
你会觉得这种模式对于创建和测试你的动物是很有帮助的.
  在这次练习中,我们不用把动物引入生态系统因为动物可能还没有能力生存得更久.反而,
我们改变到Terrarium模式下,这种模式允许你在把动物引入生态系统之前测试一下你的动物.
  在打开的.NET Terrarium 1.2环境中,可以通过点击New Terrarium按钮来切换到Terrarium
模式,输入Lab01作为名字再保存,这时会以Terrarium模式重新启动客户端.
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 

  下一步是添加一些植物到动物饲养所里,这样当你的草食动物被引入时就有东西可以吃.可以
通过点击Add按钮,再点击Server列表按钮,接着你就会看到几只已经引入的动物.

    为了这个实验,把它作为跟在真实世界里一样,有几种植物种类你可以选择,选择任何一种"plant"
再点击OK即可,这时会引入十种你选择的植物到饲养所里.
  通过选择在下拉框里的植物来添加更多的植物,点击Insert按钮,这时在饲养所里就有大量的植物了.

最后引入你的动物.可以通过点击Add按钮,再点击Browse按钮浏览到你创建的DLL(<YOUR NAME>.dll),
这个dll放在你的项目的Bin目录下.
  你应该可以在饲养所里看到十个你所创建的动物的实例.你也可以像添加植物那样使用组合框和
Insert按钮来添加更多的动物.

注意:.
  当代码在运行的时候,你不能改变动物的基本特征--性能表现:你的动物移动的速度有多快,攻击时
表现得如何,有多大等等.这些特征都是通过在你创建的类里指定属性来预先定义的.可以在Organism
 这份文档的Attributes章节里找到一些有效的属性列表.有些特征要求有点数可用,
你可以自己决定.在这些属性里每只动物都有一百点可以分.例如:你可以通过分派更多点数给
MaximumSpeedPointsAttribute属性来使动物跑得更快,但如果EyesightPointsAttribute属性的点数太少
的话,动物的视力就不是很好.
  一旦你定义了动物的特征,接着你就可以写代码来控制动物的行为了.在Organism 文档里查找Animal类
和Organism类(Animal继承自Organism)看看你可以在代码里做什么.注意很多方法都以"Begin..."开头,
这些方法都是不同的.当这些动作完成后相应的事件就会触发告诉你它已经准备好了.

------------Lab1 Over----------Now Lab2 Begin.........

  实验摘要:
在这个实验里,你已经创建了一个简单的草食动物,并在饲养所里经过测试.

练习2--处理攻击事件
  在这个hands-on实验里可以通过使用饲养所的事件模型来处理一个攻击事件.当你被另外一只动物攻击
的时候就会触发一个攻击事件,这仅仅是你可以处理的众多事件中的一个,可以在Organism文档里找到所有
的列表.
2.1 打开你在练习1中创建的动物(简单草食动物)
>打开VS2003,选择文件-打开项目,浏览到你在练习1中创建的项目.打开.
>如果源文件没有在主窗口里打开,可以在解决方案窗口里双击MyAnimal.cs图标来打开.
2.2 预定AttackedEvent (攻击事件)
 当你的动物被另外一只动物攻击的时候就会触发攻击事件。下面这行告诉游戏引擎当每次攻击事件触发时
就调用MyAnimal_Attacked方法。把下面这行添加到Initialize方法里面
Attacked += new AttackedEventHandler(MyAnimal_Attacked);

2.3添加AttackedEvent (攻击事件)句柄

 当你的动物被攻击的时候,它先试着去反抗攻击者,接着就通过在游戏板里移动到一个随机位置来远离攻
击者,把下面这个方法添加到MyAnimal类里.
// Fired if we're being attacked
void MyAnimal_Attacked(object sender, AttackedEventArgs e) {
  if(e.Attacker.IsAlive)
  {
    AnimalState theAttacker = e.Attacker;
    BeginDefending(theAttacker); //defend against the attacker
 
    WriteTrace("Run away to some random point");
    int X= OrganismRandom.Next(0, WorldWidth - 1);
    int Y= OrganismRandom.Next(0, WorldHeight - 1);
    BeginMoving(new MovementVector(new Point(X,Y), 10));
  }

2.4 重命名和生成animal DLL.
>选择项目属性,这时会打开一个项目属性对话框.
>在一般选项里选择"通用",改变Assembly Name 字段为<YOUR NAME>_Ex2,点击OK.
>通过选择生成-生成解决方案来生成animal DLL.

2.5  在Terrarium模式下引入你的草食动物到饲养所里.

------------Lab2 Over----------Now Lab3 Begin.........

实验摘要:
在这个实验里,你已经把你的草食动物变成了当受攻击时会发觉攻击并自动回应攻击.

练习3-通讯
  在接下来的实验里你会用到Antenna 属性来控制与其它动物的通讯.对Antenna 属性的状态每个动物
可以看见.可以通过改变成Antenna 属性的值来跟在生态系统里的其它动物进行交流.在这个实验里,
当发现你的植物被其它动物占领时就可以让动物发出信号,动物响应之后,占领动物就会跑开.
 
3.1 打开你在练习1中创建的项目.
3.2 定义MoveCompletedEvent事件
当你的动物停止移动时MoveCompletedEvent就会被触发,下面这行告诉游戏引擎当每次MoveCompletedEvent
被触发时就去调用MyAnimal_MoveCompleted方法
把下面这行添加到Initialize方法里
MoveCompleted +=new MoveCompletedEventHandler(MyAnimal_MoveCompleted);

3.3 添加MoveCompletedEvent 句柄
有两种原因动物会完成它的移动事件,一种是到达了它的目的地,一种是在移动的路途中受到阻拦.如果
动物的路途受到阻拦,我们就要发出信号把阻拦的动物赶走.信号使用的是antenna,值为13.
把下面这个方法添加到MyAnimal类里.
// Fired when we've finished moving.

private void MyAnimal_MoveCompleted(object sender, MoveCompletedEventArgs e)

{

    // Reset the antenna value

    this.Antennas.AntennaValue = 0;

   

    // If we've stopped because something is blocking us...

    if (e.Reason == ReasonForStop.Blocked)

    {

        WriteTrace("Something's blocking my way.");

        if (e.BlockingOrganism is AnimalState)

        {

            AnimalState blockingAnimal = (AnimalState)e.BlockingOrganism;

            if (blockingAnimal.AnimalSpecies.IsSameSpecies(this.Species))

            {

                // Signal to our friend to move out of our way.

                WriteTrace("One of my friends is blocking my way.  I'll ask him to move.");

                this.Antennas.AntennaValue = 13;

            }

        }

    }

}

3.4 加入当阻拦到战友时移开的逻辑
在每个回合里,我们需要到处寻找当战友受阻拦时发出的信号.ShouldIMoveForMyFriend 方法寻找信号为
13的动物,也就是战友.如果找到,就会远离阻拦的动物.把下面这个方法添加到MyAnimal类里.
// Routine to move out of the way when blocking our friends.

void ShouldIMoveForMyFriend()

{

    try

    {

        ArrayList foundAnimals = Scan();

 

        if (foundAnimals.Count > 0)

        {

            foreach (OrganismState organismState in foundAnimals)

            {

                if (organismState is AnimalState)

                {

                    AnimalState visibleAnimal = (AnimalState)organismState;

 

                    // Only move if the animal is one of our friends (IsSameSpecies).

                    if (visibleAnimal.Species.IsSameSpecies(this.Species))

                    {

                        // If the animal's antenna value is 13, it means they're blocked (see the MoveCompletedEvent method).

                        if (visibleAnimal.Antennas.AntennaValue == 13)

                        {

                            // We're blocking our friend, so we should move.

                            WriteTrace("I'm blocking one of my friends.  I should move.");

 

                            int newX = this.Position.X - (visibleAnimal.Position.X - this.Position.X);

                            int newY = this.Position.Y - (visibleAnimal.Position.Y - this.Position.Y);

 

                            BeginMoving(new MovementVector(new Point(newX, newY), 2));

                            return;

                        }

                    }

                }

            }

        }

    }

    catch (Exception exc)

    {

        WriteTrace(exc.ToString());

    }

}

3.5 在每回合的结尾时调用ShouldIMoveForMyFriend()方法
在每个回合的结尾,我们需要调用ShouldIMoveForMyFriend()方法来为战友除去障碍.当每个回合的IdleEvent
事件被触发时,在MyAnimal_Idle 方法的结尾处添加ShouldIMoveForMyFriend 方法的调用.把下面这行
添加到MyAnimal_Idle方法的最后一行.
ShouldIMoveForMyFriend();
3.6 重命名和生成animal DLL
>选择项目-属性,在打开的通用属性里选择-通用,把Assembly Name字段改变为<YOUR NAME>_Ex3.
>选择生成-生成解决方案,来生成animal DLL.
3.7 在Terrarium 模式下把食草动物引入到饲养所里.
如练习1所说引进去.


练习3--引入生态系统--终于可以对战了,HOHO
在接下来的实验里,你将会把你的动物引入到生态系统里,这个生态系统让这个游戏变得更有趣,在这里你
可以找一个对手来进行比赛.如果你的机器是连上Internet的话,在internet上的其它动物饲养人就可以很
安全地跟你交换动物.
双击下载并安装成功的->.NET Terrarium 1.2平台图标
Terrarium会在生态模式下打开.这时可以通过点击Introduce Animal按钮来把你的动物引入到生态系统
中.
---------图片--------
  浏览你刚才创建的项目(<YOUR NAME>_Ex3.dll),这个dll放在你项目的Bin目录下,选择动物后,点击
Open打开,这时你的动物就会被引入到生态系统中.你应该可以在屏幕中看到十只你的动物.
  你只能在生态系统中插入一只动物,所以在引入之前请确定你已经在Terrarium模式下测试过它.

实验摘要:
  现在你的动物已经在生态系统战场上跟其它动物较量了它的命运就决定在你的技术中.


为了玩这个游戏,我到主页上把它的c#教材花了两个小时翻译成了中文,方便以后看,大家也来玩玩吧.

HOHO,Let's Come and play it together!

class org.omg.CORBA.ORB说明

ORBabstract public class org.omg.CORBA.ORB 作者: Cocia Lin 说明:本文是在jdk1.3的源码中翻译整理而成。 ORB类是为CORBA ORB提供的...
  • cocia
  • cocia
  • 2001-12-05 09:51:00
  • 2750

一张图大神带你了解游戏程序员的学习之路

一张图大神带你了解游戏程序员的学习之路 Milo Yip 标签: 游戏引擎 , 游戏开发 2017-07-13 16:47:39 514 叶劲峰(Milo Yip)现任腾...
  • u012662731
  • u012662731
  • 2017-07-14 09:36:46
  • 2007

想成为挣钱的游戏程序员要经历多少阶段?

从腾讯的大牛来看,至少要经历下面几个阶段,如下图:这里列出了11个阶段,只要努力学习好,就可以去腾讯混饭吃了。1. 五子棋游戏开发http://edu.csdn.net/course/detail/5...
  • caimouse
  • caimouse
  • 2017-08-12 09:11:41
  • 1011

如何成为一名自豪的游戏程序员

什么工作最苦,程序员的工作最苦,我们号称软件民工。 什么程序员工作最苦,游戏程序员工作最苦,我们天天加班,拿着微薄的工资,号称为了理想而奋斗。 软件民工,其实有点高抬自己了。其实我们除了衣服领子看...
  • langeldep
  • langeldep
  • 2011-08-26 11:57:00
  • 11658

专门针对程序员的8款代码游戏

http://codebay.cn/post/95.html 忙完了一天的工作后,程序员都想休息一下。休息的时候,玩游戏是最好的放松方式。如果有这么一款游戏,能在放松的同时巩固学到的...
  • u010833547
  • u010833547
  • 2017-01-18 15:17:25
  • 4322

某游戏公司程序员面试题某游戏公司程序员面试题

(网上找的) 在原公司是做什么工作的?原公司的产品是哪方面的? 对C++应用到什么程度? 匈牙利命名法?对变量的命名方法? 开发程序的时候经常查MSDN吗? MFC可以吗? DC是什么? 内存泄露? ...
  • gongxinheng
  • gongxinheng
  • 2008-03-23 11:03:00
  • 5237

关于游戏程序员的职业规划

为什么做游戏程序员:乐趣、梦想、财富、成就感 我们的绰号:“程序猿”、“码农”、“IT民工” 现状: 1.  经常加班,薪水不高,项目不好 2.  亚健康,近视,缺乏锻炼,蓬头垢面,没有活力,容易...
  • unknowm
  • unknowm
  • 2014-05-31 14:09:35
  • 4486

游戏程序员应具备的几种技能

1. 做好事务记录 2. 快速反馈 3. 快速开发(RAD) 4. 选择专业化方向 5. 靠数据决策 6. 掌握一些套路...
  • unknowm
  • unknowm
  • 2017-01-14 16:03:57
  • 989

程序员必玩游戏...来测试下你的编程能力吧

  • 2010年07月11日 14:38
  • 12KB
  • 下载

惋惜!37岁游戏开发程序员突发脑溢血去世

程序员头条(ID:CoderTop) 报道消息来源:重庆晚报37岁!重庆游戏界元老冒哥突发脑溢血逝世 愿天堂没有操劳……据重庆晚报报道,1 月 16 日凌晨 4 点,又一位互联网精英倒下。此时城市还在...
  • tTU1EvLDeLFq5btqiK
  • tTU1EvLDeLFq5btqiK
  • 2018-01-22 00:00:00
  • 750
收藏助手
不良信息举报
您举报文章:.NET程序员的游戏
举报原因:
原因补充:

(最多只允许输入30个字)