大学人生テトリスβ版(ver.0.3.6)
大学人生テトリスβ版 ©JO Hiroshi
ゲーム:ノンサウンドノヴェル(音が未実装)
国際基督教大学2010年春学期Computer Gamesペルソナデザイン
に依るプログラミング課題2。テトリスとストーリィ展開を内包しつつ、
ペルソナ”瀬口慎人くん(関口勝)”のためのゲーム。瀬口くんの
好むものをベースに、瀬口くんが欲する情報、将来の可能性、
進路等を模索するゲームを設計。但し。現段階においては未実装。
今後は、テトリス画面再描画のバグ直し、選択肢の安易さの改善、
選択肢の複雑化、Endパターンの増加、ゲーム期間の延長を予定。
(タグが増えている…)
--------------------------------------------------------
操作法:
・Nextボタンによる文章の先送り
・テトリスの点数に応じた選択肢分岐
・良い選択肢を選び続けることによって将来が明るくなる
(但し、Ver1.0では選択による単純化をなくす予定)
--------------------------------------------------------
tetrisのソースコードはPoisonCode http://poisoncode.blog77.fc2.com/
を参考にさせていただています。
また、このゲームを作成するにあたり、数々のウェブサイト
を参考にさせていただきました。感謝。
--------------------------------------------------------
/**
* Copyright hacker_johiroshi ( http://wonderfl.net/user/hacker_johiroshi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3gCN
*/
/*
大学人生テトリスβ版 ©JO Hiroshi
ゲーム:ノンサウンドノヴェル(音が未実装)
国際基督教大学2010年春学期Computer Gamesペルソナデザイン
に依るプログラミング課題2。テトリスとストーリィ展開を内包しつつ、
ペルソナ”瀬口慎人くん(関口勝)”のためのゲーム。瀬口くんの
好むものをベースに、瀬口くんが欲する情報、将来の可能性、
進路等を模索するゲームを設計。但し。現段階においては未実装。
今後は、テトリス画面再描画のバグ直し、選択肢の安易さの改善、
選択肢の複雑化、Endパターンの増加、ゲーム期間の延長を予定。
(タグが増えている…)
--------------------------------------------------------
操作法:
・Nextボタンによる文章の先送り
・テトリスの点数に応じた選択肢分岐
・良い選択肢を選び続けることによって将来が明るくなる
(但し、Ver1.0では選択による単純化をなくす予定)
--------------------------------------------------------
tetrisのソースコードはPoisonCode http://poisoncode.blog77.fc2.com/
を参考にさせていただています。
また、このゲームを作成するにあたり、数々のウェブサイト
を参考にさせていただきました。感謝。
--------------------------------------------------------
*/
package
{
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.ui.Keyboard;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.display.Graphics;
/**
* AS_TETRiS08
* @author necoEngine
*/
public class Tetris extends Sprite
{
private const FIELD_WIDTH:uint = 14;
private const FIELD_HEIGHT:uint = 22;
private const CELL_WIDTH:uint = 20;
private const CELL_HEIGHT:uint = 20;
private const TET_WIDTH:uint = 4;
private const TET_HEIGHT:uint = 4;
private const EMPTY:uint = 0;
private const WALL:uint = 9;
private const LOCKED:uint = 10;
private const WALL_COLOR:uint = 0x7A5B52;
private const GRID_COLOR:uint = 0xC0C0C0;
private const TET_COLORS:Array = [
0xE9EE11, 0x4DE6E1, 0xEA68E7, 0xE49E1B, 0x2746D8, 0x46DF20, 0xED2212
];
private const tetPattern01:Array = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]];
private const tetPattern02:Array = [[0, 0, 0, 0], [2, 2, 2, 2], [0, 0, 0, 0], [0, 0, 0, 0]];
private const tetPattern03:Array = [[0, 0, 0, 0], [0, 0, 3, 0], [0, 3, 3, 3], [0, 0, 0, 0]];
private const tetPattern04:Array = [[0, 0, 0, 0], [0, 0, 0, 4], [0, 4, 4, 4], [0, 0, 0, 0]];
private const tetPattern05:Array = [[0, 0, 0, 0], [0, 5, 0, 0], [0, 5, 5, 5], [0, 0, 0, 0]];
private const tetPattern06:Array = [[0, 0, 0, 0], [0, 0, 6, 6], [0, 6, 6, 0], [0, 0, 0, 0]];
private const tetPattern07:Array = [[0, 0, 0, 0], [0, 7, 7, 0], [0, 0, 7, 7], [0, 0, 0, 0]];
private const TETROMINOS:Array = [
tetPattern01, tetPattern02, tetPattern03, tetPattern04, tetPattern05, tetPattern06, tetPattern07
];
private const MAP_BLANK:Array = [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9];
private const DELAY_RANGE:Number = 1000;
private const DELAY_MIN:Number = 100;
private const DELETE_RAG:Number = 150; // 追加
private var fieldMap:Array = [
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9],
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
];
private var fieldMapColor:Array = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
private var gameField:Shape;
private var location:Point;
private var currentTetromino:Array;
private var currentIndex:uint;
private var nextIndex:uint;
private var deleteLineIndex:Array;
private var gameover:Boolean;
private var dropTimer:Timer;
private var ragTimer:Timer; // 追加
private var nextBorad:NextTetrrominoDisplay;
private var score:int; //スコア
private var scoreboard:Sprite; //スコアボード
private var tscb:TextField = new TextField(); //スコア用テキストフィールド
private var tsc:TextField = new TextField(); //
private var continuetime:int;
private var mTimer:Timer = new Timer(1000, 5);
//MessageBox用
private var tf:TextField = new TextField();
private var tf1:TextField = new TextField();
private var tfm:TextFormat = new TextFormat;
private var button:SimpleButton = new SimpleButton();
private var count:int = 0;
private var s:Sprite = new Sprite();
private var g:Graphics = s.graphics;
private var tb:Sprite = new Sprite();
private var scene:int = 0;
private var sceneNum:int = 0; //シーンナンバ
private var bonus:int = 0; //好感度、達成度
private var restClick:int = 8 //残りクリック回数。初期値8
//A0 シーン0。イントロダクション。
private var ms:Array = [[" 2010年5月13日\n\n雨が降るとも振らないともはっきりしない今日の天気は5月らしいと言えば5月らしく、しかし、関口勝の気分は正に5月病を色を呈していた。\n 関口勝。性別は男。今年大学に入学したての1年生。新しい環境に胸を膨らませていた彼であったが、現実は彼の期待には比例せず、新しくも刺激の無い生活を提供していた…",
" トゥルルル、トゥルルル。\n\n 「ん?誰からだろう」\n 関口勝は朝一で授業があるにもかかわらず寝坊してしまった。時計を見てすぐさま飛び起きて、着替えをしながら食パンをかじっていた時に携帯電話が鳴った。\n\n着信\nイリヤ\n\n 「イリヤからか」\n",
" 勝は少し迷った。イリヤからの電話は久しぶりだが、かといって今電話に出て話していては授業に遅刻してしまう。30秒ほど考えて、電話に出る事に決めたが、残念ながらその時には携帯電話は2度寝をしてしまっていた。\n 「仕方ない。後でかけ直そう」\n 合計で1分ほど時間を無為に過ごしてしまったが、勝は自宅を出た。\n 自宅から大学までは自転車で15分ほど。勝には自転車に乗る時に音楽を聞く習慣は無い。自転車を漕ぎながら音楽を聴くような器用なまね等出来ないし、第一、注意が削がれて危ない。",
" 大学に到着して教室に向かう。しかし、教室には誰もおらず、黒板には\n\n As I said last class, Today is no class.\n\nとだけ走り書きしてあった。",
" 「失敗した。休講になったのをすっかり忘れていた。イリヤからの電話に出れば良かった」\n\n この手の失敗を勝は何度も経験している。小学生の頃、友人がガリガリ君を買うと言い出した時に勝はガリガリ君を買わず、友人は見事当たりを引き当てた。中学生の頃、ある女の子の恋愛相談を受けて、見事その女の子の意中の人と付き合わせる事に成功したが、その後に自分がその女の子に恋をしていたことに気づいた。",
"大学受験の時は、迷いに迷って自宅に置いてきた参考書の内容が試験問題に出て、当然、その大学には落ちた。端的に言えば、ここ一番の決断に彼は弱いのである。",
" 何故自分はこうも適切な判断が出来ないのか。自分の判断の多くが誤っているのなら、逆にあてにならない。ここは一つ、新しい決断方法を考案しよう、そんな事を考えながら、勝はテトリスをしていた。空き時間の多くをテトリスに費やすのが勝である。イリヤに電話をかけないでテトリスをしている時間を「空き時間」と呼ぶことへの迷いはこの際忘れる。否、忘れてはいけない。\n\n 「よし、じゃあ、もし今しているテトリスが5分間続いたらイリヤに電話をかけよう」",
"---------------- Tetris Starts [1]------------\n\n得点が10以上:イリヤに電話する\n得点が10未満:空き時間を謳歌する\n\n---------------- Tetris Ends ------------------"],
//A1 シーン1。R0. Bonus = 0
["\n 「くそう、5分も持たなかった。悔しいな。もう一度だ」\n\n 次の授業が始まるまで勝はずっとテトリスをしていた。",
"5月14日金曜日\n\n 関口勝は困っていた。クラスメイトからアルバイト一緒にしないかと誘われたのだ。\n アルバイトは今まで全くしておらず、大学に入ったら始めようとは思っていたのだが、これぞというものにまだ出会えずにいた。しかし、勝にはこれといって断る理由も無かった。\n 迷った末に、テトリスで決めようと考え、勝は「トイレに行く」と言って、一度クラスメイトのもとを離れた。\n\n 「さて、テトるか」",
"-------------------- Tetris Starts [2]----------------\n得点が20以上:\n「やるやる!そんなアルバイトが良かったんだ!」\n得点が20未満:\n「いや、僕には自宅警備員という重要なミッションがあるから…」\n-------------------- Tetris Ends ---------------------"],
//A2 シーン1。R1. Bonus = 1
[" 「お!5分持ったぞ。よーし、イリヤに電話をかけよう」\n\n トゥルルル、トゥルルル。",
" \n\n 「はい、イリ…おれ、俺です」\n 「?」\n 「おれおれです」\n 「勝だけど…」\n 「あ!わたし!わたし、おれおれだけれど、えと、何だっけ、お金がない?」\n 「すみません、間違え電話でした。失礼します」\n 「ぁあああ、ごめんなさい。イリヤです。わたしです」\n 「お早う。朝電話に出れなくてごめん。何か用?」",
"\n 「勝、どうしてるかなーって。ほら、大学に入ってそろそろ1ヶ月でしょ?」\n「ぁーうん、5月病かも」\n 「あ!あの、自宅警備員予備員だっけ?」\n 「違う、違う。ま、でも、心配してくれて嬉しいよ。ありがとう。要件はそれだけ?」\n 「んー、声が聞きたかったくらいだし、そう。じゃあ、またね」\n 「うん、また」",
"\n\n 少し元気が出てきたぞ。これもテトリスのおかげか。テトリス歴が早12年目の僕にはこの決断方法は適しているかもしれない。よし、今度から困った時はテトリスで決めよう。",
" 5月14日金曜日\n\n 関口勝は困っていた。クラスメイトからアルバイト一緒にしないかと誘われたのだ。\n アルバイトは今まで全くしておらず、大学に入ったら始めようとは思っていたのだが、これぞというものにまだ出会えずにいた。しかし、勝にはこれといって断る理由も無かった。\n\n 「そうだ。こういう時こそテトリスだ!」",
"\n-------------------- Tetris Starts [2]---------------\n得点が20点以上:\n「悪いけれど、もう他のアルバイトに決めたんだ」\n得点が20未満:\n「いや、僕には自宅警備員という重要なミッションがあるから…」\n-------------------- Tetris Ends -----------------"],
//A3 シーン2。 Bonus = 0 || Bonus = 1
["\n 「いや、僕には自宅警備員という重要なミッションがあるから…」\n 「そっか。なら仕方が無いか」\n 「保安は大事だからな」",
"\n アルバイトに誘ってくれた友人は去っていった。\n\n せっかくのチャンスを逃してしまった。それも、消極的な理由で。良かっただろうか。\n いや、しかし、自宅警備を怠るわけにはいかない。お金が貰えるからといって軽卒にアルバイトを始めるのは良くない。慎重に、もう少し後にしよう。",
"5月16日\n\n 今日は日曜日にも関わらず、関口勝は自宅で無為に時間を過ごしていた。\n 始めは、「テトリスでゲームオーバになったら、外出しよう」と決めていたのだが、どうもすぐにゲームオーバになってしまい、悔しくて何度も何度もトライしていた。窓の外を見ると、日が沈みかけていた。",
" ふと、携帯電話を見ると、メールが数件来ている。誰からだろう。\n\n 「っわ! イリヤからだ」\n\n 急いでメールを読むと、どうやら暫く会っていない事について罵詈雑言が記されている。まずいぞ。ここ数日全く連絡をとっていない。そういえば、3日前の電話にも無反応のままだった。",
" どうしよう。急いで連絡した方が良いか。いやいや。これならいっそ、寝ていたということにした方が良いかもしれない。\n うーん。よし、こんあな時はテトリスで決めよう!",
"------------------- Tetris Starts [3]----------------\n得点が30点以上:\n電話をかけ直す\n得点が30点未満:\n「見なかったことにしよう。気づかなかったのだから仕方がない」\n-------------------- Tetris Ends ---------------------"],
//A4 シーン2. Bonus = 3
["\n 「悪いけれど、もう他のアルバイトに決めたんだ」\n 「そっかー、なら仕様がないな。他あたるよ」\n 「わざわざありがとう」\n\n アルバイトに誘ってくれた友人は去っていった。\n さて、どうしよう。何故嘘をついてまで断ってしまったのだろうか。",
" トゥルルル、トゥルルル。\n\n 「あ、イリヤからだ」\n 「勝です」\n 「いや、勝は僕だよ」\n 「勝は貴方です」\n 「僕が勝です。用が無いなら切るよ?」\n 「冷たいなぁ。暫く会っていないうちに鉄のような人間になってしまって、、、私は悲しいです」\n 「比熱が大きいと言う。それで、用は?」",
" 「ぁー、すっかり忘れてた。そうそう。アルバイト一緒にやらない? 今人が足りなくて、しかも、男手を探しているの。大学も別々になっちゃったし、合う機会に丁度良いかなって」\n 「へー。それは良いね。やるよ」\n 「やった! 店長には私から言っておくから心配無用。また電話するね。バイバイ」\n\n ツーツーツー。",
" 「またテトリスのおかげかもしれない。イリヤと会える時間が増えるし、良い事尽くめだ!」",
"5月16日\n\n 今日は久々のイリヤとデートだ。だが、未だに未来科学館に行くか、考古学博物館に行くか迷っている。家族に話したら、\n\n 「それは迷う選択肢ではない」\n\nと一蹴されたが、そんなことはない。これは一大事だ。よし、困った時のテトリス先生だ。",
"\n-------------------- Tetris Starts [4]----------------\n得点が40以上: 「そうだ! 京都へ行こう!」\n得点が40分未満: 「未来科学館へ行こう!」\n-------------------- Tetris Ends -------------------"],
//A5 シーン3。R001, Bonus = 1 || R101, Bonus = 2 || R011, Bonus =2 || R111, Bonus = 3(Jump)
["\n 「よし、怒らせないいうちにかけ直そう」\n\n トゥルルル、トゥルルル。\n\n 「ぷんぷん」\n 「いやいや、怒らせないうちにかけ直せて良かった」\n 「ぷんぷん」\n 「今までアルバイトで忙しくて着信に気づけず、怒らせないうちにかけ直せて良かった」\n 「怒っています」\n 「ごめんなさい」",
" 「最近、全然会えないし、話せないし、連絡しないし。もう私のことなんかどうでも良いの? 」\n 「そんなことは無い。三度の飯よりも君の事を気にかけているよ」\n 「ブランチ派のくせに。ふんだ」\n 「そうだ。週末にでもデートしよう。久しぶりに」\n 「埋め合わせるつもりなら、ちゃんとプランを考えてきてね」\n 「わかってるよ。それじゃあまた連絡する」\n 「うん、また♪」",
" 危ないところだった。今日連絡できてよかった。来週しっかりとやればイリヤの機嫌は治りそうだ。\n 何にせよ、デートの約束もとりつけられたのだし、うまくやったのではないだろうか。",
"5月23日\n\n 今日は久々のイリヤとデートだ。だが、未だに未来科学館に行くか、考古学博物館に行くか迷っている。家族に話したら、\n\n 「それは迷う選択肢ではない」\nと一蹴されたが、そんなことはない。これは一大事だ。また、テトリスで決めようか。",
"\n-------------------- Tetris Starts [4]----------------\n得点が40以上: 「そうだ! 京都へ行こう!」\n得点が40分未満: 「未来科学館へ行こう!」\n-------------------- Tetris Ends -------------------"],
//A6 シーン3。 B = 0, 1 BAD END
["\n 「見なかったことにしよう。気づかなかったのだから仕方がない」\n 勝はこれからとる行動に真実味をもたせるため、さっそく布団を敷いて寝ることにした。\n この日はぐっすり朝の6時まで寝た。",
"6月24日\n\n 今日は最後の授業日だった。テトリスで遊んでいたばかりいたせいか、レポートはほとんど終わらず、テストの方も不安だ。イリヤは夏休みに友人と海外に行くらしく、デートの約束もあまりしていない。\n こんな風に1学期が終わってしまって良かったのだろうか。大学生活がこのようで良いのだろうか。来学期からは頑張らなければ…\n\n[BAD END]"],
//A7 シーン3。 B = 2 GOOD END
["\n 「電話をかけ直そう」\n\n トゥルルル、トゥルルル。",
" 「イリヤ?」\n 「どなた様でしょうか。ああー、知らない人ですか。知らない人とは電話してはいけないと教わったので切ります。さようなら」\n 「まてまてまてまて」\n 「電話かけても返してくれない彼氏はイリヤの彼氏じゃありません」\n 「ごめん。誤るよ」",
" 「むー、良いけれど。ところで、アルバイト一緒にやらない? 今人が足りなくて、しかも、男手を探しているの。大学も別々になっちゃったし、合う機会に丁度良いかなって」\n 「へー。それは良いね。やるよ」\n 「やった! 店長には私から言っておくから心配無用。また電話するね。バイバイ」\n\n ツーツーツー。\n\n 「ふー、なんとか事なきを得た。かけ直して良かった」",
"6月24日\n\n 今日は最後の授業日だった。レポートは大体終わらせることが出来、テストの方はなんとか。夏休みは、今まであまり相手に出来なかった分、イリヤと時間を過ごさないと。\n\n 振り返ると、物事がうまく進んだ時はテトリスをした時かもしれない。これからもテトリスを生活に応用してみようか。\n\n[BETTER END 1]"],
//A8 シーン3。 B = 3 BETTER END
["\n 「未来科学館へ行こう! 10分もったのだし、そうしよう。きっとイリヤも喜んでくれるはず」\n\n 未来科学館へ行く、と言った時のイリヤの表情はあまり良くはなかったけれど、今日の展示内容はイリヤ好みだったらしく、反応は上々だった。無論、僕も楽しむことが出来た。",
"\n 「未来館も意外と面白いんだね」,\n 「前に来た時は『つまんない!』って言っていたけれど、そう言ってくれて良かった」\n 「でも、勝最近は全然会えないから不満まんまんだったよ」\n 「そっか。今度から気をつける。また一緒にどこかへ遊びにいこ」\n 「うん!」",
"6月24日\n\n 今日は最後の授業日だった。レポートは大体終わらせることが出来、テストの方はなんとか。夏休みは、今まであまり相手に出来なかった分、イリヤと時間を過ごさないと。\n\n 振り返ると、物事がうまく進んだ時はテトリスをした時かもしれない。これからもテトリスを生活に応用してみようか。",
"\n\n[BETTER END 2]"],
//A9 シーン4。B =4 TRUE END
["\n「そうだ!京都へ行こう!」\n\n ノリと勢いで出発した日帰り京都旅行だが、その無計画さが功をなしたのか、結果はどちらも楽しむ事ができて良い1日となった。このところとても調子が良い。これも全てテトリスのおかげだ!",
"6月24日\n\n 今日は最後の授業日だった。レポートは全て終わらせることが出来、また、手応えだけで言えば、テストの結果は上々。明日にはアルバイト代が入るし、夏休みになれば、イリヤと過ごせる時間も増える。",
" 少し前までは、大学生活がこんなにうまく行くとは思えなかった。この変化の原因は、間違いなくテトリスに依るものだろう。普段、気分転換にしか使っていなかったものが使い方によってはこんなに役に立つものだとは思わなかった。これからも、困った時はテトリスで解決していくのが良いかもしれない。\n\n\n[TRUE END]"]];
public function Tetris():void
{
Minit();
}
private function Minit():void
{
SGraphics();
tb = new Sprite();
addChild(tb);
tb.graphics.beginFill(0xFAEBD7);
tb.graphics.drawRoundRect(20, 20, 425, 300, 50);
tb.graphics.endFill();
tf = TextDetail(tf); //テキストの設定
tf = createTextField(20, 20, 425, 300); //テキストボックスの生成
//TextFormatの生成
tfm.color = 0x000000;
tfm.size = 20;
//tfm.italic = true;
if (scene == 0)
tf.appendText("\n 大学人生テトリスβ版");
tf.wordWrap = true;
tf.setTextFormat(tfm);
addChild(tf);
addButton();
if (sceneNum >= 1)
reStart();
}
//bonus初期値は0。得点に応じたルート分岐。
private function changeRoot():void{
switch(sceneNum){
case 0: //sceneNum = 0 → Tetris 1, イントロダクション
break;
case 1: //sceneNum = 1→ Tetris 2
if (bonus == 0) {
scene = 1; //Array[1][]
restClick = 3;
}else { //else if (bonus == 1)
scene = 2; //Array[2][]
restClick = 6;
}
break;
case 2: //sceneNum =2 →Tetris 3 or Tetris 4
if (bonus == 0 || bonus == 1) {
scene = 3; //Array[3][]
restClick = 6;
}else if (bonus ==2) {
scene = 4; //Array[4][]
restClick = 6;
}
break;
case 3: //sceneNum = 3 →Tetris 4
if (bonus == 0) {
scene = 6;
restClick = 2;
} else if (bonus == 1) {
scene = 7;
restClick = 4;
} else if (bonus == 2) {
scene == 5;
restClick = 5;
}else if (bonus == 3) {
scene = 9;
restClick = 3;
}
break;
case 4: //復帰コース
if (bonus == 2) {
scene = 9;
restClick = 3;
} else if (bonus == 3) {
scene = 8;
restClick = 4;
}
break;
}
}
private function SGraphics():void
{
graphics.lineStyle(2.0, 0x000000);
graphics.beginFill(0x7A5B52);
graphics.drawRect(0, 0, 500, 500);
graphics.endFill();
}
private function TextDetail(tf:TextField):TextField
{
//TextBoxの生成
//var tf:TextField = new TextField();
tf.text = "Introduction1";
tf.appendText("test");
tf.x = 30;
tf.y = 30;
tf.width = 390;
tf.height = 270;
tf.multiline = true; //複数行
tf.wordWrap = true; //テキストの折り返し
//tf.autoSize = "left";
//addChild(tf);
return tf;
}
private function addButton():void
{
//Bottonの生成
button.x = 50;
button.y = 350;
button.upState = stateButton(0x0);
button.overState = stateButton(0xFF4500);
button.downState = stateButton(0xFF4500);
button.hitTestState = stateButton(0xFFF4500);
button.addEventListener(MouseEvent.CLICK, onMouseClick);
addChild(button);
textButton();
}
private function stateButton(color:int):Sprite
{
//ボタンの設定
g.lineStyle(2.0, 0xFFDEAD);
g.beginFill(0xFFDAB9);
g.drawRect(0, 0, 100, 50);
g.endFill();
//s.alpha = 1;
textButton();
return s;
}
private function textButton():void
{
//var tf1:TextField = new TextField();
tf1.defaultTextFormat = new TextFormat("_typeWriter", 20, 0x000000, true);
tf1.text = "Next";
tf1.width = 50;
tf1.height = 50;
tf1.x = 72 //(width.stateButton - tf1.width) / 2;
tf1.y = 362 //(height.stateButton - tf1.height) / 2;
tf1.autoSize = "left";
tf1.selectable = false;
addChild(tf1);
}
private function onMouseClick(event:MouseEvent):void
{
//マウスプッシュに依る先送り。
if(count==restClick)
{
removeChild(tf);
//tf = null;
removeChild(tb);
//tb = null;
removeChild(tf1);
//tf1 = null;
g.clear();
removeEventListener(MouseEvent.CLICK, onMouseClick);
removeChild(button);
graphics.clear();
init();
}
tf.text = "\nScene:"+ sceneNum +"\n" + ms[scene][count++];
tf.setTextFormat(tfm);
}
private function init():void
{
//テトリスゲームフィールド
gameField = new Shape();
addChild(gameField);
gameField.x = CELL_WIDTH;
gameField.y = CELL_HEIGHT;
TETROMINOS.push(0);
//nextテトリミノ表示ボード
nextBorad = new NextTetrrominoDisplay();
addChild(nextBorad);
nextBorad.x = stage.stageWidth - nextBorad.width - CELL_WIDTH;
nextBorad.y = CELL_HEIGHT * 2;
location = new Point(0, 0);
nextTetromino(true);
fullDrawing();
//timer設定
dropTimer = new Timer(DELAY_RANGE);
dropTimer.addEventListener(TimerEvent.TIMER, onDropTetromino);
dropTimer.start();
ragTimer = new Timer(DELETE_RAG, 1); // 追加
ragTimer.addEventListener(TimerEvent.TIMER, fillMapBlank);
//スコアの表示
scoreboard = new Sprite();
addChild(scoreboard);
scoreboard.graphics.beginFill(0x7A5B52);
scoreboard.graphics.drawRoundRect(305, 330, 150, 100, 50);
scoreboard.graphics.endFill();
score = 0;
//ステージイベント
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
/**
* イベント
** ** ** ** ** ** ** ** ** ** ** **/
private function onKeyDown(event:KeyboardEvent):void
{
switch(event.keyCode) {
case Keyboard.LEFT:
tetrominoAction(Keyboard.LEFT);
break;
case Keyboard.RIGHT:
tetrominoAction(Keyboard.RIGHT);
break;
case Keyboard.DOWN:
tetrominoAction(Keyboard.DOWN);
dropTimer.stop();
dropTimer.start();
break;
case Keyboard.UP:
tetrominoAction(Keyboard.UP);
break;
}
}
private function onDropTetromino(event:TimerEvent):void
{
/**
* 一定時間ごとに自動で落下させる
*/
tetrominoAction(Keyboard.DOWN);
}
private function fillMapBlank(event:TimerEvent):void
{
/**
* 揃ったラインを削除した後に、空白を詰める処理
* 少し時間のおいてから実行される
*/
tetrominoClear();
for (var y:int = deleteLineIndex.length - 1; y >= 0; y--) {
fieldMap.splice(deleteLineIndex[y], 1);
fieldMapColor.splice(deleteLineIndex[y], 1);
fieldMap.splice(0, 0, MAP_BLANK.concat());
fieldMapColor.splice(0, 0, MAP_BLANK.concat());
}
fullDrawing();
}
/**
* テトリミノ生成
** ** ** ** ** ** ** ** ** ** ** **/
private function createTetromino():uint {
/**
* 出現するテトリミノをランダムで選ぶ。
* 今のところただランダム値を返すだけ。
*/
return Math.floor(Math.random() * 7);
}
private function nextTetromino(first:Boolean = false):void
{
/**
* createTetromino()で選択しておいたテトリミノパターンを現在のテトリミノとしてコピー。
* その後、次のテトリミノパターンを選択しておく。
* 開始直後の「次のテトリミノがない」状態の時はテトリミノを作成してから同様の処理を行う
*/
currentTetromino = new Array();
currentIndex = (first)? createTetromino(): nextIndex;
for (var y:int = 0; y < TET_HEIGHT; y++) {
currentTetromino[y] = TETROMINOS[currentIndex][y].concat();
}
//落下テトリミノの初期配置位置
location.x = 5;
location.y = 0;
gameover = overlapCheck(currentTetromino);
if (gameover) {
dropTimer.stop();
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
nextBorad.tetrominoClear();
fullDrawing();
tscb.text = "GAME OVER \n\nSCORE: " + score;
//graphics.clear();
//gameField.graphics.clear();
removeChild(gameField);
//gameField = null;
removeChild(nextBorad);
//nextBorad = null;
scoreboard.graphics.clear();
//removeChild(scoreboard);
//scoreboard.removeChild(tscb);
//tscb.text = null;
sceneNum++; //Scene[0.1.2.3.4.5]の表示
count = 0;
if (score >= ((scene+1) * 10))
bonus++;
changeRoot();
Minit();
} else {
nextIndex = createTetromino();
nextBorad.drawNextTetromino(TETROMINOS[nextIndex], TET_COLORS[nextIndex]);
}
}
private function reStart():void{
gameover = false;
//描画マップデータ初期化
for (var y:int = 0; y < fieldMap.length; y++) {
for (var x:int = 0; x < fieldMap[y].length; x++) {
if (fieldMap[y][x] != WALL) fieldMap[y][x] = EMPTY;
}
}
location = new Point(0, 0);
nextTetromino(true);
fullDrawing();
dropTimer.start();
}
/**
* テトリミノの操作関連処理
** ** ** ** ** ** ** ** ** ** ** **/
private function tetrominoAction(key:int):void {
/**
* テトリミノの移動判定
* 引数:方向キーのキーコード
*/
switch(key) {
case Keyboard.LEFT:
if (getLeftHit()) break;
tetrominoClear();
location.x--;
fullDrawing();
break;
case Keyboard.RIGHT:
if (getRightHit()) break;
tetrominoClear();
location.x++;
fullDrawing();
break;
case Keyboard.DOWN:
if (getBottomHit()) {
lockTetromino();
nextTetromino();
fullDrawing();
break;
}
tetrominoClear();
location.y++;
fullDrawing();
break;
case Keyboard.UP:
if (turnTetromino()) break;
fullDrawing();
break;
}
}
private function adjacentCheck(tx:int, ty:int, direct:uint):Boolean {
/**
* 渡されたゲームフィールド座標に隣接するセルが空白であるかどうかをチェックして真偽値を返す
* 引数:[tx ty] 現在のテトリミノのセルが存在しているゲームフィールド上の座標
* [direct] 調べたいのはtx tyのどの方角なのか
* 戻り値:隣にブロック、テトリミノがあるなら真を返す
*/
var mx:int, my:int;
switch(direct) {
case Keyboard.LEFT:
mx = location.x + tx -1; //一つ左隣を調べたい
my = location.y + ty;
if (fieldMap[my][mx]) return true;
else return false;
case Keyboard.RIGHT:
mx = location.x + tx +1; //一つ右隣を調べたい
my = location.y + ty;
if (fieldMap[my][mx]) return true;
else return false;
case Keyboard.DOWN:
mx = location.x + tx;
my = location.y + ty + 1; //一つ下を調べたい
if (fieldMap[my][mx]) return true;
else return false;
}
return true;
}
private function getBottomHit():Boolean
{
/**
* 現在のテトリミノ(currentTetromino:Array)
* 下方向に障害物がないかどうかをチェックして真偽値を返す。
* 戻り値:障害物があった場合に真を返す
*/
var result:Boolean;
for (var x:int = 0; x < TET_WIDTH; x++) {
for (var y:int = TET_HEIGHT - 1; y >= 0; y--) {
if (currentTetromino[y][x]) {
//テトリミノがあればチェック
result = adjacentCheck(x, y, Keyboard.DOWN);
break;
}
}
if (result) break;
}
return result;
}
private function getLeftHit():Boolean {
/**
* 現在のテトリミノ(currentTetromino:Array)
* 左方向に障害物がないかどうかをチェックして真偽値を返す。
* 戻り値:障害物があった場合に真を返す
*/
var result:Boolean;
for (var y:int = 0; y < TET_HEIGHT; y++) {
for (var x:int = 0; x < TET_WIDTH; x++) {
if (currentTetromino[y][x]) {
//テトリミノがあればチェック
result = adjacentCheck(x, y, Keyboard.LEFT);
break;
}
}
if (result) break;
}
return result;
}
private function getRightHit():Boolean
{
/**
* 現在のテトリミノ(currentTetromino:Array)
* 右方向に障害物がないかどうかをチェックして真偽値を返す。
* 戻り値:障害物があった場合に真を返す
*/
var result:Boolean;
for (var y:int = 0; y < TET_HEIGHT; y++) {
for (var x:int = TET_WIDTH - 1; x >= 0; x--) {
if (currentTetromino[y][x]) {
//テトリミノがあればチェック
result = adjacentCheck(x, y, Keyboard.RIGHT);
break;
}
}
if (result) break;
}
return result;
}
private function turnTetromino():Boolean
{
/**
* テトリミノを回転させる。
* 一度仮説で回転させて、実際のマップ上でその回転が出来るかどうかを調べる。
* 回転可能なら回転させ、不可なら回転させない。
* 戻り値は利用していない。
*/
var x:int, y:int;
var myValue:int;
var pTurn:Array = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
];
//currentTetromino:Arrayを一旦コピーする
var tetTemp:Array = new Array();
for (y = 0; y < TET_HEIGHT; y++) tetTemp[y] = currentTetromino[y].concat();
//currentTetromino:Arrayを一旦コピーしたテトリミノを時計回りに90度回転させる
for (y = 0; y < TET_HEIGHT; y++) {
for (x = 0; x < TET_WIDTH; x++) pTurn[x][TET_HEIGHT - 1 - y] = tetTemp[y][x];
}
//回転した際に、障害物に重なっていないかどうかを調べる。障害がある場合は回転しない。
if (overlapCheck(pTurn)) return true;
//問題なければ回転後のマップを確定する。ただし確定する前に描画されている元のテトリミノをクリアする
tetrominoClear();
for (y = 0; y < TET_HEIGHT; y++) currentTetromino[y] = pTurn[y].concat();
return false;
}
private function overlapCheck(pTurn:Array):Boolean
{
/**
* テトリミノを回転させた時に、他の障害物と重なっていないかをチェックして真偽値を返す
* 引数:[pTurn] 一旦回転させたテトリミノのマップ情報
* 戻り値:障害物に重なっていた場合に真を返す
*/
for (var y:int = 0; y < TET_HEIGHT; y++) {
for (var x:int = 0; x < TET_WIDTH; x++) {
if (pTurn[y][x]) {
var mx:int = location.x + x;
var my:int = location.y + y;
if(fieldMap[my][mx] && fieldMap[my][mx] != currentIndex + 1) return true;
}
}
}
return false;
}
/**
* テトリミノの固定処理など
** ** ** ** ** ** ** ** ** ** ** **/
private function lockTetromino():void
{
/**
* 下方向に移動できなくなったテトリミノをマップデータ上に固定する。
*/
for (var y:int = 0; y < TET_HEIGHT; y++) {
for (var x:int = 0; x < TET_WIDTH; x++) {
if (currentTetromino[y][x]) {
var mx:int = location.x + x;
var my:int = location.y + y;
fieldMap[my][mx] = LOCKED; // 固定を表す定数を代入
fieldMapColor[y][x] += TET_COLORS[currentIndex];
}
}
}
lineCheck();
scoreboard.addChild(tscb);
ScoreCheck();
//落下速度を少しだけ早める
if (dropTimer.delay > DELAY_MIN) dropTimer.delay--;
}
/*
private function LimitTimer()
{
var minuteTimer:Timer = new Timer(1000, 500);
mTimer.addEventListener(TimerEvent.TIMER, onTick);
//mTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
mTimer.start();
}
public function onTick(event:TimerEvent):void
{
tscb.appendtext = "\n\n Time: " + event.target.currentCount;
}
*/
//スコアの表示
private function ScoreCheck():void
{
scoreboard.removeChild(tscb)
tscb = createTextField(330, 350, 100, 100);
tscb.text = "SCORE: " + score + "\n\nTime: " + continuetime;
}
private function createTextField(x:Number, y:Number, width:Number, height:Number):TextField
{
var result:TextField = new TextField();
result.x = x;
result.y = y;
result.width = width;
result.height = height;
addChild(result);
return result;
}
private function lineCheck():void
{
/**
* 揃っているラインがないかどうかをチェックして、あった場合は削除する。
*/
deleteLineIndex = new Array();
var end:Boolean;
var x:int, y:int;
for (y = FIELD_HEIGHT - 2; y >= 0 && !end; y--) {
var zero:Boolean = false;
for (x = 0; x < FIELD_WIDTH && !zero; x++) {
if (fieldMap[y][x] <= 0) zero = true;
}
//揃った行を削除する
if (!zero) {
fieldMap.splice(y, 1, MAP_BLANK.concat());
fieldMapColor.splice(y, 1, MAP_BLANK.concat());
//削除する行の配列インデックスを保存しておく
deleteLineIndex.push(y);
//点数加算
score++;
}
}
// 削除した行を詰めるのはちょっと遅らせる
if (deleteLineIndex.length > 0) ragTimer.start();
}
/**
* 描画関連
** ** ** ** ** ** ** ** ** ** ** **/
private function tetrominoClear():void
{
/**
* マッピングデータ上から現在のテトリミノデータを消去する。
* テトリミノを移動する時に必要な処理。
*/
for (var y:int = location.y; y < location.y + TET_HEIGHT; y++) {
var py:int = y - location.y;
for (var x:int = location.x; x < location.x + TET_WIDTH; x++) {
var px:int = x - location.x;
if (currentTetromino[py][px]) {
fieldMap[y][x] = EMPTY;
fieldMapColor[y][x] = EMPTY;
}
}
}
}
private function fullDrawing():void
{
colorMapping();
drawField();
}
private function colorMapping():void
{
/**
* ゲームフィールドを描画するためのマッピングデータを作成する
*/
for (var y:int = 0; y < FIELD_HEIGHT; y++) {
for (var x:int = 0; x < FIELD_WIDTH; x++) {
//壁のマッピング
if (fieldMap[y][x] == WALL) fieldMapColor[y][x] = WALL_COLOR;
//テトリミノのマッピング
if (y >= location.y && y < location.y + TET_HEIGHT &&
x >= location.x && x < location.x + TET_WIDTH) {
var px:int = x - location.x;
var py:int = y - location.y;
if(currentTetromino[py][px] && (fieldMap[y][x] == EMPTY || gameover)) {
fieldMap[y][x] = currentTetromino[py][px];
fieldMapColor[y][x] = TET_COLORS[currentIndex];
}
}
}
}
}
private function drawField():void
{
/**
* ゲームフィールド描画
*/
var py:Number = 0;
gameField.graphics.clear();
gameField.graphics.lineStyle(1, GRID_COLOR);
for (var y:int = 0; y < fieldMap.length; y++) {
var px:Number = 0;
for (var x:int = 0; x < fieldMap[y].length; x++) {
if (fieldMap[y][x] > EMPTY) {
gameField.graphics.beginFill(fieldMapColor[y][x]);
gameField.graphics.drawRect(px, py, CELL_WIDTH, CELL_HEIGHT);
}
px += CELL_WIDTH;
}
py += CELL_HEIGHT;
}
gameField.graphics.endFill();
}
/* //ゲームの初期化?
private function initMapping():void
{
for (var y:int = 0; y < FIELD_HEIGHT; y++) {
for (var x:int = 0; x < FIELD_WIDTH; x++) {
//壁のマッピング
if (fieldMap[y][x] == WALL) fieldMapColor[y][x] = WALL_COLOR;
}
}
}
*/ }
}
/*
-------------------------------------
-------------------------------------
-------------------------------------
-------------------------------------
-------------------------------------
*/
import flash.display.Sprite;
import flash.display.Shape;
/**
* ...
* @author necoEngine
*/
class NextTetrrominoDisplay extends Sprite {
private const FRAME_WIDTH:uint = 120;
private const FRAME_HEIGHT:uint = 120;
private const CENTER_X:uint = FRAME_WIDTH / 2;
private const CENTER_Y:uint = FRAME_HEIGHT / 2;
private const CELL_WIDTH:uint = 20;
private const CELL_HEIGHT:uint = 20;
private const FRAME_COLOR:uint = 0xFFCC00;
private const GRID_COLOR:uint = 0xC0C0C0;
private var baseFrame:Shape;
private var tetrominoShape:Shape;
public function NextTetrrominoDisplay():void
{
init();
}
private function init():void
{
baseFrame = new Shape();
addChild(baseFrame);
baseFrame.graphics.lineStyle(2, FRAME_COLOR, 1);
baseFrame.graphics.drawRoundRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT, 10, 10);
tetrominoShape = new Shape();
addChild(tetrominoShape);
}
public function drawNextTetromino(mapData:Array, color:int):void
{
/**
* 次に落下させるテトリミノを描画する。
*/
var py:Number = 0;
tetrominoShape.graphics.clear();
tetrominoShape.graphics.lineStyle(1, GRID_COLOR);
for (var y:int = 0; y < mapData.length; y++)
{
var px:Number = 0;
var hit:Boolean;
for (var x:int = 0; x < mapData[y].length; x++) {
if (mapData[y][x]) {
tetrominoShape.graphics.beginFill(color);
tetrominoShape.graphics.drawRect(px, py, CELL_WIDTH, CELL_HEIGHT);
hit = true;
}
px += CELL_WIDTH;
}
if (hit) py += CELL_HEIGHT;
}
tetrominoShape.graphics.endFill();
tetrominoShape.x = -(CELL_WIDTH * 2 - CENTER_X);
//幅が違うものを少し補正
if (tetrominoShape.width > 50 && tetrominoShape.width < 70) tetrominoShape.x -= 10;
tetrominoShape.y = -(tetrominoShape.height / 2 - CENTER_Y);
}
public function tetrominoClear():void { tetrominoShape.graphics.clear(); }
}