はてなハイク STAR FIGHTERS
by
lieutar
2010-12-30 [2010/12/30 15:12:55]
はてなハイクで実行すると、星を打ちあう簡単な対戦型シューティングが初まる。カーソルキーで移動、Zで星発射。ESCで終了
@@ -8,294 +8,336 @@
(function(){
- var Z_INDEX_USER = 65536;
- var Z_INDEX_BULLET = 65535;
+ 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 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;
+ Object, function(SUPER, Class){
+ var counter = 0;
+
+ this.initialize = function(x,y){
+ this.key = 'elem_'+ counter++;
+ this._x = x;
+ this._y = y;
+ this._pre_x = NaN;
+ this._pre_y = NaN;
+ this._spped = 1;
+ this._dx = 0;
+ this._dy = 0;
+ this._pdx = 0;
+ this._pdy = -1;
+ this._img = null;
+ Game.registerElement(this);
+ };
+
+
+ this.initImage = function(url){
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.style.position = 'fixed';
+ img.style.zIndex = '65536';
+ img.src = url;
+ this._img = img;
+ return img;
+ };
+
+ this.setSpeed = function(s){
+ this._speed = s;
+ };
+
+ this.getPosition = function(){
+ return {
+ x: this._x ,
+ y: this._y
+ };
+ };
+
+ this.getSpeed = function(){ return this._speed; };
+
+ this.setDirection = function(x, y){
+ this._dx = x;
+ this._dy = y;
+ };
+
+ this.getDirection = function(){
+ return { x:this._dx, y:this._dy };
+ };
+
+ this.setShotDirection = function(x,y){
+ this._pdx = x;
+ this._pdy = y;
+ };
+
+ this.getShotDirection = function(){
+ return { x:this._pdx, y:this._pdy };
+ };
+
+ this.step = function(){
+ this._pre_x = this._x;
+ this._pre_y = this._y;
+ this._x = this._x + this._dx * this._speed;
+ this._y = this._y + this._dy * this._speed;
+ };
+
+ 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.getTrack = function(){
+ var R = 0;
+ return R;
+ };
+
+ this.onHit = function(){
+ };
- this.initialize = function(){
- this.key = 'elem_'+ counter++;
- Game.registerElement(this);
- };
-
- this.step = function(){
- };
-
- this.redraw = function(){
- };
-
- this.getTrack = function(){
- };
-
- this.onHit = function(){
- };
- }
+ this.onScreen = function(){
+ var sx = this._x;
+ var sy = this._y;
+ return (sx > 0 && sx < window.innerWidth &&
+ sy > 0 && sy < window.innerHeight);
+ };
+ }
);
var Bullet = inherit(
- GameElement, function(SUPER, Class){
+ GameElement, function(SUPER, Class){
+ this.initialize = function(x,y){
+ SUPER.initialize.apply(this,[x, y]);
+ this.setDirection(0,-1);
+ this.setSpeed(10);
+ this.initImage('http://s.hatena.ne.jp/images/star.gif');
+ };
- 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.step = function(){
+ SUPER.step.apply(this, []);
+ if(!this.onScreen()) this._dispose = true;
+ };
+ }
);
var User = inherit(
- GameElement, function(SUPER,Class){
+ 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';
- };
-
- }
- );
+ this.initialize = function(name){
+ SUPER.initialize.apply(this,[0,0]);
+ this.name = name;
+ var img = this.initImage(
+ 'http://www.st-hatena.com/users/' + name.substring(0,2) +
+ '/' + name + '/profile.gif'
+ );
+ this.setSpeed(5);
+ this._move_k = {n:0,s:0,w:0,e:0};
+ this._x =
+ Math.floor((window.innerWidth - img.clientWidth ) / 2
+ );
+ this._y =
+ (window.innerHeight - img.clientHeight - 10);
+ this.setShotDirection(0,-1);
+ };
- 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
- );
+ this.getHotSpot = function(){
+ var img = this._img;
+ return {
+ x: Math.floor(this._x + img.clientWidth / 2),
+ y: Math.floor(this._y + img.clientHeight / 2)
+ };
+ };
- 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
- );
+ this.getSpeed = function(){
+ var dir = this.getDirection();
+ if(dir.x == 0 && dir.y == 0) return 0;
+ return SUPER.getSpeed.apply(this);
+ };
- Game.start();
+ this.shot = function(){
+ var pos = this.getPosition();
+ var bullet = new Bullet(pos.x, pos.y);
+ var dir = this.getShotDirection();
+ bullet.setDirection(dir.x, dir.y);
+ bullet.setSpeed(this.getSpeed() + 2);
+ };
-})();
+ this.setDirection = function(x,y){
+ SUPER.setDirection.apply(this, [x,y]);
+ if(x != 0 || y != 0) this.setShotDirection(x, 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.setDirection(x,y);
+ };
+
+
+ }
+ );
+
+ 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();
+ e.preventDefault();
+ // 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();
+ e.preventDefault();
+ 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(x,y){
this.key = 'elem_'+ counter++;
this._x = x;
this._y = y;
this._pre_x = NaN;
this._pre_y = NaN;
this._spped = 1;
this._dx = 0;
this._dy = 0;
this._pdx = 0;
this._pdy = -1;
this._img = null;
Game.registerElement(this);
};
this.initImage = function(url){
var img = document.createElement('img');
document.body.appendChild(img);
img.style.position = 'fixed';
img.style.zIndex = '65536';
img.src = url;
this._img = img;
return img;
};
this.setSpeed = function(s){
this._speed = s;
};
this.getPosition = function(){
return {
x: this._x ,
y: this._y
};
};
this.getSpeed = function(){ return this._speed; };
this.setDirection = function(x, y){
this._dx = x;
this._dy = y;
};
this.getDirection = function(){
return { x:this._dx, y:this._dy };
};
this.setShotDirection = function(x,y){
this._pdx = x;
this._pdy = y;
};
this.getShotDirection = function(){
return { x:this._pdx, y:this._pdy };
};
this.step = function(){
this._pre_x = this._x;
this._pre_y = this._y;
this._x = this._x + this._dx * this._speed;
this._y = this._y + this._dy * this._speed;
};
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.getTrack = function(){
var R = 0;
return R;
};
this.onHit = function(){
};
this.onScreen = function(){
var sx = this._x;
var sy = this._y;
return (sx > 0 && sx < window.innerWidth &&
sy > 0 && sy < window.innerHeight);
};
}
);
var Bullet = inherit(
GameElement, function(SUPER, Class){
this.initialize = function(x,y){
SUPER.initialize.apply(this,[x, y]);
this.setDirection(0,-1);
this.setSpeed(10);
this.initImage('http://s.hatena.ne.jp/images/star.gif');
};
this.step = function(){
SUPER.step.apply(this, []);
if(!this.onScreen()) this._dispose = true;
};
}
);
var User = inherit(
GameElement, function(SUPER,Class){
this.initialize = function(name){
SUPER.initialize.apply(this,[0,0]);
this.name = name;
var img = this.initImage(
'http://www.st-hatena.com/users/' + name.substring(0,2) +
'/' + name + '/profile.gif'
);
this.setSpeed(5);
this._move_k = {n:0,s:0,w:0,e:0};
this._x =
Math.floor((window.innerWidth - img.clientWidth ) / 2
);
this._y =
(window.innerHeight - img.clientHeight - 10);
this.setShotDirection(0,-1);
};
this.getHotSpot = function(){
var img = this._img;
return {
x: Math.floor(this._x + img.clientWidth / 2),
y: Math.floor(this._y + img.clientHeight / 2)
};
};
this.getSpeed = function(){
var dir = this.getDirection();
if(dir.x == 0 && dir.y == 0) return 0;
return SUPER.getSpeed.apply(this);
};
this.shot = function(){
var pos = this.getPosition();
var bullet = new Bullet(pos.x, pos.y);
var dir = this.getShotDirection();
bullet.setDirection(dir.x, dir.y);
bullet.setSpeed(this.getSpeed() + 2);
};
this.setDirection = function(x,y){
SUPER.setDirection.apply(this, [x,y]);
if(x != 0 || y != 0) this.setShotDirection(x, 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.setDirection(x,y);
};
}
);
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();
e.preventDefault();
// 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();
e.preventDefault();
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 です。