はてなハイク STAR FIGHTERS
by
lieutar
2010-12-30 [2010/12/30 15:12:55]
はてなハイクで実行すると、星を打ちあう簡単な対戦型シューティングが初まる。カーソルキーで移動、Zで星発射。ESCで終了
@@ -1,176 +1,301 @@
/*
* @title haiku-shoot
- * @description はてなハイクで自アイコンを操作します(つくりかけ。なげだすかも)
+ * @description はてなハイクで星を撃つ
* @include http://h.hatena.ne.jp/*
* @license MIT License
* @require
*/
(function(){
- var Z_INDEX_USER = 65536;
- var Z_INDEX_BULLET = 65535;
- var Bullet = (function(x,y){
- this.x=x;
- this.y=y;
- });
- Bullet.prototype = {
- fire: function(x,y){
- var img = document.createElement('img');
- img.src = 'http://s.hatena.ne.jp/images/star.gif';
- document.body.appendChild(img);
- img.style.position = 'fixed';
- var sx = this.x;
- var sy = this.y;
- setTimeout(function(){
- img.style.top = (sy - img.clientHeight / 2) + 'px';
- img.style.left = (sx - img.clientWidth / 2) + 'px';
- sx += x;
- sy += y;
- if(sx > 0 && sx < window.innerWidth && sy > 0 && sy < window.innerHeight){
- setTimeout(arguments.callee, 10);
- }else{
- img.parentNode.removeChild(img);
- }
- },10);
- }
- };
-
- var user = (function(){
- var name = document.evaluate('.//p[@class="username"]/a/text()',
- document.body,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null).snapshotItem(0).data;
- var img = new Image();
- img.src = (
- 'http://www.st-hatena.com/users/' + name.substring(0,2) + '/' + name + '/profile.gif'
- );
- document.body.appendChild(img);
- img.style.zIndex = String(Z_INDEX_USER);
- img.style.position = 'fixed';
- img.style.top = (window.innerHeight - img.clientHeight - 10) + 'px';
- img.style.left = Math.floor((window.innerWidth - img.clientWidth ) / 2) + 'px';
- return {
- name: name,
- icon: img,
- speed: 5,
- shot: function(){
- var bullet = new Bullet(Math.floor(img.offsetLeft + img.clientWidth /
- 2),img.offsetTop);
- bullet.fire(0,-20);
- },
- moving: false,
- _move_k: {n:0,s:0,w:0,e:0},
- _move_x: 0,
- _move_y: 0,
- stop: function(){
- if(!this.moving) return;
- clearTimeout(this.moving);
- this.moving = null;
- },
- move: function(dir){
- var _move_k = this._move_k;
- switch(dir){
- case 'n':
- _move_k.n = 1;
- if(_move_k.s > 0) _move_k.s = 2;
- break;
- case 'N':
- _move_k.n = 0;
- if(_move_k.s > 0) _move_k.s = 1;
- break;
- case 's':
- _move_k.s = 1;
- if(_move_k.n > 0) _move_k.n = 2;
- break;
- case 'S':
- _move_k.s = 0;
- if(_move_k.n > 0) _move_k.n = 1;
- break;
- case 'w':
- _move_k.w = 1;
- if(_move_k.e > 0) _move_k.e = 2;
- break;
- case 'W':
- _move_k.w = 0;
- if(_move_k.e > 0) _move_k.e = 1;
- break;
- case 'e':
- _move_k.e = 1;
- if(_move_k.w > 0) _move_k.w = 2;
- break;
- case 'E':
- _move_k.e = 0;
- if(_move_k.w > 0) _move_k.w = 1;
+ var Z_INDEX_USER = 65536;
+ var Z_INDEX_BULLET = 65535;
+
+
+ var inherit = function(parent, initializer){
+ var klass = function(){};
+ klass.prototype = parent.prototype;
+ var proto = new klass;
+ if(!('initialize' in proto)) proto.initialize = function(){};
+ var R = function(){
+ this.initialize.apply(this,arguments);
+ };
+ R.prototype = proto;
+ initializer.apply(
+ proto,
+ [
+ parent.prototype,
+ R
+ ]
+ );
+ return R;
+ };
+
+ var Game = new (inherit(
+ Object, function(SUPER, Class){
+ this.initialize = function(){
+ this.elems = {};
+ };
+
+ this.registerElement = function(elem){
+ this.elems[elem.key] = elem;
+ };
+
+ this.unregisterElement = function(elem){
+ delete this.elems[elem.key];
+ };
+
+
+ this.iter = function(){
+ var elems = this.elems;
+ var f;
+ for(f in elems){
+ elems[f].step();
+ }
+
+ // 衝突検知と、衝突後の処理を書く
+
+ for(f in elems){
+ elems[f].redraw();
+ }
+ };
+
+ this.start = function(){
+ var self = this;
+ (function(){
+ self.iter();
+ setTimeout(arguments.callee, 10);
+ })();
+ };
}
- var x = 0;
- var y = 0;
- if(_move_k.s != _move_k.n){
- y = _move_k.s > _move_k.n ? 1 : -1;
+ ));
+
+
+ var GameElement = inherit(
+ Object, function(SUPER, Class){
+ var counter = 0;
+
+ this.initialize = function(){
+ this.key = 'elem_'+ counter++;
+ Game.registerElement(this);
+ };
+
+ this.step = function(){
+ };
+
+ this.redraw = function(){
+ };
+
+ this.getTrack = function(){
+ };
+
+ this.onHit = function(){
+ };
}
- if(_move_k.w != _move_k.e){
- x = _move_k.e > _move_k.w ? 1 : -1;
+ );
+
+ var Bullet = inherit(
+ GameElement, function(SUPER, Class){
+
+ this.initialize = function(x,y,dx,dy,speed){
+ SUPER.initialize.apply(this,[]);
+ this._x=x;
+ this._y=y;
+ this._pre_x = x;
+ this._pre_y = y;
+ this._dx = dx;
+ this._dy = dy;
+ this._speed = speed;
+ var img = document.createElement('img');
+ img.src = 'http://s.hatena.ne.jp/images/star.gif';
+ document.body.appendChild(img);
+ img.style.position = 'fixed';
+ this._img = img;
+ };
+
+ this.redraw = function(){
+ var img = this._img;
+ if(this._dispose){
+ Game.unregisterElement(this);
+ img.parentNode.removeChild(img);
+ return;
+ }
+ var sx = this._x;
+ var sy = this._y;
+ img.style.top = (sy - img.clientHeight / 2) + 'px';
+ img.style.left = (sx - img.clientWidth / 2) + 'px';
+ };
+
+ this.step = function(){
+ this._pre_x = this._x;
+ this._pre_y = this._y;
+ var sx = this._x + this._dx * this._speed;
+ var sy = this._y + this._dy * this._speed;
+ if(sx > 0 && sx < window.innerWidth &&
+ sy > 0 && sy < window.innerHeight){
+ this._x = sx;
+ this._y = sy;
+ } else {
+ this._dispose = true;
+ }
+ };
}
- this._move_x = x;
- this._move_y = y;
- if(x == 0 && y == 0){
- this.stop();
- return;
+ );
+
+ var User = inherit(
+ GameElement, function(SUPER,Class){
+
+ this.initialize = function(name){
+ SUPER.initialize.apply(this,[]);
+ this.name = name;
+ var img = new Image();
+ img.src = (
+ 'http://www.st-hatena.com/users/' + name.substring(0,2) +
+ '/' + name + '/profile.gif'
+ );
+ document.body.appendChild(img);
+ img.style.zIndex = String(Z_INDEX_USER);
+ img.style.position = 'fixed';
+ this.img = img;
+ this.speed = 5;
+ this._move_k = {n:0,s:0,w:0,e:0};
+ this._move_x = 0;
+ this._move_y = 0;
+ this._x =
+ Math.floor((window.innerWidth - img.clientWidth ) / 2
+ );
+ this._y =
+ (window.innerHeight - img.clientHeight - 10);
+ this._px = 0;
+ this._py = 0;
+ };
+
+ this.shot = function(){
+ new Bullet(Math.floor(this._x + this.img.clientWidth / 2),
+ this._y,
+ 0,
+ -1,
+ 20);
+ };
+
+ this.step = function(){
+ this._px = this._x;
+ this._py = this._y;
+ this._x += (this.speed * this._move_x);
+ this._y += (this.speed * this._move_y);
+ };
+
+ this.move = function(dir){
+ var _move_k = this._move_k;
+ switch(dir){
+ case 'n':
+ _move_k.n = 1;
+ if(_move_k.s > 0) _move_k.s = 2;
+ break;
+ case 'N':
+ _move_k.n = 0;
+ if(_move_k.s > 0) _move_k.s = 1;
+ break;
+ case 's':
+ _move_k.s = 1;
+ if(_move_k.n > 0) _move_k.n = 2;
+ break;
+ case 'S':
+ _move_k.s = 0;
+ if(_move_k.n > 0) _move_k.n = 1;
+ break;
+ case 'w':
+ _move_k.w = 1;
+ if(_move_k.e > 0) _move_k.e = 2;
+ break;
+ case 'W':
+ _move_k.w = 0;
+ if(_move_k.e > 0) _move_k.e = 1;
+ break;
+ case 'e':
+ _move_k.e = 1;
+ if(_move_k.w > 0) _move_k.w = 2;
+ break;
+ case 'E':
+ _move_k.e = 0;
+ if(_move_k.w > 0) _move_k.w = 1;
+ }
+ var x = 0;
+ var y = 0;
+ if(_move_k.s != _move_k.n){
+ y = _move_k.s > _move_k.n ? 1 : -1;
+ }
+ if(_move_k.w != _move_k.e){
+ x = _move_k.e > _move_k.w ? 1 : -1;
+ }
+ this._move_x = x;
+ this._move_y = y;
+ };
+
+ this.redraw = function(){
+ var img = this.img;
+ img.style.top = this._y + 'px';
+ img.style.left = this._x + 'px';
+ };
+
}
- if(this.moving) return;
- var self = this;
- (function(){
- img.style.top = (img.offsetTop + self.speed * self._move_y) + 'px';
- img.style.left = (img.offsetLeft + self.speed * self._move_x) + 'px';
- self.moving = setTimeout(arguments.callee, 10);
- })();
- }
- };
- })();
+ );
+
+ var name = document.evaluate(
+ './/p[@class="username"]/a/text()',
+ document.body,
+ null,
+ XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
+ null).snapshotItem(0).data;
+
+ var user = new User(name);
-document.addEventListener( 'keypress', function(e){ e.preventDefault();}, false);
+ document.addEventListener( 'keypress',
+ function(e){ e.preventDefault();}, false);
+
+ window.addEventListener(
+ 'keydown', function(e){
+ e.stopPropagation();
+ // console.log(e.keyCode);
+ switch(e.keyCode){
+ case 37: //LEFT
+ user.move('w');
+ break;
+ case 38: //UP
+ user.move('n');
+ break;
+ case 39: //RIGHT
+ user.move('e');
+ break;
+ case 40: //DOWN
+ user.move('s');
+ break;
+ case 90: // Z
+ user.shot();
+ }
+ }, true
+ );
+
+ window.addEventListener(
+ 'keyup', function(e){
+ e.stopPropagation();
+ switch(e.keyCode){
+ case 37: //LEFT
+ user.move('W');
+ break;
+ case 38: //UP
+ user.move('N');
+ break;
+ case 39: //RIGHT
+ user.move('E');
+ break;
+ case 40: //DOWN
+ user.move('S');
+ break;
+ }
+ }, true
+ );
- window.addEventListener(
- 'keydown', function(e){
- e.stopPropagation();
-// console.log(e.keyCode);
- switch(e.keyCode){
- case 37: //LEFT
- user.move('w');
- break;
- case 38: //UP
- user.move('n');
- break;
- case 39: //RIGHT
- user.move('e');
- break;
- case 40: //DOWN
- user.move('s');
- break;
- case 90: // Z
- user.shot();
- }
- }, true
- );
- window.addEventListener(
- 'keyup', function(e){
- e.stopPropagation();
- switch(e.keyCode){
- case 37: //LEFT
- user.move('W');
- break;
- case 38: //UP
- user.move('N');
- break;
- case 39: //RIGHT
- user.move('E');
- break;
- case 40: //DOWN
- user.move('S');
- break;
- }
- }, true
- );
+ Game.start();
})();
/*
* @title haiku-shoot
* @description はてなハイクで星を撃つ
* @include http://h.hatena.ne.jp/*
* @license MIT License
* @require
*/
(function(){
var Z_INDEX_USER = 65536;
var Z_INDEX_BULLET = 65535;
var inherit = function(parent, initializer){
var klass = function(){};
klass.prototype = parent.prototype;
var proto = new klass;
if(!('initialize' in proto)) proto.initialize = function(){};
var R = function(){
this.initialize.apply(this,arguments);
};
R.prototype = proto;
initializer.apply(
proto,
[
parent.prototype,
R
]
);
return R;
};
var Game = new (inherit(
Object, function(SUPER, Class){
this.initialize = function(){
this.elems = {};
};
this.registerElement = function(elem){
this.elems[elem.key] = elem;
};
this.unregisterElement = function(elem){
delete this.elems[elem.key];
};
this.iter = function(){
var elems = this.elems;
var f;
for(f in elems){
elems[f].step();
}
// 衝突検知と、衝突後の処理を書く
for(f in elems){
elems[f].redraw();
}
};
this.start = function(){
var self = this;
(function(){
self.iter();
setTimeout(arguments.callee, 10);
})();
};
}
));
var GameElement = inherit(
Object, function(SUPER, Class){
var counter = 0;
this.initialize = function(){
this.key = 'elem_'+ counter++;
Game.registerElement(this);
};
this.step = function(){
};
this.redraw = function(){
};
this.getTrack = function(){
};
this.onHit = function(){
};
}
);
var Bullet = inherit(
GameElement, function(SUPER, Class){
this.initialize = function(x,y,dx,dy,speed){
SUPER.initialize.apply(this,[]);
this._x=x;
this._y=y;
this._pre_x = x;
this._pre_y = y;
this._dx = dx;
this._dy = dy;
this._speed = speed;
var img = document.createElement('img');
img.src = 'http://s.hatena.ne.jp/images/star.gif';
document.body.appendChild(img);
img.style.position = 'fixed';
this._img = img;
};
this.redraw = function(){
var img = this._img;
if(this._dispose){
Game.unregisterElement(this);
img.parentNode.removeChild(img);
return;
}
var sx = this._x;
var sy = this._y;
img.style.top = (sy - img.clientHeight / 2) + 'px';
img.style.left = (sx - img.clientWidth / 2) + 'px';
};
this.step = function(){
this._pre_x = this._x;
this._pre_y = this._y;
var sx = this._x + this._dx * this._speed;
var sy = this._y + this._dy * this._speed;
if(sx > 0 && sx < window.innerWidth &&
sy > 0 && sy < window.innerHeight){
this._x = sx;
this._y = sy;
} else {
this._dispose = true;
}
};
}
);
var User = inherit(
GameElement, function(SUPER,Class){
this.initialize = function(name){
SUPER.initialize.apply(this,[]);
this.name = name;
var img = new Image();
img.src = (
'http://www.st-hatena.com/users/' + name.substring(0,2) +
'/' + name + '/profile.gif'
);
document.body.appendChild(img);
img.style.zIndex = String(Z_INDEX_USER);
img.style.position = 'fixed';
this.img = img;
this.speed = 5;
this._move_k = {n:0,s:0,w:0,e:0};
this._move_x = 0;
this._move_y = 0;
this._x =
Math.floor((window.innerWidth - img.clientWidth ) / 2
);
this._y =
(window.innerHeight - img.clientHeight - 10);
this._px = 0;
this._py = 0;
};
this.shot = function(){
new Bullet(Math.floor(this._x + this.img.clientWidth / 2),
this._y,
0,
-1,
20);
};
this.step = function(){
this._px = this._x;
this._py = this._y;
this._x += (this.speed * this._move_x);
this._y += (this.speed * this._move_y);
};
this.move = function(dir){
var _move_k = this._move_k;
switch(dir){
case 'n':
_move_k.n = 1;
if(_move_k.s > 0) _move_k.s = 2;
break;
case 'N':
_move_k.n = 0;
if(_move_k.s > 0) _move_k.s = 1;
break;
case 's':
_move_k.s = 1;
if(_move_k.n > 0) _move_k.n = 2;
break;
case 'S':
_move_k.s = 0;
if(_move_k.n > 0) _move_k.n = 1;
break;
case 'w':
_move_k.w = 1;
if(_move_k.e > 0) _move_k.e = 2;
break;
case 'W':
_move_k.w = 0;
if(_move_k.e > 0) _move_k.e = 1;
break;
case 'e':
_move_k.e = 1;
if(_move_k.w > 0) _move_k.w = 2;
break;
case 'E':
_move_k.e = 0;
if(_move_k.w > 0) _move_k.w = 1;
}
var x = 0;
var y = 0;
if(_move_k.s != _move_k.n){
y = _move_k.s > _move_k.n ? 1 : -1;
}
if(_move_k.w != _move_k.e){
x = _move_k.e > _move_k.w ? 1 : -1;
}
this._move_x = x;
this._move_y = y;
};
this.redraw = function(){
var img = this.img;
img.style.top = this._y + 'px';
img.style.left = this._x + 'px';
};
}
);
var name = document.evaluate(
'.//p[@class="username"]/a/text()',
document.body,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null).snapshotItem(0).data;
var user = new User(name);
document.addEventListener( 'keypress',
function(e){ e.preventDefault();}, false);
window.addEventListener(
'keydown', function(e){
e.stopPropagation();
// console.log(e.keyCode);
switch(e.keyCode){
case 37: //LEFT
user.move('w');
break;
case 38: //UP
user.move('n');
break;
case 39: //RIGHT
user.move('e');
break;
case 40: //DOWN
user.move('s');
break;
case 90: // Z
user.shot();
}
}, true
);
window.addEventListener(
'keyup', function(e){
e.stopPropagation();
switch(e.keyCode){
case 37: //LEFT
user.move('W');
break;
case 38: //UP
user.move('N');
break;
case 39: //RIGHT
user.move('E');
break;
case 40: //DOWN
user.move('S');
break;
}
}, true
);
Game.start();
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。