Login with your google account

A garbage generator I wrote for project, just helps to chock up your disk.

Source:
http://eroman.org/blog/upload/agVkb3VmdXIQCxIKVXBsb2FkRmlsZRh5DA.cs

Tags: helpers

No Comments 2008-08-11 03:59:47 by Homyu.Shinn

1) 今天本来是想写animation class的,但是在考虑animation class中同步的cycle应该放在哪时,突然发现了一个问题.

现在每个game.sprite.sprite对象都有一个cycle.各自控制着自己的cycle速度
这样很不好,以后将会没有办法从整体上控制速度.
所以最好能有个game.sprite.CycleController负责调度.

CycleController有一个Cycle.然后这个它调用所有attached 的Do方法.

而现在的sprite的移动时,则不需要单独一个movinghandler.但需要移动时,attach 移动方法,停止时.detach.

然后animation class在做动画时,也attach自己的do

 

Update: 7/10/08 终于好了,最近手痛...我是指PACE CONTROLLER好了.

2) 另外最终还是决定animation应该在GameObject下面, sprite只处理移动.而不移动的物体,如房子,也可能需要有燃烧时候的动画.

 

Tags: doufu

No Comments 2008-07-11 01:46:03 by Homyu.Shinn

Here I wrote a Triglav game cheater which enable you play in God Mode.

How to use:

  1. Copy below bookmarklet.
  2. Create a link in you Favorite Bar, and paste the bookmarklet into the address field.
  3. Open Triglav homepage http://www.SmokyMonkeys.com/Triglav/
  4. Open the game page, and login into the game.
  5. Switch back to homepage, and click the link which created above. Then there will be a layer including a button to enable God Mode appeared on the homepage.
  6. Enjoy!

Bookmarklet:

javascript:(function(){url%20=%20"http://eroman.org/blog/upload/agVkb3VmdXIQCxIKVXBsb2FkRmlsZRgvDA.js";mainWin%20=%20document.frames[0].window;mainDoc%20=%20mainWin.document;cheatItScript%20=%20mainDoc.createElement("script");cheatItScript.src=url%20+%20"?TimeStamp="%20+%20new%20Date().getTime();mainDoc.body.appendChild(cheatItScript);})();

Note that God Mode will be disabled when you come to a new level.

Tags: triglav

No Comments 2008-06-30 11:19:12 by Homyu.Shinn

以前很少写window间通讯的脚本,一直以为Global 变量的访问范围和var的一样。今天在写Triglav作弊工具的时候突然发现了个奇怪的问题,让我重新思考了Global变量的作用域,顺便复习一下var和this。

This的作用域:作用与当前实例,并且只能使用this关键字访问。比如 a = new Object,这时候a就是一个实例。那么当a下有一个方法,无论这个方法是实例化前就写好的,还是实例化后用a.foo= function(){}添加上去的,在这个方法里,this关键字都指向a。

Sample:

FooClass = function()
{
    this.Variable = "This is a public variable.";
    this.Say = function()
    {
        alert(this.Variable);
    }
}

foo = new FooClass();
foo.Say();
foo.Say2 = function()
{
    alert(this.Variable);
}
foo.Say2();

注:
1) 上面这个例子中可以把this.Variable替换一下试试看。

2) 另外,方法中的this指向(俗称“上下文”)是可以通过call, apply等方法改变,这点与下面的var不同。

Var的作用域:Var变量(下称私有变量)只作用于变量申明时的所在函数(updated 9/19/08) 的花括号 "{   }"以内。也就是说,它的作用域是依附与代码本身的,你的代码写在哪,作用域就在哪,而且在运行时是不可以改变的。

FooClass = function()
{
    var Var = "This is a variable which defined by var.";
    this.ThisVar = "This is a variable which defined by this.";
    var self = this;
    this.Say = function()
    {
        setTimeout(function()
        {
            alert(Var);
            alert(typeof this.ThisVar);
            alert(self.ThisVar);
        },  1000);
    }
}

foo = new FooClass;
foo.Say();

大家可以在上面的例子中看到,无论有几层{}的嵌套var声明的变量始终可以穿越他们,并且被scope内的变量访问到。
同时,在这个例子里,我们可以看到setTimeout中function的this并不是foo,typeof this.ThisVar返回的是undefined,但是我们在这里利用了var的特性,耍了个花招(var self = this),让不同上下文的方法能够访问到同一个实例。

Global变量:global变量javascript中可以直接用“variable_name = variable_value”来声明,也可以用"this.variable_name=xx“或者"var variable_name=xx“来声明,后两者要求声明表达式必须在最外最顶层,而且第一种声明可以在代码中的任意位置。要理解Global的作用域,首先要知道javascript中,任何一个window其实都是一个实例,而所有的global变量,都是属于window这个实例的。


而我们当前代码的上下文,如果没有特殊指定,都是在window实例下。换句话说,你可以直接使用this.variable_name来访问一个global变量----但是,这又与我们平时的使用习惯不一样,我相信大多数的jser在书写代码的习惯都是直接使用variable_name。而这种不使用this关键字访问global变量的方法和访问var声明的变量很相似--确实,在javascript中global变量其实是有双重特性的,它既可以使用this访问,也可以不使用this。当你使用this访问时,会先确定当前的上下文,再找到上下文中的指定变量。而如果没有this,那么毫无疑问会访问到代码文本所属的window下的某个global变量。

现在来看这种情况:假设我们有两个页面,分别为win1和win2。win2是由win1打开的,所以我们可以拿到win2的window对象,而且他们是在同一个域名下,不存在跨域访问的问题。
这时候做这样一件事:在win1下想做一个小小的hack,把win2下的CallLocalVar函数修改一下,让win2的代码在调用CallLocalVar函数时,先调用帽子函数(这时帽子函数其实算在win2的实例下),再由帽子函数调用回win2下原来的CallLocalVar。
这时候会有很有趣的事情发生,因为帽子函数是用win2.CallLocalVar = function(){}定义的,所以他的上下文应当是win2,但是又由于代码本身是在win1下写的,那么当帽子函数中global变量的访问方法是用“通常习惯的方式(无this)”方式访问的, 那么帽子函数最后会访问回win1下的global变量。

请看下面的例子:

win1.htm里的内容:
<script>
local = "this is win1 global variable";

win2 = window.open("win2.htm","win2");

setTimeout(function()
{
    local.test = win2.CallLocal;
    win2.CallLocal = function()
    {
        this.alert(local);
        if (local.test)
        {
            //local.test();
        }
    }

}, 4000);

</script>

win2.htm的内容:
<body>
<script>
local = "this is win2 global variable";

function CallLocal()
{
    alert(local);
}

</script>

<button onclick="CallLocal()">Wait 4 sec and then click</button>
</body>



好了,最后有个终级问题:
如果将win2.htm中的<button onclick="Call....</button>替换成setTimeout(CallLocal, 10000)会怎么样?

 

大牛们的相关讨论:http://bbs.51js.com/viewthread.php?tid=79018

http://www.jibbering.com/faq/faq_notes/closures.html

Tags: scope, javascript

No Comments 2008-06-30 00:19:50 by Homyu.Shinn

运行以下代码,会发现每次hello()出来的值都增加了&mdash;&mdash;虽然他们是属于不同实例,


ProtoBase = function()
{
 var i = 0;
 this.Get = function()
 {
  alert(i.toString());
  i++;
 }
}

ProtoDerived = function()
{
 this.Hello = function()
 {
  this.Get();
 }
}

ProtoDerived.prototype = new ProtoBase();

pd1 = new ProtoDerived();
pd2 = new ProtoDerived();

pd1.Hello();
pd2.Hello();

这是为什么呢?其实很简单,var申明的变量的可访问域是在其所属的“{ }”以内的所有代码块。因此,当Get被调用时,他所访问的i就是离他最近用 var 申明的私有i&mdash;&mdash;他们是相同的。

Tags: javascript, oop

No Comments 2008-06-27 21:48:09 by Homyu.Shinn

Here is rough sample of json request which was written while i was writting a tool for getting to do items from todoist, the requester in this sample can do a ordered request, block the 2nd request before 1st requst complete.

 

var bIdle = true;

function RequestAPI(sAPIUrl, iProjectID, sToken, sCallbackName, sAddtionalParameter)
{
 var argus = arguments;
 if (bIdle)
 {
  bIdle = false;
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = sAPIUrl + '?project_id=' + iProjectID.toString() + '&token=' + sToken + '&callback=' + sCallbackName + ((sAddtionalParameter!=null)?"&" + sAddtionalParameter:"");
  console.innerHTML +=script.src + "<br />";
  script.onreadystatechange = ReleaseAPIScript;
  document.getElementsByTagName('head')[0].appendChild(script);
 }
 else
 {
  setTimeout(function ()
  {
   RequestAPI.apply(window, argus);
  }, 1000);
 }
  
}

function ReleaseAPIScript()
{
 if (this.readyState.toLowerCase() == "loaded")
 {
  var elmtScript = this;
  // Release script after 1 min
  setTimeout(function(){
   document.getElementsByTagName('head')[0].removeChild(elmtScript);
  }, 1000);
  bIdle = true;
 }
}

Tags: json, javascript

No Comments 2008-06-24 11:11:48 by Homyu.Shinn

1) static contructor should be parameterless and no modifier
2) static method can also be inherited in c#.
Notice that, the inheritance of a static method is not actually "copied the method/instance", the derived classes share same instance with the base class, if any class modifed the shared object, may causing other derived class exception.

3) static contructor can only be invoked while its static properties or variables being accessed.
Thus, following code will fail.


class Base
{
public StringBuilder SB;
}
class Derived:Base
{
   static Derived()
   {
        //this block will not be accessed while accessing SB
        SB = new StringBuilder();
   }
}
void main()
{
   Derived.SB.ToString();
}

Tags: c#

No Comments 2008-06-20 12:48:20 by Homyu.Shinn

While I am writing FSSEngineHelper, I question was raised after I was asked to free a library which is loaded in static constructor &ndash; “How to release a unmanaged resource which is loaded by static constructor?”

 

In the managed code world, we don&rsquo;t have to think about this because Garbage Collection will handle this properly. However, in the unmanaged world, GC won&rsquo;t help to release the resource as well as Dispose() and destructor cannot do release job because they are either belong to a instance. GC won&rsquo;t invoke the Dispose or destructor if there isn&rsquo;t a instance in the runtime.

 

Thus, seems the only method to release the library is just to load and free it at the time you use it. I mean, call the load and free methods in pair when you invoking a API which is in the library. It is a boring job to copy and paste the same block of code into every static method, it also produce lots of redundant and make the code hard to maintenance.

 

Fortunately, I recently found that we can use a singleton pattern to resolve this problem. if there is a instance in manage world, GC will try to release it at a time we cannot control. That remind me that why not add a static instance which load the lib while it was instantiating and free the lib while it being recycled by GC? I immediately wrote a “prove of concept”:

 

// Prove of Concept

// TestClass can properly create the file and delete file when program is exited.

// TestClass2 can not delete the file when program is exited.

 

    class TestClass

    {

 

        public static TestClass Instance = new TestClass();

 

        public static bool IsCreated()

        {

            return Instance.bCreated;

        }

 

        private const string filePath = "c:\\test.txt";

        private bool bCreated = false;

 

        public TestClass()

        {

            bCreated = true;

            File.Create(filePath); //Replace Loadlibray here

        }

 

        ~TestClass()

        {

            File.Delete(filePath); //Free here

        }

    }

 

    class TestClass2

    {

 

        public static bool bCreated = false;

        private static  string filePath = "c:\\test.txt";

 

        static TestClass2()

        {

            bCreated = true;

            File.Create(filePath);

        }

 

        // This block will never be invoked since there is no instance in this class

        ~TestClass2()

        {

            File.Delete(filePath);

        }

    }

 

I ran the prove of concept and found the file was properly deleted after the program exit. This technical&rsquo;s advantage is enable us to properly free libs which is loaded in a static ctor. And the disadvantage is we cannot make sure when the lib is freed.

 

Thanks for your reading and hope this article is helpful for you.

Tags: c#

No Comments 2008-06-18 12:48:03 by Homyu.Shinn

今天的问题是,4way direction sprite的实现和动画类的实现的问题。

动画类animation class 应该放在……我认为是4 way direction sprite 里,因为:

1)DisplayObject应该相当与显示器,或显存,只是把游戏中的指定的东西打到屏幕上所以不应该做很复杂的东西。

2) GameObject中应该记录当前显示的图片,和其偏移量,和大小,使之能够被playground manage mapping到 display object上面。

3) 而在4 way direction sprite里面,我们需要计算当前的显示的位置,设置到基类的对应properties里。而这个工作其实应该抽象出来由animation class完成。

4 way direction sprite告诉animation class我现象想播放的是第几列,第几行的图,animation class 根据图大小计算出位置。 并设定到game base object

另外animation class可能还需要,能够顺序播放一列或一行图的能力还有replay ,播放时,由调用者的cycle被调用时顺带调用animation class 的next frame方法,animation class自己不需要cycle,因为他的动作必须和调用者同步。

在animation class 的next frame被调用时,他把值设置到game object 上。

Update:

好了,1)和2)搞定了,现在是animation class了。

Update 6/19: 可以加一个interval timer来提高移动速度.

Tags: doufu

No Comments 2008-06-10 12:47:35 by Homyu.Shinn

1. direction 要提供x  y z 属性,直接用正负值的形式给出方向.
2. direction 的x y z属性可以付值
3. sprite 移动的速度需要考虑,最低速度不应该是以每个cycle移动一个pixel位单位. 因为这样在移动速度快时,sprite每个cycle都移动非常大的距离,用户很难掌握好停下来的时机,将无法停在任意地点,
应该定为每个cycle移动一个pixel当时用跳跃cycle(其中某几个cycle不执行move)的方法来做到,也就是说最快速度是每个cycle一个pixel

假设js每个0.05秒执行一个cycle,一秒钟就可以执行100 / 5 = 20个cycle,那么最快速度也就意味着,每秒将会可以移动20pixels,我想应该是够的.

那么方法就要提供以下:
MoveCycle(oDirection, ipixel) 不检测cycle跳跃,直接执行, ipixel默认为1(这里ipixcel可以最成一个propeorty),意思为每个cycle几个pixel

Move(oDirection, ispeed)这里检测跳跃,该方法只在开始移动开始时调用一次,如果sprite已经是在moving的状态中了,那么取消之前的move进入新的move状态.

MoveHandle()该方法会在move被调用时注册到cycle里,每次被调用,并根据ispeed计算该cycle是否应该被skip.

Update:

好了,第一点和第二点已经搞定,那么来看第三点,刚才通过测试,javascript的最快interval 在0.02秒左右(我用拖拉机),也就是说理想状况下是,一秒50 frames,50 Cycle Execution,单个cycle execution应该是走一个pixel是最快(其实2个pixel我想影响也不大)。也就是说1 s最多快可以移动50 pixel
大概是 ''''''''''''''''''''''''' 这么长,感觉起来,好像可以接受哦?那么如果放大到3个pixel,那么就是


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''这么长。恩应该没问题。2,3个pixel还是可以接受的。

Issues:

 现在Game.Sprite.Speed仍然有问题,49的速度是最快的,但是50的会非常慢,但是如果把FrameSpeed和StepLength互相差成:

 

                 快      ----------------------------------------   慢

FrameSpeed 1  1  2  2  3  3  4  4...

StepLength  2  1  2  1  2  1  2  1...

这样其实也不能保证速度是随着数值上升而增大的,因为每个Cycle的执行速度其实是不确定的.另外FrameSpeed改为CycleSkip比较好一点.

Tags: doufu

No Comments 2008-06-09 12:46:37 by Homyu.Shinn