//--------------------------------------------------------------------//
// 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;i
0){
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);
}
}