DespairTypingソースコード



コメントに解説をしておきました。詳細は説明できていませんが、少しでも参考になれば幸いです。
/* DespairTyping author 49 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.security.*;
import java.util.ArrayList;
import java.lang.Math;

public class typing extends Applet implements Runnable,KeyListener{
	/*
	キャラクターデータは【画像ファイル名、文章、ローマ字(複数)、ピリオド(終わり)】の形式で
	書かれます。
	*/

	ArrayList images = new ArrayList(); //キャラクター画像
	ArrayList kotonoha = new ArrayList(); //ワード
	ArrayList rkotonoha = new ArrayList(); //ローマ字の文章。一つの文章に複数ある可能性アリ
	ArrayList nkotonoha = new ArrayList(); //ワードの番号を記憶


	
	Image canvus=null;//画像描画用キャンバス
	String nstr="";//現在打ち込み中のワード
	int odai=0;//お題の番号
	int score=0;//撃破数
	int totals;//結局の点数。
	int gtype=0;//正しく打てた回数
	int mistype=0;//タイプミスの回数
	int dbn=0;//ワードの数
	String hstr;//表示されるstring
	String oldstr;//さっきまでの打ち込み内容
	long start;//始まった時の時間。一分測定用
	boolean endFlag=false;//終わったかどうか判定。

	//画面
	static int G_WIDTH=480;
	static int G_HEIGHT=500;

	
	public static void main(String args[]) {
		//アプレットの作成
		Applet app=new typing();

		//アプレットの初期化
		app.init();
		//フレームの初期化
		Frame frame = new Frame();
		frame.pack();
		frame.setVisible(true);
		frame.setVisible(false);
		frame.pack();
		frame.setSize(G_WIDTH,G_HEIGHT);

		//これを忘れると閉じるボタンを押しても閉じなくなってしまいます
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {System.exit(0);}});
		frame.setResizable(false);
		//フレームにアプレットを貼り付けています
		frame.add(app);
		frame.setVisible(true);
	  }
	public void init(){
		int i=0;//普通の変数
		int s=0;//今現在【何処】を読み込んでいるか判定

		String line;//データ読み込みに使うString

		//キーリスナー、スレッドの作成
		addKeyListener(this);
		requestFocus();
		new Thread(this).start();


                //ファイルの読み込みはこの形にしないとhtmlに張ったときに失敗します。
		BufferedReader sequenceReader = null;
		try {
			if(sequenceReader != null)
				sequenceReader.close();
			InputStream is = getClass().getResource("stage.txt").openStream();
			InputStreamReader isr = new InputStreamReader(is);
			sequenceReader = new BufferedReader(isr);
			//ゲームスタート用に。一律でゲーム開始点数を足すことで0割りを防止。
			kotonoha.add("start");
			rkotonoha.add("start");
			nkotonoha.add(0);
			images.add(Toolkit.getDefaultToolkit().getImage(getClass().getResource("start.GIF")));

			nkotonoha.add(1);i=1;
			while ((line = sequenceReader.readLine()) != null) {
				if(line.equals(".")){
					s=0;
					nkotonoha.add(i);
				}else{
					if(s==2){
						rkotonoha.add(line);
						i+=1;
					}
					if(s==1){
						kotonoha.add(line);
						s=2;
					}
					if(s==0){
						images.add(Toolkit.getDefaultToolkit().getImage(getClass().getResource(line)));
						s=1;
					}
				}
			}
			sequenceReader.close();
			dbn=kotonoha.size()-1;
			loadGame();

		} 
		catch(Exception e) {e.printStackTrace();}
	}
	
	public void keyTyped(KeyEvent e){


	}
	public void keyPressed(KeyEvent e){
		if(endFlag && e.getKeyCode()==KeyEvent.VK_ESCAPE){endFlag=false;loadGame();return;}
		
		if(e.getKeyCode()==KeyEvent.VK_ESCAPE){nstr="";oldstr="";hstr=(String)rkotonoha.get((Integer)nkotonoha.get(odai));return;}
		nstr=nstr+String.valueOf(e.getKeyChar());
		if(!nstr.equals(oldstr)){gtype+=1;checkWord();}
	}

	public void keyReleased(KeyEvent e){}

	public void run(){
		while(true){
			
			repaint();
			try{
				Thread.sleep(10);
			}catch(Exception e){}
		}
	}

	public void paint(Graphics g){
		/*
		描画で画面がちらつく理由は、例えば三つの絵を描くときに、A、B、Cを一瞬のうちでは描くことが出来ず
		一瞬だけAだけが表示された状態などになってしまうことにあります。
		それを回避するために、ユーザからは見えない画面を作り、そこにA,B,Cと必要な絵を全て描いてから、その画面の内容を
		ディスプレイに表示します。どの言語でも描画では必ずといって良いほど使う重要な概念です。
		*/
		
		int i;//forloop用
		int s;//forloop用
		//ユーザに見えない画面(Graphics bu)の作成
		Graphics bu;//画像書き込み用グラフィック

		//実際にディスプレイに書き込む時の形はImageなので、書き込み用イメージ(Image cauvus)とbuのつながりを作っておく。
		if(canvus==null){canvus=createImage(G_WIDTH,G_HEIGHT);}
		
		bu=canvus.getGraphics();
		bu.setColor(Color.black);
		
		Font ft= new Font("MS Pゴシック",0,20);
		bu.setFont(ft);
		//見えない画面を塗りつぶしておく
		bu.fillRect(0,0,G_WIDTH,G_HEIGHT);
		bu.setColor(Color.white);

		if(!endFlag){
			//お題。画像の表示
			bu.drawImage((Image)images.get(odai),0,0,this);
			bu.drawString((String)kotonoha.get(odai),50,410);
			bu.drawString(hstr.toUpperCase(),50,450);
			//bu.drawString(nstr.toUpperCase(),50,310);

			if(score>0 && System.currentTimeMillis()-start>60000){

				totals=score*100+gtype*10;
				totals=totals*gtype*gtype;
				totals=totals/((gtype+mistype)*(gtype+mistype));

				endFlag=true;
			}
		}
		else{
			bu.drawString("ESCキーで次のゲーム",50,360);
			bu.drawString("Score:"+Integer.toString(totals),50,220);

			bu.drawString("Programmer:しく",50,400);
			bu.drawString("http://gekidan49.web.fc2.com/",50,440);
		}

		//bu.drawString("yutori bajai!!",100,100);	
		
		//見えない画面の開放
		bu.dispose();

		//ディスプレイへの描画
		g.drawImage(canvus,getInsets().left,getInsets().top,this);
		//g.drawString("yutori bajai!!"+ sdat[0].substring(0,1) + sdat[0],100,100);
		
	}
	public void update(Graphics g){
		paint(g);
	}

	public void loadGame(){
		odai=0;
		nstr="";
		oldstr="";
		hstr=(String)rkotonoha.get((Integer)nkotonoha.get(odai));

		score=0;
		gtype=0;
		mistype=0;
		nstr="";


	}
	public void checkWord(){
		int i;
		String t;

		for(i=(Integer)nkotonoha.get(odai);i<(Integer)nkotonoha.get(odai+1);i++){
			t=(String)rkotonoha.get(i);
			if(t.toUpperCase().equals(nstr.toUpperCase())){renewWord();return;}
			if(t.toUpperCase().startsWith(nstr.toUpperCase())){
				hstr=t.substring(nstr.length());
				oldstr=nstr;
				return;
			}
		}
		mistype+=1;
		gtype-=1;
		nstr=oldstr;
	}

	public void renewWord(){
		score+=1;
		//startをタイプしてスタート
		if(score==1){
			gtype=1;mistype=0;
			start=System.currentTimeMillis();
		}
		nstr="";
		oldstr="";
		odai+=1+(int)(Math.random()*(dbn));
		odai=odai%dbn+1;
		
		hstr=(String)rkotonoha.get((Integer)nkotonoha.get(odai));
	}
}


Programmingのトップに戻る

トップに戻る
inserted by FC2 system