//--------------------------------------------------------------------// // 3DダンジョンRPG ver.1.1 // //--------------------------------------------------------------------// // クラス一覧 // interface Parameters パラメータインターフェイス // interface Message メッセージインターフェイス // class DungeonRPG メイン // class DungeonViewPanel ダンジョン表示部分 // class ControlButton コントロールボタンクラス // class StatusPanel ステータス表示パネル // class DungeonMessagePanel メッセージパネル // class ItemListPanel アイテムリストパネル // class ImageData イメージクラス // class DungeonData ダンジョンデータ // class Floor 階層データ // class MapGrid マップ1マスのデータ // class MonsterMap ワンダリングモンスター分布クラス // class KeyDoor 鍵付き扉クラス // class Event イベントクラス // class Elevator エレベータークラス // class Item アイテムクラス // class Character キャラクタークラス // class Player プレイヤークラス // class Monster モンスタークラス // class draw2D 2次元マップ表示 // class draw3D 3次元マップ表示 //--------------------------------------------------------------------// import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.lang.*; import java.util.*; import java.io.*; import java.net.URL; //--------------------------------------------------------------------// // パラメータインターフェイス interface Parameters{ static final int UP1=38; // キーコード static final int LEFT1=37; static final int RIGHT1=39; static final int DOWN1=40; static final int UP2=104; static final int LEFT2=100; static final int RIGHT2=102; static final int DOWN2=98; static final int NORTH=0; // プレイヤーの向いている方向 static final int EAST=1; static final int SOUTH=2; static final int WEST=3; static final int NONE=0; // ボタン・パネル選択 static final int MOVE=1; static final int FORWARD=2; static final int LEFT=3; static final int RIGHT=4; static final int BACK=5; static final int VIEWSW=6; static final int EVENT=7; static final int YESNO=8; static final int YES=9; static final int NO=10; static final int ELEVATOR=11; static final int BATTLE=12; static final int ATTACK=13; static final int ESCAPE=14; static final int ITEM=15; static final int USE=16; static final int DROP=17; static final int NOEVENT=0; // イベント選択 static final int START=1; static final int GOAL=2; static final int UPSTAIR=3; static final int DOWNSTAIR=4; static final int WARP1WAY=5; static final int WARP2WAY=6; static final int ELEVATORIN=7; static final int ITEMGET=8; static final int ENCOUNT=9; static final int MESSAGE=10; static final int HEAL=11; static final int NOSELECT=-1; // アイテム・エレベーター階層未選択 static final int SELECT=1; // イベント選択肢の種類 static final int EVSELECT=2; static final int MSSWITCH[]= {NOSELECT,NOSELECT,NOSELECT,SELECT,SELECT,NOSELECT,NOSELECT,EVSELECT ,SELECT,NOSELECT,NOSELECT,SELECT}; // メッセージ表示の種類 static final int VIEW3D=0; // 視点選択 static final int VIEW2D=1; static final int WALL=1; // 壁データ static final int DOOR=2; static final int FLOORMAX=100; // 階層の上限 static final int EVENTMAX=1000; // イベントの上限 static final int WALLMAX=500000; // 壁数の上限 static final int MONSTERMAX=1000; // モンスター種類数の上限 static final int EVFLOORMAX=100; // 移動できるフロア数の上限 static final int ITEMMAX=20; // アイテム数の上限 static final int MONSTER1MAP=10; // 1マップ内モンスター種類数の上限 static final int MONSTERITEM=10; // モンスターが持っているアイテム種類数の上限 static final int EVENTLINE=100; // イベントメッセージ行数の上限 static final int MESSAGELINE=30; // 表示メッセージ行数の上限 static final int DEPTH=10; // 奥行きの最大値 static final int KEY=0; // アイテム種類 static final int CURE=1; static final int WEAPON=2; static final int DEFEND=3; static final int LVMAX=100; // レベルの最大値 static final int NOEXP=0; // 最大レベルでの次レベルの経験値表示 static final double SIGMA=0.2/Math.PI; // 攻撃ダメージの変動範囲 } //--------------------------------------------------------------------// // メッセージインターフェイス interface Message{ static final String PANELBUTTON[]={"前(8)","左(4)","右(6)","後(2)","はい(Y)","いいえ(N)" ,"視点変換(C)","攻撃(A)","逃走(E)","アイテム(I)" ,"使用(U)","捨てる(D)"}; static final String PLAYERPARAM[]={"LV: ","HP: ","AT: ","DF: ","EXP: "}; static final String SLASH="/"; static final String WEAPON="武器:",DEFEND="防具:"; static final String ENCOUNTMESSAGE="が現れた"; static final String ATTACKED="の攻撃"; static final String MONSTERDAMAGE="ポイントのダメージを与えた"; static final String PLAYERDAMAGE="ポイントのダメージを受けた"; static final String NI="に",HA="は"; static final String ESCAPEMESSAGE="は逃げ出した"; static final String ESCAPEOKMESSAGE="逃走に成功した"; static final String ESCAPENGMESSAGE="逃走に失敗した!"; static final String WINMESSAGE="を倒した"; static final String EXP="経験値",POINTGETMESSAGE="ポイント獲得した"; static final String LVUPMESSAGE="はレベルが上がった"; static final String POINTUPMESSAGE="ポイント上昇した"; static final String GETMESSAGE="を手に入れた"; static final String MAXHP="最大HPが",ATTACKP="攻撃力が",DEFENCEP="防御力が"; static final String DEADMESSAGE="は死亡しました"; static final String USEMESSAGE="を使った",NOUSEMESSAGE="は使えない"; static final String DROPMESSAGE="を捨てた",NODROPMESSAGE="は捨てられない"; static final String CUREMESSAGE="ポイント回復"; static final String EQUIPMESSAGE="を装備した"; static final String YESNOSELECT="Yes(Y) / No(N)"; } //--------------------------------------------------------------------// // メイン public class DungeonRPG extends Applet{ DungeonViewPanel dpanel; String name,iname; private Color backColor=Color.black,textColor=Color.white; private Image template=null; //--------------------------------------------------------------------// public void init(){ // データファイル名 URL base=getDocumentBase(); name=getParameter("mapdata"); if (name==null) name="sumple.dgn"; iname=getParameter("image"); if (iname==null) iname="template.gif"; getTemplateImage(iname); setLayout(new BorderLayout()); dpanel=new DungeonViewPanel(base,name,template,backColor,textColor); add("Center",dpanel); } //--------------------------------------------------------------------// public void destroy(){ remove(dpanel); } //--------------------------------------------------------------------// void getTemplateImage(String iname){ // テンプレートイメージ読み込み URL ibase=getClass().getResource(iname); MediaTracker mt=new MediaTracker(this); template=getToolkit().getImage(ibase); mt.addImage(template,0); try{ mt.waitForAll(); } catch(InterruptedException e){} } } //--------------------------------------------------------------------// // ダンジョン表示部分 class DungeonViewPanel extends Panel implements MouseListener,KeyListener,Parameters,Message{ DungeonData dd; StatusPanel spanel; String message; boolean waitsw=true; // 表示待ちスイッチ int mapView=VIEW3D; // 表示設定 int event=START; // イベント int mode=EVENT; // 状態スイッチ int panelMode=MOVE; // パネル表示スイッチ int button=NONE; // 押したボタン int itemIndex=NOSELECT; // 選択したアイテム int elevatorFloor=NOSELECT; // ボタンサブキー boolean setElevator=false; // 表示待ちスイッチ int fx,fy,fxi,fyi,x0,y0,x1,y1,esize; // 地図表示サイズ・位置 int depth=6; // 表示奥行き private Image bgImage; // ダブルバッファリング用イメージ private Graphics bg; Color backColor,textColor; // 背景色・文字色 int fontsize1=18,fontsize2=12; // 文字フォントの大きさ ControlButton forward,left,right,back,viewsw; // ボタン ControlButton yes,no,attack,escape,item,use,drop; ControlButton elevator[]=new ControlButton[FLOORMAX]; //--------------------------------------------------------------------// public DungeonViewPanel(URL base,String name,Image image ,Color backColor,Color textColor){ this.backColor=backColor; this.textColor=textColor; getData(base,name,image); setBackground(backColor); addMouseListener(this); addKeyListener(this); } //--------------------------------------------------------------------// void getData(URL base,String name,Image image){ // データ読み込み int i; InputStream is=null; message=null; try{ is=new URL(base,name).openStream(); dd=new DungeonData(is,image); } catch(Exception e){ message=e.toString(); } try{ if(is!=null) is.close(); } catch(Exception e){} } //--------------------------------------------------------------------// public void mouseClicked(MouseEvent e){ } //--------------------------------------------------------------------// public void mousePressed(MouseEvent e){ int mousex,mousey,i,flr=-1,index; if(waitsw) return; mousex=e.getX(); mousey=e.getY(); e.consume(); if(panelMode==ITEM){ mousePressedItem(mousex,mousey); } else{ switch(mode){ case MOVE: mousePressedMove(mousex,mousey); break; case EVENT: mousePressedEvent(mousex,mousey); break; case BATTLE: mousePressedBattle(mousex,mousey); break; } } repaint(); } //--------------------------------------------------------------------// public void mouseReleased(MouseEvent e){ if(waitsw) return; ReleasedAction(); repaint(); } //--------------------------------------------------------------------// public void mouseEntered(MouseEvent e){ } //--------------------------------------------------------------------// public void mouseExited(MouseEvent e){ } //--------------------------------------------------------------------// public void keyPressed(KeyEvent e){ int keyin=e.getKeyCode(); if(waitsw) return; if(panelMode==ITEM){ keyTypedItem(keyin); } else{ switch(mode){ case MOVE: keyTypedMove(keyin); break; case EVENT: keyTypedEvent(keyin); break; case BATTLE: keyTypedBattle(keyin); break; } } repaint(); } //--------------------------------------------------------------------// public void keyReleased(KeyEvent e){ if(waitsw) return; ReleasedAction(); repaint(); } //--------------------------------------------------------------------// public void keyTyped(KeyEvent e){ } //--------------------------------------------------------------------// void ReleasedAction(){ // ボタン離し時実行 switch(button){ case FORWARD: goAhead(); break; case LEFT: turnLeft(); break; case RIGHT: turnRight(); break; case BACK: turnBack(); break; case YES: eventOn(1); break; case NO: eventOff(); break; case VIEWSW: changeView(); break; case ATTACK: Attack(); break; case ESCAPE: Escape(); break; case ITEM: Item(); break; case USE: Use(dd.ipanel.index); break; case DROP: Drop(dd.ipanel.index); break; case ELEVATOR: elevator[elevatorFloor].Release(); eventOn(elevatorFloor+2); break; } button=NONE; } //--------------------------------------------------------------------// void mousePressedItem(int mousex,int mousey){ // アイテム選択時マウス入力 int index=dd.ipanel.selected(mousex,mousey); if(index==dd.ipanel.NOSELECT){ if(use.press(mousex,mousey)){ button=USE; use.Press(); } else if(drop.press(mousex,mousey)){ button=DROP; drop.Press(); } else{ panelMode=mode; } } } //--------------------------------------------------------------------// void mousePressedMove(int mousex,int mousey){ // 移動時マウス入力 if(forward.press(mousex,mousey)){ button=FORWARD; forward.Press(); } else if(left.press(mousex,mousey)){ button=LEFT; left.Press(); } else if(right.press(mousex,mousey)){ button=RIGHT; right.Press(); } else if(back.press(mousex,mousey)){ button=BACK; back.Press(); } else if(viewsw.press(mousex,mousey)){ button=VIEWSW; viewsw.Press(); } else if(item.press(mousex,mousey)){ button=ITEM; item.Press(); } } //--------------------------------------------------------------------// void mousePressedEvent(int mousex,int mousey){ // イベント時マウス入力 int i; elevatorFloor=NOSELECT; switch(MSSWITCH[dd.event[event].type]){ case SELECT: if(yes.press(mousex,mousey)){ button=YES; yes.Press(); } else if(no.press(mousex,mousey)){ button=NO; no.Press(); } break; case EVSELECT: for(i=0;i0){ panelMode=ITEM; repaint(); } } //--------------------------------------------------------------------// void Use(int index){ // アイテム使用処理 if(panelMode==ITEM && index>=0){ dd.useItem(index); } panelMode=mode; repaint(); } //--------------------------------------------------------------------// void Drop(int index){ // アイテム廃棄処理 if(panelMode==ITEM && index>=0){ dd.dropItem(index); } panelMode=mode; repaint(); } //--------------------------------------------------------------------// public void update(Graphics g){ // 再表示 if (dd!=null) { waitsw=true; paintMap(bg); g.drawImage(bgImage,0,0,this); waitsw=false; } else if(message!=null){ drawError(g,message); } } //--------------------------------------------------------------------// public void paint(Graphics g){ // 表示 fx=getSize().width; fy=getSize().height; if(dd!=null){ waitsw=true; setPaint(); paintMap(bg); g.drawImage(bgImage,0,0,this); waitsw=false; } else if(message!=null){ drawError(g,message); } } //--------------------------------------------------------------------// void setPaint(){ // 表示部分設定 DungeonMessagePanel mpanel; ItemListPanel ipanel; bgImage=createImage(fx,fy); bg=bgImage.getGraphics(); x0=dd.textWidth(bg,fontsize2,16)+2; y0=dd.titleHeight(bg,fontsize1)+2; fxi=fx-2*x0-5; fyi=2*fy/3-y0-5; esize=(int)(0.8*Math.min(fxi,fyi)); x1=x0+(fxi-esize)/2; y1=y0+(fyi-esize)/2; spanel=new StatusPanel(fontsize2,0,y0,x0-5,fyi,backColor,textColor); mpanel=new DungeonMessagePanel(bg,fontsize2,0,2*fy/3,fx-x0-5,fy/3 ,backColor,textColor); ipanel=new ItemListPanel(bg,fontsize2,x0+5,fy/3,fx-2*x0-10,fy/3-5 ,backColor,textColor); dd.setMIPanel(mpanel,ipanel); if(dd.event[event].type==START) dd.drawMessage(event); fxi=fx-x0-5; fyi=fy-y0-5; dd.set3DMesh(fxi,fyi,depth); dd.set2DMesh(fxi,fyi); setControlPanel(); } //--------------------------------------------------------------------// void setControlPanel(){ // コントロールパネル設定 int dx=x0/2-1,dy=fy/10-1,sy0,cx0,cy0,cx1,cx2,dx2,dy2; cx0=fx-x0; cy0=y0; cx1=cx0+x0/4; cx2=x0+(fx-2*x0)/6; dx2=(fx-2*x0)/3; dy2=fy/10; forward=new ControlButton(PANELBUTTON[0],cx1,cy0,dx,dy); cy0+=dy; left=new ControlButton(PANELBUTTON[1],cx0,cy0,dx,dy); right=new ControlButton(PANELBUTTON[2],cx0+dx,cy0,dx,dy); cy0+=dy; back=new ControlButton(PANELBUTTON[3],cx1,cy0,dx,dy); cy0+=dy; yes=new ControlButton(PANELBUTTON[4],cx2,cy0,dx2,dy2); no=new ControlButton(PANELBUTTON[5],cx2+dx2,cy0,dx2,dy2); viewsw=new ControlButton(PANELBUTTON[6],cx1,cy0,dx,dy); cy0+=dy; attack=new ControlButton(PANELBUTTON[7],cx1,cy0,dx,dy); cy0+=dy; escape=new ControlButton(PANELBUTTON[8],cx1,cy0,dx,dy); cy0+=dy; item=new ControlButton(PANELBUTTON[9],cx1,cy0,dx,dy); cy0+=dy; use=new ControlButton(PANELBUTTON[10],cx1,cy0,dx,dy); cy0+=dy; drop=new ControlButton(PANELBUTTON[11],cx1,cy0,dx,dy); } //--------------------------------------------------------------------// void paintMap(Graphics g){ // マップ描画 int fx2,fy2; g.setColor(backColor); g.fillRect(0,0,fx,fy); dd.drawTitle(g,dd.flr[dd.mg[dd.pp].floor].floorColor ,dd.flr[dd.mg[dd.pp].floor].wallColor,fx,fontsize1); if(mapView==VIEW3D){ dd.draw3DMap(g,0,y0,fxi,fyi,depth); dd.mpanel.draw(g); spanel.draw(g,dd.player); } else{ dd.draw2DMap(g,0,y0); } switch(panelMode){ case BATTLE: g.drawImage(dd.imagedata.partImage[dd.currentEnemy.image],x1,y1 ,esize,esize,this); drawBattlePanel(g); break; case YESNO: drawYesNoPanel(g); break; case ELEVATOR: fx2=fx-2*x0-5; fy2=2*fy/3-y0-5; if(setElevator) setElevatorPanel(g,event,x0,y0,fx2,fy2,fontsize1); drawElevator(g,event,fontsize1,backColor,textColor); break; case MOVE: drawMovePanel(g); break; case ITEM: drawItemPanel(g); break; } ButtonRelease(); } //--------------------------------------------------------------------// void drawMovePanel(Graphics g){ // 移動用パネル表示 Font font=new Font("Serif",Font.PLAIN,fontsize2); g.setFont(font); forward.draw(g,backColor,textColor); left.draw(g,backColor,textColor); right.draw(g,backColor,textColor); back.draw(g,backColor,textColor); viewsw.draw(g,backColor,textColor); item.draw(g,backColor,textColor); } //--------------------------------------------------------------------// void drawBattlePanel(Graphics g){ // 戦闘用パネル表示 Font font=new Font("Serif",Font.PLAIN,fontsize2); g.setFont(font); attack.draw(g,backColor,textColor); escape.draw(g,backColor,textColor); item.draw(g,backColor,textColor); } //--------------------------------------------------------------------// void drawYesNoPanel(Graphics g){ // Yes/No選択表示 Font font=new Font("Serif",Font.PLAIN,fontsize2); g.setFont(font); yes.draw(g,backColor,textColor); no.draw(g,backColor,textColor); } //--------------------------------------------------------------------// void drawItemPanel(Graphics g){ // アイテム用パネル表示 Font font=new Font("Serif",Font.PLAIN,fontsize2); dd.ipanel.draw(g); g.setFont(font); use.draw(g,backColor,textColor); drop.draw(g,backColor,textColor); } //--------------------------------------------------------------------// void setElevatorPanel(Graphics g,int ev,int x0,int y0,int fx,int fy ,int fontsize){ // エレベーター階層表示設定 int i,flr,sx,sy,dx,dy,nx,ny; Font font=new Font("Serif",Font.PLAIN,fontsize); String message=""; g.setFont(font); FontMetrics fm=g.getFontMetrics(); dx=dd.textWidth(g,fontsize,5)+2; dy=fm.getHeight()+2; nx=fx/dx; ny=fy/dy; sx=x0+(fx-dx)/2; sy=y0+dy; for(i=0;i=0) message=""+flr+"F"; else message="B"+(-flr)+"F"; sx=x0+dx/2+(i/ny)*dx; sy=y0+(i%ny+1)*dy; elevator[i]=new ControlButton(message,sx,sy,dx,dy); } setElevator=false; } //--------------------------------------------------------------------// void drawElevator(Graphics g,int ev,int fontsize ,Color backColor,Color textColor){ // エレベーター階層表示 int i; Font font=new Font("Serif",Font.PLAIN,fontsize); g.setFont(font); for(i=0;i=nline){ dl=1+lineNumber-nline; for(i=dl;i0){ g.setFont(font); g.setColor(backColor); g.fillRect(x0,y0,x,y); g.setColor(textColor); g.drawRect(x0,y0,x,y); for(i=0;i0){ g.setFont(font); g.setColor(backColor); g.fillRect(x0,y0,x,y); g.setColor(textColor); g.drawRect(x0,y0,x,y); if(index>=0) g.drawRect(x0+(index/ny)*sx,y0+(index%ny)*sy,sx,sy); for(i=0;i=index){ itemNumber--; for(i=index;i=0){ ftitle=" "+flabel+"F"; } else{ ftitle=" B"+(-flabel)+"F"; } if(ftitle2.equals("null")){} else{ ftitle+=" "+ftitle2; } readIntNumbers(st,array,2); n1=array[0]; n2=array[1]; jjmax=2*n1*n2+n1+n2; sumf+=n1*n2; for(j=ofsetf;jf2) event[eventp-1]=new Event(DOWNSTAIR,pt2,1,0,evMessage); else event[eventp-1]=new Event(UPSTAIR,pt2,1,0,evMessage); evMessage[0]=readMessage(st); if(f1>f2) event[eventp]=new Event(UPSTAIR,pt1,1,0,evMessage); else event[eventp]=new Event(DOWNSTAIR,pt1,1,0,evMessage); } else if(st.sval.equals("warp1way")){ // 片道ワープ eventp++; readIntNumbers(st,array,6); pt1=pointer(array[1],array[2],array[0]); pt2=pointer(array[4],array[5],array[3]); mg[pt1].setEvent(eventp); evMessage[0]=readMessage(st); event[eventp]=new Event(WARP1WAY,pt2,0,1,evMessage); } else if(st.sval.equals("warp2way")){ // 双方向ワープ eventp+=2; readIntNumbers(st,array,6); pt1=pointer(array[1],array[2],array[0]); pt2=pointer(array[4],array[5],array[3]); mg[pt1].setEvent(eventp-1); mg[pt2].setEvent(eventp); evMessage[0]=readMessage(st); event[eventp-1]=new Event(WARP2WAY,pt2,0,1,evMessage); event[eventp]=new Event(WARP2WAY,pt1,0,1,evMessage); } else if(st.sval.equals("elevator")){ // エレベーター if(st.nextToken()==StreamTokenizer.TT_NUMBER) nf=(int)st.nval; elev[ielev]=new Elevator(nf); evMessage[0]=readMessage(st); for(i=0;i0) player.equip(item[wpn]); if(dfd>0) player.equip(item[dfd]); EndOfPart=true; } } } //--------------------------------------------------------------------// void readMonsterData(StreamTokenizer st) throws IOException{ // モンスターデータ読み込み int i,j,number,image,hp,at,df,exp,itemNumber=0; boolean EndOfPart=false; String name; int array[]=new int[2*MONSTERITEM]; int itemnum[]=new int[MONSTERITEM]; double itemDrop[]=new double[MONSTERITEM]; while(!EndOfPart){ switch (st.nextToken()) { default: EndOfPart=true; case StreamTokenizer.TT_EOL: break; case StreamTokenizer.TT_NUMBER: // モンスター number=(int)st.nval; while(st.nextToken()!=StreamTokenizer.TT_WORD); name=st.sval; readIntNumbers(st,array,6); image=array[0]; hp=array[1]; at=array[2]; df=array[3]; exp=array[4]; itemNumber=array[5]; readIntNumbers(st,array,2*itemNumber); for(i=0;i=0){ monster=mmap[mg[pp].monster].EncountMonster(rd); if(monster>=0) EncounterEnemy(monster); } } return mg[pp].event; } //--------------------------------------------------------------------// void turnRight(){ // 右を向く direc=(direc+1)%4; } //--------------------------------------------------------------------// void turnLeft(){ // 左を向く direc=(direc+3)%4; } //--------------------------------------------------------------------// void turnBack(){ // 後を向く direc=(direc+2)%4; } //--------------------------------------------------------------------// boolean canThrough(int wall){ // 通過可能判定 int ii; boolean can=true; if(wall==WALL){ can=false; } else if(wall<0){ ii=keyNumber[-wall]; if(item[ii].getNumber==0) can=false; } return can; } //--------------------------------------------------------------------// void eventAction(int ev,int floor){ // イベント実行 int pelev,i; mpanel.clear(); switch(event[ev].type){ default: break; // イベント無し case NOEVENT: break; // スタート case START: mg[pp].setEvent(NOEVENT); break; // ゴール case GOAL: break; // 上り階段 case UPSTAIR: pp=event[mg[pp].event].move; mg[pp].Through(); break; // 下り階段 case DOWNSTAIR: pp=event[mg[pp].event].move; mg[pp].Through(); break; // 片道ワープ case WARP1WAY: pp=event[mg[pp].event].move; mg[pp].Through(); break; // 双方向ワープ case WARP2WAY: pp=event[mg[pp].event].move; mg[pp].Through(); break; // エレベーター case ELEVATORIN: if(floor>=0){ pelev=event[mg[pp].event].move; pp=elev[pelev].point[floor]; mg[pp].Through(); } break; // アイテム獲得 case ITEMGET: getItem(event[mg[pp].event].move); mg[pp].setEvent(NOEVENT); break; // 固定モンスター case ENCOUNT: EncounterEnemy(event[mg[pp].event].move); mg[pp].setEvent(NOEVENT); break; // メッセージ case MESSAGE: break; // 回復ポイント case HEAL: player.Cure(player.maxhp); break; } if(event[ev].line2==0){ mpanel.clear(); } else if(event[ev].line1!=0){ for(i=event[ev].line1;i0){ mpanel.write(EXP+getexp+POINTGETMESSAGE); levelUp=player.getExp(getexp); if(levelUp){ mpanel.write(player.name+LVUPMESSAGE); mpanel.write(MAXHP+player.dhp[player.level-1] +POINTUPMESSAGE); mpanel.write(ATTACKP+player.dattack[player.level-1] +POINTUPMESSAGE); mpanel.write(DEFENCEP+player.ddefence[player.level-1] +POINTUPMESSAGE); } } if(getitem>=0){ getItem(getitem); if(ipanel.itemNumber<=ipanel.itemNumberMax) mpanel.write(item[getitem].name+GETMESSAGE); } currentEnemy=null; } //--------------------------------------------------------------------// void PlayerDead(){ // プレイヤーが死亡したときの処理 mpanel.write(player.name+DEADMESSAGE); pp=startPoint; direc=NORTH; currentEnemy=null; player.Cure(player.maxhp); } //--------------------------------------------------------------------// void getItem(int itemNumber){ // アイテム獲得 if(ipanel.itemNumber0;i--){ for(j=-d3d.nw[i];j<=0;j++){ kk=viewPointer(i-1,j); kk2=viewPointer(i-1,-j); switch(direc){ case NORTH: ww[0]=wall[mg[kk].nw]; ww[1]=wall[mg[kk2].nw]; ww[2]=wall[mg[kk].ww]; ww[3]=wall[mg[kk2].ew]; break; case EAST: ww[0]=wall[mg[kk].ew]; ww[1]=wall[mg[kk2].ew]; ww[2]=wall[mg[kk].nw]; ww[3]=wall[mg[kk2].sw]; break; case SOUTH: ww[0]=wall[mg[kk].sw]; ww[1]=wall[mg[kk2].sw]; ww[2]=wall[mg[kk].ew]; ww[3]=wall[mg[kk2].ww]; break; case WEST: ww[0]=wall[mg[kk].ww]; ww[1]=wall[mg[kk2].ww]; ww[2]=wall[mg[kk].sw]; ww[3]=wall[mg[kk2].nw]; } d3d.draw3DMap(g,x0,y0,i,j,lineColor,flr[mg[pp].floor].wallColor ,flr[mg[pp].floor].swallColor,flr[mg[pp].floor].doorColor ,ww,kd); } } } //--------------------------------------------------------------------// int viewPointer(int depth,int side){ // 相対位置による指定 int px=0,py=0; px=mg[pp].x; py=mg[pp].y; switch(direc){ case NORTH: // 北向き px+=side; py-=depth; break; case EAST: // 東向き px+=depth; py+=side; break; case SOUTH: // 南向き px-=side; py+=depth; break; case WEST: // 西向き px-=depth; py-=side; } if(px<0) px+=flr[mg[pp].floor].n1; else if(px>=flr[mg[pp].floor].n1) px-=flr[mg[pp].floor].n1; if(py<0) py+=flr[mg[pp].floor].n2; else if(py>=flr[mg[pp].floor].n2) py-=flr[mg[pp].floor].n2; return flr[mg[pp].floor].pointer(px,py); } //--------------------------------------------------------------------// void draw2DMap(Graphics g,int x0,int y0){ // 2次元地図表示 int ks,ke,k,xx,yy; ks=flr[mg[pp].floor].ofsetf; ke=ks+flr[mg[pp].floor].n1*flr[mg[pp].floor].n2; for(k=ks;k0 && use) getNumber--; } //--------------------------------------------------------------------// void getItem(){ // アイテム獲得処理 getNumber++; } //--------------------------------------------------------------------// void loseItem(){ // アイテム廃棄処理 if(getNumber>0 && drop) getNumber--; } } //--------------------------------------------------------------------// // キャラクタークラス class Character implements Parameters{ String name; // キャラクターの名前 int maxhp=0; // キャラクターの最大生命力 int hp=0; // キャラクターの生命力 int attack=0; // キャラクターの攻撃力 int defence=0; // キャラクターの防御力 int experience=0; // キャラクターの経験値 Character(String name,int hp,int attack,int defence){ this.name=name; maxhp=hp; this.hp=hp; this.attack=attack; this.defence=defence; } } //--------------------------------------------------------------------// // プレイヤークラス class Player extends Character{ Item weapon=null,defend=null; // プレイヤーの武器・防具 int level=1,levelMax=1; // プレイヤーのレベル・最大値 int nextExp=0; // 次のレベルの経験値 int dhp[]=new int[LVMAX]; // レベルアップ時の上昇最大HP int dattack[]=new int[LVMAX]; // レベルアップ時の上昇攻撃力 int ddefence[]=new int[LVMAX]; // レベルアップ時の上昇防御力 int dexp[]=new int[LVMAX]; // レベルアップに必要な経験値 Player(String name,int hp,int attack,int defence,int levelMax ,int dhp[],int dattack[],int ddefence[],int dexp[]){ super(name,hp,attack,defence); int i; this.levelMax=levelMax; for(i=0;i=nextExp && nextExp!=NOEXP){ maxhp+=dhp[level]; hp+=dhp[level]; attack+=dattack[level]; defence+=ddefence[level]; level++; if(level==levelMax) nextExp=NOEXP; else nextExp=dexp[level]; return true; } return false; } } //--------------------------------------------------------------------// // モンスタークラス class Monster extends Character{ int image=0; // 部品イメージ番号 int itemNumber=0; // 持っているアイテムの種類数 int item[]=new int[MONSTERITEM]; // 持っているアイテム double ItemDrop[]=new double[MONSTERITEM]; // アイテムを落とす確率 Monster(String name,int image,int hp,int attack,int defence,int experience ,int itemNumber,int item[],double ItemDrop[]){ super(name,hp,attack,defence); int i; this.image=image; this.experience=experience; this.itemNumber=Math.min(itemNumber,MONSTERITEM); for(i=0;i=0){ xx[0]=x; xx[1]=1-x; for(i=0;i<2;i++){ make3DSideWall(depth,xx[i],x0,x0+fx,y0,fy); if(ww[i+2]==WALL){ draw3DSideWall(g,swallColor,lineColor,vwallx,vwally); } else if(ww[i+2]==DOOR){ draw3DSideWall(g,swallColor,lineColor,vwallx,vwally); make3DSideDoor(depth-1,xx[i],x0,x0+fx,y0); draw3DSideWall(g,doorColor,lineColor,vdoorx,vdoory); } else if(ww[i+2]<0){ draw3DSideWall(g,swallColor,lineColor,vwallx,vwally); make3DSideDoor(depth-1,xx[i],x0,x0+fx,y0); draw3DSideWall(g,kd[-ww[i+2]].color,lineColor,vdoorx,vdoory); } } } } //--------------------------------------------------------------------// void init3DMap(Graphics g,int x0,int y0,int depth,Color ceilColor ,Color floorColor){ // 3次元地図表示初期化 g.setColor(ceilColor); g.fillRect(x0,y0,fx,y1[depth]); g.setColor(Color.black); g.fillRect(x0,y0+y1[depth],fx,fy-2*y1[depth]); g.setColor(floorColor); g.fillRect(x0,y0+fy-y1[depth],fx,y1[depth]); } //--------------------------------------------------------------------// void make3DSideWall(int i,int j,int x0,int xmax,int y0,int ymax){ // 横壁表示座標データ作成 vwally[0]=y0+y1[i-1]; vwally[1]=y0+y1[i]; vwally[2]=vwally[1]+dy[i]; vwally[3]=vwally[0]+dy[i-1]; vwallx[0]=x0+x1[i-1]+dx[i-1]*j; vwallx[1]=x0+x1[i]+dx[i]*j; if(vwallx[0]xmax){ vwally[0]+=(vwally[1]-vwally[0])*(xmax-vwallx[0]) /(vwallx[1]-vwallx[0]); vwally[3]=2*y0+ymax-vwally[0]; vwallx[0]=xmax; } vwallx[2]=vwallx[1]; vwallx[3]=vwallx[0]; } //--------------------------------------------------------------------// void make3DSideDoor(int i,int j,int xmin,int xmax,int ymin){ // 横扉表示座標データ作成 int ddx; vwallx[0]=xmin+x1[i]+dx[i]*j; vwally[0]=ymin+y1[i]; vwally[3]=vwally[0]+dy[i]; if(i==0){ vdoorx[0]=vwallx[0]; vdoorx[1]=(vwallx[0]+vwallx[1])/2; vdoory[0]=vwally[0]; vdoory[1]=(vwally[0]+vwally[1])/2; vdoory[2]=(vwally[3]+vwally[2])/2; vdoory[3]=vwally[3]; } else{ vdoorx[0]=(3*vwallx[0]+vwallx[1])/4; vdoorx[1]=(vwallx[0]+3*vwallx[1])/4; vdoory[0]=(3*vwally[0]+vwally[1])/4; vdoory[1]=(vwally[0]+3*vwally[1])/4; vdoory[2]=(vwally[3]+3*vwally[2])/4; vdoory[3]=(3*vwally[3]+vwally[2])/4; } vdoory[0]+=(vdoory[3]-vdoory[0])/5; vdoory[1]+=(vdoory[2]-vdoory[1])/5; ddx=vdoorx[1]-vdoorx[0]; if(vdoorx[0]xmax){ vdoory[0]+=(vdoory[1]-vdoory[0])*(xmax-vdoorx[0])/ddx; vdoory[3]+=(vdoory[2]-vdoory[3])*(xmax-vdoorx[0])/ddx; vdoorx[0]=xmax; } vdoorx[2]=vdoorx[1]; vdoorx[3]=vdoorx[0]; } //--------------------------------------------------------------------// void draw3DWall(Graphics g,Color wallColor,Color lineColor ,int x0,int y0,int xx,int yy){ // 前壁描画 g.setColor(wallColor); g.fillRect(x0,y0,xx,yy); g.setColor(lineColor); g.drawRect(x0,y0,xx,yy); } //--------------------------------------------------------------------// void draw3DSideWall(Graphics g,Color wallColor,Color lineColor ,int xx[],int yy[]){ // 横壁描画 g.setColor(wallColor); g.fillPolygon(xx,yy,4); g.setColor(lineColor); g.drawPolygon(xx,yy,4); } //--------------------------------------------------------------------// void draw3DDoor(Graphics g,Color wallColor,Color lineColor ,int x0,int y0,int xx0,int i,int j){ // 前扉描画 int drx0,drx,dry0; drx0=dx[i]/4; drx=dx[i]-2*drx0; dry0=dy[i]/5; if(xx0==0){ drx0+=x1[i]+dx[i]*j; if(drx0<0){ drx+=drx0; drx0=0; } } else if(xx0+drx0+drx>fx){ drx=fx-xx0-drx0; } draw3DWall(g,wallColor,lineColor,x0+xx0+drx0,y0+y1[i]+dry0 ,drx,dy[i]-dry0); } }