ブラウザ上を猫が散歩するブックマークレット

ブラウザ上を猫が散歩するブックマークレットを書きました。



下記をブラウザのアドレス欄にコピペしてみてください。

javascript:(function(){d=document;s=d.createElement('script');s.setAttribute('src','http://gamedev.vs.land.to/hatena/javascript/wandercat00/WanderCat.js');d.documentElement.appendChild(s);}())

画面のどこかで、猫がうろちょろしているはずです。



RPGツクールで使うような16x16のキャラチップの小さな猫なので、見つかりにくいかもしれないです。
画面をクリックすると猫が一匹増えます。
※たまに猫じゃないのも出てきます。



FirefoxIEで動作を確認しましたが、猫を増やした場合にIEではちょっと処理速度が落ちるようです。




このスクリプト(WanderCat.js)のソースは以下においておきます。



以前作った迷路(JavaScriptで迷路の自動生成 - valinstの日記
のキャラ移動コードをそのまま使用しているので、ちょっと無駄が多めかもしれません。

var Chara = function(name,path) {
    this.px = 0;
    this.py = 0;
    this.x = 0;
    this.y = 0;
    this.dir = 2;
    this.step = 0;
    this.name = name;
    this.animationCount = 0;
    this.SPEED = 1;
    this.CS = 16;
    this.movingLength = 0;
    this.isMoving = false;
    this.changeCount = 0;
    this.waitCount = 0;
    this.maxWait = 0;
    
    for(var i = 0; i < 12; ++i){    
        var cimg = document.createElement("img");
        cimg.id = name+i;
        cimg.src = (path+"/"+i)+".png";
        cimg.style.position = "absolute";
        cimg.style.left = -64;
        cimg.style.top  = -64;
        cimg.style.visibility = "hidden";
        if(document.body)
            document.body.appendChild(cimg);
        else
            document.documentElement.appendChild(cimg);
    }
}

Chara.prototype._set = function(element,x,y) {
    element.style.left = x;
    element.style.top  = y; 
}

Chara.prototype.put = function(x,y) {
    this.x = x;
    this.y = y;
    this.px = (x * this.CS);
    this.py = (y * this.CS);
    var element = document.getElementById(this.name + (this.dir * 3 + this.step));
    this._set(element,this.px,this.py);
    element.style.visibility = "visible";   
}

Chara.prototype.animation = function() {
    if(++this.animationCount > 15){
        this.setVisibleCurrentStep("hidden");
        this.step = this.step ? 0 : 2;
        var name = this.setVisibleCurrentStep("visible");
        this._set(document.getElementById(name),this.px,this.py);
        this.animationCount = 0;
    }
}

Chara.prototype.setVisibleCurrentStep = function(str) {
    var name = this.name + (this.dir * 3 + this.step);
    document.getElementById(name).style.visibility = str;
    return name;
}

Chara.prototype.move = function() {
    this.animation();
    
    if(this.waitCount != 0){
        if(++this.waitCount > this.maxWait)
            this.waitCount = 0;
        return false;
    }
    
    if( this.isMoving ){
        this.setVisibleCurrentStep("hidden");
        var ret = false;
        switch (this.dir) {
            case 1: ret = this.moveRight(); break;
            case 3: ret = this.moveLeft();  break;
            case 0: ret = this.moveUp();    break;
            case 2: ret = this.moveDown();  break;
        }
        var name = this.setVisibleCurrentStep("visible");
        this._set(document.getElementById(name),this.px,this.py);
        return ret;
    }else{
        this.setVisibleCurrentStep("hidden");
        if(++this.changeCount > 2){
            var r = Math.floor(Math.random()*6);
            if(r >= 4){
                this.waitCount = 1;
                this.maxWait = Math.floor(Math.random()*20) + 40;
            }else
                this.dir = r;
            this.changeCount = 0;
        }
        var name = this.setVisibleCurrentStep("visible");
        this._set(document.getElementById(name),this.px,this.py);
        this.isMoving = true;
    }
    return false;
}

Chara.prototype.moveLeft = function() {
    if(this.x - 1 < 0){
        this.isMoving = false;
        this.movingLength = 0;  
        return true;
    }
    
    this.px -= this.SPEED;
    if (this.px < 0) {
        this.px = 0;
    }
    this.movingLength += this.SPEED;
    if (this.movingLength >= this.CS) {
        this.x--;
        this.px = this.x * this.CS;
        this.isMoving = false;
        this.movingLength = 0;
        return true;
    }
    return false;
}

Chara.prototype.moveRight = function() {
    if(this.x + 1 > (getBrowserWidth()/this.CS)-1){
        this.isMoving = false;
        this.movingLength = 0;  
        return true;
    }
    
    this.px += this.SPEED;
    if (this.px > getBrowserWidth() - this.CS) {
        this.px = getBrowserWidth() - this.CS;
    }
    this.movingLength += this.SPEED;
    if (this.movingLength >= this.CS) {
        this.x++;
        this.px = this.x *this. CS;
        this.isMoving = false;
        this.movingLength = 0;
        return true;
    }
    return false;
}

Chara.prototype.moveUp = function() {
    if(this.y - 1 < 0){
        this.isMoving = false;
        this.movingLength = 0;  
        return true;
    }
    this.py -= this.SPEED;
    if (this.py < 0) this.py = 0;
    this.movingLength += this.SPEED;
    if (this.movingLength >= this.CS) {
        this.y--;
        this.py = this.y * this.CS;
        this.isMoving = false;
        this.movingLength = 0;
        return true;
    }
    return false;
}

Chara.prototype.moveDown = function() {
    if(this.y + 1 > (getBrowserHeight()/this.CS)-1){
        this.isMoving = false;
        this.movingLength = 0;  
        return true;
    }
    this.py += this.SPEED;
    if (this.py > getBrowserHeight() - this.CS) {
        this.py = getBrowserHeight() - this.CS;
    }
    this.movingLength += this.SPEED;
    if (this.movingLength >= this.CS) {
        this.y++;
        this.py = this.y * this.CS;
        this.isMoving = false;
        this.movingLength = 0;
        return true;
    }
    return false;
}

function getBrowserWidth() {  
    if ( window.innerWidth ) {
        return window.innerWidth; 
    } 
    else if ( document.documentElement && document.documentElement.clientWidth != 0 ) {
        return document.documentElement.clientWidth; 
    }
    else if ( document.body ) {
        return document.body.clientWidth;
    }
    return 0;  
}  
function getBrowserHeight() {  
    if ( window.innerHeight ) {
        return window.innerHeight; 
    } 
    else if ( document.documentElement && document.documentElement.clientHeight != 0 ) {
        return document.documentElement.clientHeight; 
    }
    else if ( document.body ) {
        return document.body.clientHeight;
    }
    return 0;  
}  

var charaList = new Array;

var createNewCat = function(num) {
    var names = ["cat0", "cat1", "cat2", "swn", "btf", "cok"];
    var chara = new Chara("cat"+new Date().getTime(),"image/"+names[num]);
    chara.put(Math.floor(Math.random()*getBrowserWidth())/16,Math.floor(Math.random()*getBrowserHeight())/16);
    charaList.push(chara);
}

setInterval(function(){
    for(var i in charaList){
        charaList[i].move();
    }
},16*2);

var mouseDown = function() {
    if( Math.floor(Math.random()*100) < 95)
        createNewCat(Math.floor(Math.random()*3));
    else
        createNewCat(Math.floor(Math.random()*3)+3);
}

if (document.addEventListener){
    document.addEventListener("click", mouseDown, true);
} else if (document.attachEvent){
    document.attachEvent("onclick", mouseDown, true);
}

createNewCat(0);