/* * Atsushi YAMAMOTO * Copyright (c) 2004- Atsushi YAMAMOTO. All rights reserved. * * Krogue is a rogue-like game that can be played on AH-K3001V. */ /* * グローバル変数 */ var WALL = "#"; var SPACE = "#"; var STAIR = "%"; var MAPID = "map"; var DEBUGID = "debug"; var STATUSID = "status"; // HTML中でのステータスをいれる部分のID var STATUSID2 = "status2"; // HTML中でのステータスをいれる部分のID var ITEMSELECTID = "items"; var MAP = null; var DEBUG = null; var STATUS = null; var ITEMSELECT = null; var NOTFOUND = 100; var WIDTH = 6; // 見える領域(横) var HEIGHT = 5; // 見える領域(縦) var ending = false; var ITEMMAX = 10; /* * 初期化処理 */ function init(){ MAP = document.getElementById(MAPID); DEBUG = document.getElementById(DEBUGID); STATUS = document.getElementById(STATUSID); STATUS2 = document.getElementById(STATUSID2); ITEMSELECT = document.getElementById(ITEMSELECTID); d = new Dungeon(8, 7); // とりあえずのマップの大きさ(この2倍+1になる) h = new Hero(d); Character.member.pop(); Character.member.unshift(h); } /* * 現在の階層に応じた敵を出現させる. */ function newEnemy(d){ var tmp = Math.floor(d.stair + Math.sqrt(Math.random()*(d.stair*6))); switch(tmp){ case 1: case 4: case 6: return new EnemyS(d); case 2: case 7: return new EnemyB(d); case 3: case 9: return new EnemyE(d); case 7: case 10: return new EnemyK(d); case 5: case 8: case 11: return new EnemyH(d); case 14: case 16: case 19: return new EnemyZ(d); case 12: case 15: case 19: return new EnemyQ(d); case 13: case 17: case 20: return new EnemyC(d); case 18: case 22: case 24: return new EnemyF(d); case 21: case 23: case 26: return new EnemyY(d); case 28: case 31: case 35: return new EnemyT(d); case 25: case 27: case 29: case 38: return new EnemyP(d); case 28: case 30: case 37: case 42: return new EnemyG(d); default: return new EnemyD(d); } } /* * AH-K3001V用の設定. * キーに応じて動かす. */ function keyDown(){ switch(event.keyCode){ case 100: case 52: left(); break; case 102: case 54: right(); break; case 104: case 50: up(); break; case 98: case 56: down(); break; case 101: case 53: update(); break; case 35: downstair(); break; default: } } /* * マップをHTML内に表示させる. */ function toHTML(str){ MAP.innerHTML = str; } /* * ステータス行1(マップ下)への表示 */ function status(str){ STATUS.innerHTML = str; } /* * ステータス行2(マップ上)への表示 */ function status2(str){ STATUS2.innerHTML = str; } /* * デバッグ用(本番では用いない) */ function debug(str){ DEBUG.innerHTML = str; } /* * 主人公が左へ進む(フォームやAH-K3001Vのボタンで駆動される) */ function left(){ if(h.left()) update(); } /* * 主人公が右へ進む(フォームやAH-K3001Vのボタンで駆動される) */ function right(){ if(h.right()) update(); } /* * 主人公が上へ進む(フォームやAH-K3001Vのボタンで駆動される) */ function up(){ if(h.up()) update(); } /* * 主人公が下へ進む(フォームやAH-K3001Vのボタンで駆動される) */ function down(){ if(h.down()) update(); } /* * 主人公が選択したアイテムを使う */ function useItem(){ if(h.item(ITEMSELECT.selectedIndex)) update(); } /* * 階段を下に下りる */ function downstair(){ if(d.stairx == h.x && d.stairy == h.y){ d.downstair(); Character.assign(h, d); Character.member.unshift(h); status2("階段を下った"); h.stop = false; display(); } } /* * 敵を動かし,表示のアップデートを行なう * ついでに,敵が少なかったら(見えない場所に)生成 */ function update(){ if(ending){ end(); cookiereset(); init(); return; } for(var i = 0; i < Character.member.length; i++){ Character.member[i].update(); } if(Math.floor(h.hp) <= 0){ display(); alert("rest in peace"); cookiereset(); startgame(); }else{ h.takerest(); if(Character.member.length < 5 && Math.floor(Math.random() * 15) == 0){ e = newEnemy(d); if(Math.abs(h.x - e.x) < WIDTH+1 && Math.abs(h.x - e.x) < HEIGHT+1){ Character.member.pop(e); } } display(); } } /* * マップやステータス行の表示を呼び出す */ function display(){ d.display(h.x, h.y); status("B" + d.stair + "(" + h.x + "," + h.y + ") " + Math.floor(h.hp) + "/" + h.maxhp + " "+Math.floor(h.hunger/10) + "
L." + h.level + " E." + h.exp + " A." + h.attackp + " G."+h.money); } /* * エンディング(と言えないほどのものだが)を呼び出す */ function end(){ alert("おめでとう\nあなたは地下深くに咲く\n一輪の花を見つけました\n\n記録\n地下"+d.stair + "階/レベル" + h.level+ "/" + h.money + "G"); alert("新たな旅をはじめます"); ending = false; } /* * セーブ */ function save(){ var date = new Date(); document.cookie=""; date.setTime(date.getTime() + (60*24*3600*1000)); // expireする日付(60日) var datestr = date.toGMTString(); var itemstr = ""; if(ITEMSELECT.options.length > 0){ itemstr += ITEMSELECT.options[0].value; } for(var i = 1; i < ITEMSELECT.options.length; i++){ itemstr += "," + ITEMSELECT.options[i].value; } document.cookie='rg_data=' + Math.floor(h.hp) + "," + h.maxhp + "," + h.exp + "," + h.money + "," + h.attackp + "," + d.stair + "," + h.hunger + "," + itemstr + '; expires=' + datestr + ';'; // alert("保存しました"); } /* * データ消去 */ function cookiereset(){ var date = new Date(); date.setTime(date.getTime() - 10000); // 過去の期限にしてみる document.cookie='rg_data=; expires=' + date.toGMTString() + ';'; } /* * ゲームスタート * セーブデータがあれば,そのデータをロード */ function startgame(){ var cookie = document.cookie; init(); if(cookie.match(/rg_data=([^;]+)/)){ // セーブデータあり var data = RegExp.$1.split(","); h.hp = parseInt(data[0]); h.maxhp = parseInt(data[1]); h.exp = parseInt(data[2]); h.money = parseInt(data[3]); h.attackp = parseInt(data[4]); d.stair = parseInt(data[5]); h.hunger = parseInt(data[6]); while(h.exp> h.level*h.level*h.level+3*h.level*h.level){ h.level++; } ITEMSELECT.options.length = 0; for(var i = 7; i < data.length && i < 7+ITEMMAX; i++){ h.getItem(data[i]); } status2("冒険を再開します"); }else{ h.getItem(0); h.getItem(1); status2("洞窟へようこそ"); } display(); } /* * ダンジョンクラス * マップや階層を保持.階が進むと,init()してマップを再生成 */ function Dungeon(w, h){ // インスタンス変数 this.width = 2*w+1; this.height = 2*h+1; this.stair = 1; this.map = initArray(this.width, this.height); /* * マップの初期化(壁や,アイテム,敵など) */ Dungeon.prototype.init = function(){ for(var y = 0; y < this.height; y++){ this.map[0][y] = this.map[this.width-1][y] = WALL; } for(var x = 0; x < this.width; x++){ this.map[x][0] = this.map[x][this.height-1] = WALL; } for(var y = 1; y < this.height-1; y++){ for(var x = 1; x < this.width-1; x++){ if(x % 2 == 0 && y % 2 == 0) this.map[x][y] = WALL; else this.map[x][y] = SPACE; } } for(var y = 2; y < this.height-1; y+=2){ switch(Math.floor(Math.random() * 4)){ case 0: this.map[1][y] = WALL; break; case 1: this.map[3][y] = WALL; break; case 2: this.map[2][y-1] = WALL; break; case 3: this.map[2][y+1] = WALL; break; } } for(var y = 2; y < this.height-1; y+=2){ for(var x = 4; x < this.width-1; x+=2){ switch(Math.floor(Math.random() * 3)){ case 0: this.map[x+1][y] = WALL; break; case 1: this.map[x][y-1] = WALL; break; case 2: this.map[x][y+1] = WALL; break; } } } while(true){ var x = Math.floor(Math.random() * this.width); var y = Math.floor(Math.random() * this.height); if(this.map[x][y] != WALL){ this.stairx = x; this.stairy = y; break; } } Character.member = new Array(); Item.list = new Array(); Money.list = new Array(); var item_num = Math.floor(Math.random()*3.5+1); var enemy_num = 4; if(Math.random() < 0.01){ enemy_num = 8 + Math.floor(15*Math.random()); item_num += 5; } for(var i = 0; i < enemy_num; i++){ newEnemy(this); } for(var i = 0; i < item_num; i++){ new Item(this); } new Money(this);new Money(this); } function initArray(x, y){ a = new Array(x); for(var i = 0; i < x; i++){ a[i] = new Array(y); } return a; } /* * 下の階に下りる際の,ダンジョンの更新 */ Dungeon.prototype.downstair = function(){ this.stair++; save(); this.init(); } /* * ダンジョンのマップへの表示 */ Dungeon.prototype.display = function(x, y){ var str = ""; var tmparray = initArray(this.width, this.height); tmparray[this.stairx][this.stairy] = STAIR; for(var i = 0; i < Item.list.length; i++){ var c = Item.list[i]; tmparray[c.x][c.y] = c.mark; } for(var i = 0; i < Money.list.length; i++){ var c = Money.list[i]; tmparray[c.x][c.y] = c.mark; } for(var i = 0; i < Character.member.length; i++){ var c = Character.member[i]; tmparray[c.x][c.y] = c.mark; } for(var j = y-HEIGHT; j <= y+HEIGHT; j++){ for(var i = x-WIDTH; i <= x+WIDTH; i++){ if(i < 0 || j < 0 || i >= this.width || j >= this.height) str += WALL; else if(tmparray[i][j] != null) str += tmparray[i][j]; else str += this.map[i][j]; } str += "
"; } toHTML(str); } this.init(); } /* * キャラクタクラス * 敵や主人公のスーパークラス * 配置や共通のメソッドやフィールドを定義 */ function Character(d){ this.dungeon = d; this.mark = "?"; // マップ表示での記号 this.attackp = 2; // 攻撃力 this.hp = 10; // HP this.maxhp = 0; // 最大HP this.hunger = 1000; this.stop = false; // はえとりぐさ用 Character.m = d.map; Character.assign(this, d); Character.member.push(this); } /* * 配置用クラスメソッド */ Character.assign = function(ch, d){ out:while(true){ var x = Math.floor(Math.random() * d.width); var y = Math.floor(Math.random() * d.height); if(d.map[x][y] == SPACE){ for(var i = 0; i < Character.member.length; i++){ var c = Character.member[i]; if(x == c.x && y == c.y) continue out; } ch.x = x; ch.y = y; break; } } } /* * 移動インスタンスメソッド */ Character.prototype.move = function(x, y){ this.x = x; this.y = y; } /* * 休憩(つまり,HP回復)インスタンスメソッド * 現在は主人公のみを回復させている */ Character.prototype.takerest = function(){ this.hp += this.maxhp/120; if(this.maxhp < this.hp) this.hp = this.maxhp; this.hunger--; } /* * 移動可能判定インスタンスメソッド */ Character.prototype.movable = function(x, y){ if(Character.m[x][y] == WALL) return false; else{ for(var i = 0; i < Character.member.length; i++){ var c = Character.member[i]; if(x == c.x && y == c.y) return i; } if(this.stop){ status2("動けない!"); return false; }else{ return true; } } } /* * 攻撃インスタンスメソッド */ Character.prototype.attack = function(opid, plus){ if(this.attackp == 0) return false; var op = Character.member[opid]; if(Math.floor(Math.random()*10) < 1){ return false; }else{ op.hp -= (this.attackp+plus)*(-Math.random()*0.5+1.3); if(op.hp <= 0){ if(this == h){ status2(Enemy.names[op.mark] + "を倒した"); if(op.mark == "F"){ this.stop = false; } } this.exp += op.exp; Character.member.splice(opid, 1); // die } return true; } } /* * 主人公クラス * Character を継承し,必要なメソッドをオーバーライド. */ function Hero(d){ this.temp = Character; this.temp(d); // 親クラスのコンストラクタを呼ぶ this.mark = "@"; this.hp = 12; this.money = 0; this.attackp = 4; this.maxhp = 12; this.exp = 0; this.level = 1; ITEMSELECT.options.length = 0; } // とりあえず継承 force_inherit(Hero, Character); /* * アイテム取得時の操作.(メソッドでなくてもよかったかも.) */ Hero.prototype.getItem = function(itemid){ ITEMSELECT.options[ITEMSELECT.options.length] = new Option(Item.names[itemid], itemid); } /* * 移動インスタンスメソッド * 移動/攻撃できると判定したら,適宜動作する. * 攻撃時には,レベルアップ判定なども行なう.移動時にはアイテム取得判定. */ Hero.prototype.move = function(x, y){ var m = this.movable(x, y); if(Character.member[m] != null){ status2("攻撃"); if(!this.attack(m, 0)){ status2("攻撃がかわされた"); } if(this.level < 30 && this.exp > this.level*this.level*this.level+3*this.level*this.level){ this.level++; this.attackp += 1 + Math.floor(Math.random(Math.random()*2)); var up = Math.floor(this.maxhp * 0.1 + 2); this.maxhp += up; this.hp += up; status2("levelアップ"); save(); } return true; }else if(m == true){ this.x = x; this.y = y; for(var i = 0; i < Item.list.length; i++){ var item = Item.list[i]; if(x == item.x && y == item.y){ if(ITEMSELECT.options.length < ITEMMAX){ // アイテムはITEMMAX個までしか持てない Item.list.splice(i, 1); this.getItem(item.id); status2(Item.names[item.id] + "を拾った"); if(item.id == Item.names.length-1) // これはエンディングね. ending = true; }else{ status2(Item.names[item.id] + "がある"); } } } for(var i = 0; i < Money.list.length; i++){ var money = Money.list[i]; if(x == money.x && y == money.y){ this.money += money.q; status2(money.q + "Gを拾った"); Money.list.splice(i, 1); } } return true; }else{ return false; } } /* * アイテム使用インスタンスメソッド * きれいに書くなら,Itemクラスに持っていくべきだろう. */ Hero.prototype.item = function(selectid){ if(selectid < 0) return false; var itemid = parseInt(ITEMSELECT.options[selectid].value); for(var i = selectid; i < ITEMSELECT.options.length-1; i++){ ITEMSELECT.options[i].text = ITEMSELECT.options[i+1].text; ITEMSELECT.options[i].value = ITEMSELECT.options[i+1].value; } ITEMSELECT.options.length = ITEMSELECT.options.length-1; status2(Item.names[itemid] + "を使った"); switch(itemid){ case 0: // つるはし for(var i = this.x-1; i <= this.x + 1 && i < this.dungeon.width-1; i++){ if(i <= 0) continue; for(var j = this.y-1; j <= this.y + 1 && j < this.dungeon.height-1; j++){ if(j <= 0) continue; Character.m[i][j] = SPACE; } } break; case 1: // 薬草 this.hunger += 40; if(this.hp < this.maxhp){ this.hp += 20 + 8 * (Math.random()-0.5); }else{ this.maxhp++;this.hp++; } break; case 2: // 雷の巻物 for(var i = 0; i < Character.member.length; i++){ var c = Character.member[i]; if(c == this || c.x < this.x-1 || c.x > this.x+1 || c.y < this.y-1 || c.y > this.y+1)continue; this.attack(i, this.attackp * 8); } break; case 3: // ワープ草 this.hunger += 40; Character.assign(this, d); this.stop = false; break; case 4: // 光の水 this.hunger += 20; if(this.hp < this.maxhp){ this.hp = this.maxhp; }else{ this.maxhp+=2;this.hp+=2; } break; case 5: // 乾パン this.hunger += 800; break; case 6: // キノコ var rand = Math.floor(Math.random() * 4); if(rand == 0){ this.hunger += 30; status2("毒キノコだった"); if(this.attackp > 2){ this.attackp--; } }else if(rand == 1){ this.attackp++; this.hunger += 70; status2("力が湧いてきた"); }else{ this.hunger += 300; status2("おいしかった"); } break; } if(this.hunger > 1000){ this.hunger = 1000; } return true; } /* * 左に移動するインスタンスメソッド */ Hero.prototype.left = function(){ return this.move(this.x-1, this.y); } /* * 右に移動するインスタンスメソッド */ Hero.prototype.right = function(){ return this.move(this.x+1, this.y); } /* * 上に移動するインスタンスメソッド */ Hero.prototype.up = function(){ return this.move(this.x, this.y-1); } /* * 下に移動するインスタンスメソッド */ Hero.prototype.down = function(){ return this.move(this.x, this.y+1); } Hero.prototype.update = function(){ if(this.hunger <= 0){ this.hunger = 0; this.hp--; } } /* * 敵クラスのスーパークラス. * Characterクラスをオーバーライドしている. * ヘビなど特殊能力のない敵は,このクラスを継承して, * インスタンス変数だけを書き換えれば十分である. */ function Enemy(d){ this.temp = Character; this.temp(d); this.mark = "!"; this.direction = Math.floor(Math.random() * 4); // 向き } force_inherit(Enemy, Character); /* * 更新インスタンスメソッド(つまり,主人公のターンが終わったので何か動作する) */ Enemy.prototype.update = function(){ var f = this.find() if(f != -1){ this.direction = f; } if(!this.move(this.direction)){ while(!this.move(Math.floor(Math.random() * 4.5))){} } } /* * 移動インスタンスメソッド * 0-4が上下左右に対応している * 移動/攻撃する. */ Enemy.prototype.move = function(num){ this.direction = num; var x, y; switch(num){ case 0: x = this.x + 1; y = this.y; break; case 1: x = this.x - 1; y = this.y; break; case 2: x = this.x; y = this.y + 1; break; case 3: x = this.x; y = this.y - 1; break; default: this.direction = Math.floor(Math.random() * 4) return true; } var m = this.movable(x, y); if(Character.member[m] == h){ this.attack(m, 0); return true; }else if(Character.member[m] != null){ return false; }else if(m == true){ this.x = x; this.y = y; return true; }else{ return false; } } /* * 移動の方向の判定を行なう. * 主人公が近くにいなければ,判定しない. * 近くにいれば,trace()を呼び出す. */ Enemy.prototype.find = function(){ // 主人公を追い掛ける var diffx = h.x - this.x; var diffy = h.y - this.y; if(Math.abs(diffx) >= 5 || Math.abs(diffy) >= 5){ return -1; }else{ return this.trace(this.x, this.y, h.x, h.y, 0); } } /* * 再帰的に主人公の場所を追う. * いい加減なメソッドなので,つるはしを使った後など,重くなる */ Enemy.prototype.trace = function (sx, sy, ex, ey, t){ if(Character.m[sx][sy] == WALL || t > 5){ return NOTFOUND; } if(sx == ex && sy == ey){ return t; } var step = this.trace(sx+1, sy, ex, ey, t+1); var step2 = this.trace(sx-1, sy, ex, ey, t+1); var step3 = this.trace(sx, sy+1, ex, ey, t+1); var step4 = this.trace(sx, sy-1, ex, ey, t+1); if(t != 0){ if(step > step2) step = step2; if(step > step3) step = step3; if(step > step4) step = step4; return step; }else{ var tmp = 0; if(step > step2){ step = step2; tmp = 1; } if(step > step3){ step = step3; tmp = 2; } if(step > step4){ step = step4; tmp = 3; } if(step != NOTFOUND) return tmp; else return -1; } } Enemy.names = new Array(); /* * へび(S) * 特に何もなし.弱い. */ function EnemyS(d){ this.temp = Enemy; this.temp(d); this.mark = "S"; this.hp = 9; this.exp = 1; Enemy.names[this.mark] = "へび"; } force_inherit(EnemyS, Enemy); /* * 大うずら(E) * 特に何もなし.弱い. */ function EnemyE(d){ this.temp = Enemy; this.temp(d); this.mark = "E"; this.hp = 13; this.exp = 2; Enemy.names[this.mark] = "大うずら"; } force_inherit(EnemyE, Enemy); /* * 大はやぶさ(K) * 1ターンで二度の移動が可能.(移動+攻撃や攻撃+攻撃は不可能) * HPは低い */ function EnemyK(d){ this.temp = Enemy; this.temp(d); this.mark = "K"; this.hp = 9; this.exp = 2; Enemy.names[this.mark] = "大はやぶさ"; } force_inherit(EnemyK, Enemy); EnemyK.prototype.update = function(){ var f = this.find() var x = this.x; var y = this.y; if(f != -1){ this.direction = f; } if(!this.move(this.direction)){ while(!this.move(Math.floor(Math.random() * 4.5))){} } if(x != this.x || y != this.s){ // 1ターン目で移動した時 var tmpatp = this.attackp; this.attackp = 0; f = this.find() if(f != -1){ this.direction = f; } if(!this.move(this.direction)){ while(!this.move(Math.floor(Math.random() * 4.5))){} } this.attackp = tmpatp; } } /* * 大こうもり(B) * ランダムに動作するので注意 */ function EnemyB(d){ this.temp = Enemy; this.temp(d); this.mark = "B"; this.hp = 9; this.exp = 1; Enemy.names[this.mark] = "大こうもり"; } force_inherit(EnemyB, Enemy); EnemyB.prototype.update = function(){ this.direction = Math.floor(Math.random() * 4); if(!this.move(this.direction)){ while(!this.move(Math.floor(Math.random() * 4.5))){} } } /* * 小鬼(H) * ヘビなどよりは強い */ function EnemyH(){ this.temp = Enemy; this.temp(d); this.mark = "H"; this.hp = 17; this.attackp = 3; this.exp = 4; Enemy.names[this.mark] = "小鬼"; } force_inherit(EnemyH, Enemy); /* * ゾンビ(Z) * 特徴はない */ function EnemyZ(d){ this.temp = Enemy; this.temp(d); this.mark = "Z"; this.hp = 26; this.attackp = 5; this.exp = 9; Enemy.names[this.mark] = "ゾンビ"; } force_inherit(EnemyZ, Enemy); /* * 大つのじか(Q) * 少し強くなってきた */ function EnemyQ(d){ this.temp = Enemy; this.temp(d); this.mark = "Q"; this.hp = 34; this.attackp = 7; this.exp = 18; Enemy.names[this.mark] = "大つのじか"; } force_inherit(EnemyQ, Enemy); /* * ケンタウロス(C) * 最初は逃げた方がよい */ function EnemyC(d){ this.temp = Enemy; this.temp(d); this.mark = "C"; this.hp = 45; this.attackp = 9; this.exp = 24; Enemy.names[this.mark] = "ケンタウロス"; } force_inherit(EnemyC, Enemy); /* * はえとりぐさ(F) * 主人公が周りに来ると足を捕まえる * 倒すまで動けない */ function EnemyF(d){ this.temp = Enemy; this.temp(d); this.mark = "F"; this.hp = 45; this.attackp = 6; this.exp = 21; Enemy.names[this.mark] = "はえとりぐさ"; } force_inherit(EnemyF, Enemy); EnemyF.prototype.update = function(){ if(this.x-1 == h.x && this.y == h.y || this.x+1 == h.x && this.y == h.y || this.x == h.x && this.y+1 == h.y || this.x == h.x && this.y-1 == h.y){ this.attack(0, 0); } } EnemyF.prototype.attack = function(opid, plus){ this.tmp = Enemy.prototype.attack; this.tmp(opid, 0); h.stop = true; } /* * 雪男(Y) * 力があるので注意 */ function EnemyY(d){ this.temp = Enemy; this.temp(d); this.mark = "Y"; this.hp = 59; this.attackp = 15; this.exp = 32; Enemy.names[this.mark] = "雪男"; } force_inherit(EnemyY, Enemy); /* * 巨人(T) * トロールです.逃げたくなる. */ function EnemyT(d){ this.temp = Enemy; this.temp(d); this.mark = "T"; this.hp = 84; this.attackp = 19; this.exp = 40; Enemy.names[this.mark] = "巨人"; } force_inherit(EnemyT, Enemy); /* * 幽霊(P) * 姿が見えない.アイテムなどの上に来たときは少しチャンス? */ function EnemyP(d){ this.temp = Enemy; this.temp(d); this.mark = SPACE; this.hp = 65; this.attackp = 15; this.exp = 45; Enemy.names[this.mark] = "幽霊"; } force_inherit(EnemyP, Enemy); /* * 翼ライオン(G) * グリフォンです. * 1ターンに二回動ける */ function EnemyG(d){ this.temp = Enemy; this.temp(d); this.mark = "G"; this.hp = 115; this.attackp = 22; this.exp = 110; Enemy.names[this.mark] = "翼ライオン"; } force_inherit(EnemyG, Enemy); EnemyG.prototype.update = function(){ this.temp = Enemy.prototype.update; this.temp(); this.temp(); } /* * ドラゴン(D) * 二マス離れた直線上から攻撃可能 */ function EnemyD(d){ this.temp = Enemy; this.temp(d); this.mark = "D"; this.hp = 145; this.attackp = 26; this.exp = 140; Enemy.names[this.mark] = "ドラゴン"; } force_inherit(EnemyD, Enemy); EnemyD.prototype.update = function(){ if(this.x-2 == h.x && this.y == h.y && this.movable(this.x-1, this.y) == true || this.x+2 == h.x && this.y == h.y && this.movable(this.x+1, this.y) == true || this.x == h.x && this.y-2 == h.y && this.movable(this.x, this.y-1) == true || this.x == h.x && this.y+2 == h.y && this.movable(this.x, this.y+1) == true){ this.attack(0, -5); }else{ this.temp = Enemy.prototype.update; this.temp(); } } /* * 落ちているお金 */ function Money(d){ Money.assign(this, d); this.mark = "*"; this.q = Math.floor(Math.random()*d.stair*5+1); Money.list.push(this); } /* * お金の配置を決めるクラスメソッド * アイテムのない場所に設置する. */ Money.assign = function(ch, d){ out:while(true){ var x = Math.floor(Math.random() * d.width); var y = Math.floor(Math.random() * d.height); if(d.map[x][y] == SPACE){ for(var i = 0; i < Item.list.length; i++){ var c = Item.list[i]; if(x == c.x && y == c.y) continue out; } for(var i = 0; i < Money.list.length; i++){ var c = Money.list[i]; if(x == c.x && y == c.y) continue out; } ch.x = x; ch.y = y; break; } } } /* * 落ちているアイテムなど */ function Item(d){ Item.assign(this, d); this.mark = "?"; if(d.stair < 27){ this.id = Math.floor(Math.random()*(Item.names.length-1)); }else{ this.id = Math.floor(Math.random()*(Item.names.length)); } Item.list.push(this); } Item.names = new Array("つるはし", "薬草", "雷の巻物", "ワープ草", "光の水", "乾パン", "キノコ", "一輪の花"); /* * アイテムの配置を決める */ Item.assign = function(ch, d){ out:while(true){ var x = Math.floor(Math.random() * d.width); var y = Math.floor(Math.random() * d.height); if(d.map[x][y] == SPACE){ for(var i = 0; i < Item.list.length; i++){ var c = Item.list[i]; if(x == c.x && y == c.y) continue out; } ch.x = x; ch.y = y; break; } } }