#東方弾幕風 #Title[よっつつなげるときえる符「ぷよぷよ」] #Text[] #ScriptVersion[2] #Image[] #BGM[] /*=================================================================== 今更ながら弾幕風テトリスに影響を受けて作ってみました。 若干重いので(特にピースが増えてくると)ゲームになるかどうか怪しいですが…。 もし何かご意見を頂けるようでしたら、 登録してすっぽかしっぱなしのTwitterアカウント"@ Haya_Maki"までお願いします。。 気が向いたら次Ver出します。気が向いたら。 */=================================================================== script_enemy_main { @Initialize { CutIn(YOUMU, "よっつつなげるときえる符「ぷよぷよ」", "", 0, 0 ,0 ,0); SetLife(100); ////SetTimer(92); SetDurableSpellCard; MagicCircle(false); SetScore(500000); SetPlayerIni; SetGameField; DropPiece; MovePiece; Enemy; ///Slow(1); //CreateDebugWindow; SetMovePosition02(GetCenterX, GetCenterY, 60); } @MainLoop { yield; } let CELL = 17.5; // ピース間の間隔 let FIELD_WIDTH = 6; let FIELD_HEIGHT = 12; let FIELD_BOTTOM = GetClipMaxY - 60; let FIELD_TOP = GetClipMaxY - 60 - (CELL*FIELD_HEIGHT); let FIELD_LEFT = GetCenterX - (FIELD_WIDTH*CELL)*0.5 - CELL*1; let FIELD_RIGHT = GetCenterX + (FIELD_WIDTH*CELL)*0.5; let FIELD_CENTER = FIELD_LEFT + CELL * 3; let CASE_0 = YELLOW01; // 黄 let CASE_1 = RED01; // 赤 let CASE_2 = GREEN01; // 緑 let CASE_3 = BLUE01; // 青 let CASE_4 = PURPLE01; // 紫 let CASE_5 = ORANGE01; // 橙 let CASE_6 = AQUA01; // 水 let CASE_J = WHITE01; // 灰(おじゃまぷよ) let COLOR_VARIATION = 4;// ピースは何色使うか //let WAIT_TIMES = 10; // WAIT_TIMES毎に1マス進む // ぷよぷよでは1フレームごとに滑らかに落下させます let DROP_SPEED = 0.5; // 1フレーム毎に進むピクセル数 let DROP_SPEED_QUICK = 4; let DELETE_NUMBER = 4;// 何個繋がったら消えるか let CHAIN_COUNT = 1;// 連鎖数管理 let OJAMA_RATE = 140;// おじゃまレート管理(DeleteScore/OJAMA_RATE = 落とすおじゃまぷよ) let DroppedFrag = "False";// 操作中ピースが着地したら"True" let PieceAFrag = "False";// ピースAが着地したら"True" let PieceBFrag = "False";// ピースBが着地したら"True" let DeleteFrag = "False";// ピースを消したら"True" // ↑グローバル変数================================================================= // ピースを落とすためのtask // あと消すのも管理してます let DeleteScore = 0;// 消したときのスコアを示す変数(DeleteScore/OJAMA_RATE = 落とすおじゃまぷよ) task DropPiece{ wait(120); let arrayRandomA = []; let arrayRandomB = []; loop(3){ arrayRandomA = arrayRandomA ~ [rand_int(0,COLOR_VARIATION - 1)]; arrayRandomB = arrayRandomB ~ [rand_int(0,COLOR_VARIATION - 1)]; } let StockJ = 0;// 30個以上のおじゃまぷよは次に繰り越すための変数 let Jfrag = "False"; loop{ let type = [CASE_0, CASE_1, CASE_2, CASE_3, CASE_4, CASE_5, CASE_6]; CreateNextPiece(FIELD_RIGHT + CELL, FIELD_TOP + CELL*2, type[arrayRandomA[1]], type[arrayRandomB[1]]); CreateNextPiece(FIELD_RIGHT + CELL, FIELD_TOP + CELL*5, type[arrayRandomA[2]], type[arrayRandomB[2]]); CreatePieceA(FIELD_CENTER, FIELD_TOP-CELL, type[arrayRandomA[0]], type[arrayRandomB[0]]); arrayRandomA = erase(arrayRandomA, 0); arrayRandomB = erase(arrayRandomB, 0); arrayRandomA = arrayRandomA ~ [rand_int(0,COLOR_VARIATION - 1)]; arrayRandomB = arrayRandomB ~ [rand_int(0,COLOR_VARIATION - 1)]; //着地するまで待つ while(DroppedFrag != "True" || PieceAFrag != "True" || PieceBFrag != "True"){ yield; } DeleteScore += DeletePiece; if(DeleteFrag != "False"){ // 一連鎖してたらもう一度DeletePieceを呼ぶ loop{ DeleteFrag = "False"; CHAIN_COUNT ++; wait(30);// DeletePieceとDeletePieceの間はyield必須っぽい? DeleteScore += DeletePiece; if(DeleteFrag == "False"){ break; } } } else{ //↓++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 試験的に、自身の連鎖分のおじゃまぷよが自フィールドに落ちてきます;; let SendOjama = int(DeleteScore/OJAMA_RATE); DeleteScore -= SendOjama * OJAMA_RATE; if(SendOjama < 0){ SendOjama = 0;} let FallOjama = int(ENEMY_SCORE/OJAMA_RATE); ENEMY_SCORE -= FallOjama * OJAMA_RATE; FallOjama -= SendOjama; FallOjama += StockJ; // 30個以上はいっぺんに落とさない if(FallOjama > 30){ StockJ = FallOjama - 30; FallOjama = 30; } else{ StockJ = 0; } let DropY = 1; while(FallOjama >= 1){ let arrayLine = [1,2,3,4,5,6]; loop{ let Random = rand_int(0, length(arrayLine)-1); CreatePieceJ(FIELD_LEFT + CELL*arrayLine[Random], FIELD_TOP - CELL*DropY); arrayLine = erase(arrayLine, Random); FallOjama--; if(FallOjama < 1 || length(arrayLine) < 1){ //wait(10); break; } } DropY++; wait(2); wait(10*(DropY - 1)); } //↑++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } //フラグをもどす DroppedFrag = "False"; PieceAFrag = "False"; PieceBFrag = "False"; //連鎖数をもどす CHAIN_COUNT = 1; yield; } } // 仮想敵の攻撃(?)task let ENEMY_SCORE = 0; let COUNT_E = 0; task Enemy{ let dropnum = 1; wait(180); loop{ if(COUNT_E > 1000){ ENEMY_SCORE += OJAMA_RATE * rand_int(int(dropnum), int(dropnum)+3); COUNT_E = 0; dropnum += 1; if(DROP_SPEED <= 1.5){DROP_SPEED += 0.05;} if(OJAMA_RATE <= 40){OJAMA_RATE -= 2.5;} } while(CHAIN_COUNT != 1){yield;} COUNT_E ++; yield; } } // ピースA(回転の際の軸となるほう)のtask let arrayPieceA = []; task CreatePieceA(x, y, colorA, colorB){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, 90);// ←意外とどうでもいい ObjShot_SetGraphic(obj, colorA); ObjShot_SetDelay(obj, 10); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); Obj_SetAlpha(obj, 255);// グラフィック消さない Obj_SetCollisionToPlayer(obj, false);// 攻撃判定なし // オブジェクトIDの登録 arrayPieceA = arrayPieceA ~ [obj]; // ピースBを作成 CreatePieceB(x, y - CELL, colorB, obj); while( DroppedFrag != "True" ){ Obj_SetAngle( obj, Obj_GetAngle(arrayPieceB[0])+180 ); yield; } FreeFall(obj); CreateDroppedPiece(Obj_GetX(obj), Obj_GetY(obj), colorA); Obj_Delete(obj); PieceAFrag = "True"; // オブジェクトIDの削除 ascent(A in 0..length(arrayPieceA)){ if(obj==arrayPieceA[A]){ arrayPieceA = erase(arrayPieceA, A); break; } } } // ピースB(ピースAを軸として回転するほう)のtask let arrayPieceB = []; task CreatePieceB(x, y, colorB, ParentID){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, -90);// 初期位置:ピースAから見て-90度方向にセットします ObjShot_SetGraphic(obj, colorB); ObjShot_SetDelay(obj, 10); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); Obj_SetAlpha(obj, 255);// グラフィック消さない Obj_SetCollisionToPlayer(obj, false);// 攻撃判定なし // オブジェクトIDの登録 arrayPieceB = arrayPieceB ~ [obj]; while( DroppedFrag != "True" ){ Obj_SetX( obj, Obj_GetX(ParentID) + CELL * cos(Obj_GetAngle(obj)) ); Obj_SetY( obj, Obj_GetY(ParentID) + CELL * sin(Obj_GetAngle(obj)) ); // ショットボタンで右回転====================================================================== if(GetKeyState(VK_SHOT) == KEY_PUSH){ let angle = 0; let NextX = Obj_GetX(ParentID) + CELL * cos(Obj_GetAngle(obj)+90); let NextY = Obj_GetY(ParentID) + CELL * sin(Obj_GetAngle(obj)+90); let RightCell = 0; let LeftCell = 0; let TwiceRotation = "False"; // 右のマスが空白じゃなかったら左に一マスシフトフラグ if(NextX >= FIELD_RIGHT){ RightCell = 1; } ascent(D in 0..length(arrayDroppedPiece)){ if(NextX + CELL > Obj_GetX(arrayDroppedPiece[D]) && NextX <= Obj_GetX(arrayDroppedPiece[D]) && NextY > Obj_GetY(arrayDroppedPiece[D]) - CELL*0.5){ RightCell = 1; break; } } // 左のマスが空白じゃなかったら右に一マスシフトフラグ if(NextX <= FIELD_LEFT){ LeftCell = 1; } ascent(D in 0..length(arrayDroppedPiece)){ if(NextX - CELL < Obj_GetX(arrayDroppedPiece[D]) && NextX >= Obj_GetX(arrayDroppedPiece[D]) && NextY > Obj_GetY(arrayDroppedPiece[D]) - CELL*0.5){ LeftCell = 1; break; } } if(RightCell == 1 && LeftCell == 1){ TwiceRotation = "True"; } if(RightCell == 1 && TwiceRotation == "False"){ if( Obj_GetAngle(obj) == 0 || Obj_GetAngle(obj) == 270 ){ Obj_SetX( ParentID, Obj_GetX(ParentID) - CELL ); } } if(LeftCell == 1 && TwiceRotation == "False"){ if( Obj_GetAngle(obj) == 90){ Obj_SetX( ParentID, Obj_GetX(ParentID) + CELL ); } } // 下のマスが空白じゃなかったら上に一マスシフト if(NextY + CELL >= FIELD_BOTTOM){ Obj_SetY( ParentID, Obj_GetY(ParentID) - CELL ); } ascent(D in 0..length(arrayDroppedPiece)){ if(NextY + CELL >= Obj_GetY(arrayDroppedPiece[D]) && NextX - CELL*0.5 <= Obj_GetX(arrayDroppedPiece[D]) && NextX + CELL*0.5 >= Obj_GetX(arrayDroppedPiece[D])){ Obj_SetY( ParentID, Obj_GetY(ParentID) - CELL ); break; } } if(TwiceRotation == "True"){ Obj_SetAngle( obj, Obj_GetAngle(obj)+180 ); } if(TwiceRotation == "False"){ while(angle <= 90){ Obj_SetX( obj, Obj_GetX(ParentID) + CELL * cos(Obj_GetAngle(obj) + angle) ); Obj_SetY( obj, Obj_GetY(ParentID) + CELL * sin(Obj_GetAngle(obj) + angle) ); angle += 30; //↓のyield;を有効にすると滑らかに90度回転します。 //でも回転途中でピースにぶつけるとめり込んだりしてしまいます(( //yield; } Obj_SetAngle( obj, Obj_GetAngle(obj)+90 ); } }// =========================================================================== // ボムボタンで左回転====================================================================== if(GetKeyState(VK_BOMB) == KEY_PUSH){ let angle = 0; let NextX = Obj_GetX(ParentID) + CELL * cos(Obj_GetAngle(obj) - 90); let NextY = Obj_GetY(ParentID) + CELL * sin(Obj_GetAngle(obj) - 90); let RightCell = 0; let LeftCell = 0; let TwiceRotation = "False"; // 右のマスが空白じゃなかったら左に一マスシフトフラグ if(NextX >= FIELD_RIGHT){ RightCell = 1; } ascent(D in 0..length(arrayDroppedPiece)){ if(NextX + CELL > Obj_GetX(arrayDroppedPiece[D]) && NextX <= Obj_GetX(arrayDroppedPiece[D]) && NextY > Obj_GetY(arrayDroppedPiece[D]) - CELL*0.5){ RightCell = 1; break; } } // 左のマスが空白じゃなかったら右に一マスシフトフラグ if(NextX <= FIELD_LEFT){ LeftCell = 1; } ascent(D in 0..length(arrayDroppedPiece)){ if(NextX - CELL < Obj_GetX(arrayDroppedPiece[D]) && NextX >= Obj_GetX(arrayDroppedPiece[D]) && NextY > Obj_GetY(arrayDroppedPiece[D]) - CELL*0.5){ LeftCell = 1; break; } } if(RightCell == 1 && LeftCell == 1){ TwiceRotation = "True"; } if(RightCell == 1 && TwiceRotation == "False"){ if( Obj_GetAngle(obj) == 90){ Obj_SetX( ParentID, Obj_GetX(ParentID) - CELL ); } } if(LeftCell == 1 && TwiceRotation == "False"){ if( Obj_GetAngle(obj) == 0 || Obj_GetAngle(obj) == 270 ){ Obj_SetX( ParentID, Obj_GetX(ParentID) + CELL ); } } // 下のマスが空白じゃなかったら上に一マスシフト if(NextY + CELL >= FIELD_BOTTOM){ Obj_SetY( ParentID, Obj_GetY(ParentID) - CELL ); } ascent(D in 0..length(arrayDroppedPiece)){ if(NextY + CELL >= Obj_GetY(arrayDroppedPiece[D]) && NextX - CELL*0.5 <= Obj_GetX(arrayDroppedPiece[D]) && NextX + CELL*0.5 >= Obj_GetX(arrayDroppedPiece[D])){ Obj_SetY( ParentID, Obj_GetY(ParentID) - CELL ); break; } } if(TwiceRotation == "True"){ Obj_SetAngle( obj, Obj_GetAngle(obj)+180 ); } if(TwiceRotation == "False"){ while(angle >= -90){ Obj_SetX( obj, Obj_GetX(ParentID) + CELL * cos(Obj_GetAngle(obj) + angle) ); Obj_SetY( obj, Obj_GetY(ParentID) + CELL * sin(Obj_GetAngle(obj) + angle) ); angle -= 30; //↓のyield;を有効にすると滑らかに90度回転します。 //でも回転途中でピースにぶつけるとめり込んだりしてしまいます(( //yield; } Obj_SetAngle( obj, Obj_GetAngle(obj)-90 ); } } //=========================================================================== if(Obj_GetAngle(obj) > 360){Obj_SetAngle(obj, Obj_GetAngle(obj)-360)} if(Obj_GetAngle(obj) < 0){Obj_SetAngle(obj, Obj_GetAngle(obj)+360)} yield; } FreeFall(obj); CreateDroppedPiece(Obj_GetX(obj), Obj_GetY(obj), colorB); Obj_Delete(obj); PieceBFrag = "True"; // オブジェクトIDの削除 ascent(B in 0..length(arrayPieceB)){ if(obj==arrayPieceB[B]){ arrayPieceB = erase(arrayPieceB, B); break; } } } // 着地済みのピースのtask let arrayDroppedPiece = []; task CreateDroppedPiece(x, y, color){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, color);// 角度=色の内部で取り扱われている数字(色を判別するため) ObjShot_SetGraphic(obj,color); ObjShot_SetDelay(obj, 0); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); if(color == CASE_J){ Obj_SetAlpha(obj, 128);// 着地済みおじゃまぷよだったら画像を半透明 } Obj_SetCollisionToPlayer(obj, false);// 攻撃判定なし // オブジェクトIDの登録 arrayDroppedPiece = arrayDroppedPiece ~ [obj]; while( !Obj_BeDeleted(obj) ){ if(Obj_GetY(obj) < FIELD_TOP-CELL){ break; } FreeFall(obj); yield; } Obj_Delete(obj); // オブジェクトIDの削除 ascent(let D in 0..length(arrayDroppedPiece)){ if(obj==arrayDroppedPiece[D]){ arrayDroppedPiece = erase(arrayDroppedPiece, D); break; } } } // ↓おじゃまぷよのtask+++++++++++++++++++++++++++++++++++ task CreatePieceJ(x, y){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, CASE_J);// 角度=色の内部で取り扱われている数字(色を判別するため) ObjShot_SetGraphic(obj, CASE_J); ObjShot_SetDelay(obj, 0); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); Obj_SetAlpha(obj, 128);// グラフィック半透明 Obj_SetCollisionToPlayer(obj, false);// 攻撃判定なし while( !Obj_BeDeleted(obj) ){ if(FreeFall(obj) == "Finished"){break;} yield; } CreateDroppedPiece(Obj_GetX(obj), Obj_GetY(obj), CASE_J); Obj_Delete(obj); } // ↑+++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ピースを動かすためのtask task MovePiece{ let QuickScoreCount = 0; loop{ let arrayPieceAB = []; ascent(A in 0..length(arrayPieceA)){ arrayPieceAB = arrayPieceAB ~ [arrayPieceA[A]]; } ascent(B in 0..length(arrayPieceB)){ arrayPieceAB = arrayPieceAB ~ [arrayPieceB[B]]; } let GameOver = "False"; let LeftCell = 0; let RightCell = 0; let BottomCell = 0; //0 = なにもない, 1 = 壁orピース ascent(AB in 0..length(arrayPieceAB)){// ------------------------------------------------------- //左は空白か否か判定 if(Obj_GetX(arrayPieceAB[AB]) - CELL*1 <= FIELD_LEFT ){ LeftCell = 1; } //右は空白か否か判定 if(Obj_GetX(arrayPieceAB[AB]) + CELL*1 >= FIELD_RIGHT ){ RightCell = 1; } //下は空白か否か判定 if(Obj_GetY(arrayPieceAB[AB]) + CELL*1 >= FIELD_BOTTOM ){ BottomCell = 1; } }// ------------------------------------------------------------------------------------------- ascent(AB in 0..length(arrayPieceAB)){// =============================================================== // WAIT_TIMESごとに下へ移動 if(Obj_GetY(arrayPieceAB[AB]) <= FIELD_BOTTOM && DroppedFrag != "True"){ Obj_SetY(arrayPieceAB[AB], Obj_GetY(arrayPieceAB[AB]) + DROP_SPEED); } ascent(D in 0..length(arrayDroppedPiece)){// ========================================= // 死亡フラグ if(Obj_GetY(arrayDroppedPiece[D]) < FIELD_TOP && Obj_GetX(arrayDroppedPiece[D]) > FIELD_CENTER - CELL*1 && Obj_GetX(arrayDroppedPiece[D]) < FIELD_CENTER + CELL*1){ GameOver = "True"; } ascent(AB in 0..length(arrayPieceAB)){// ------------------------------------------------------- //左は空白か否か判定 if(Obj_GetX(arrayPieceAB[AB]) - CELL <= Obj_GetX(arrayDroppedPiece[D]) && Obj_GetX(arrayPieceAB[AB]) >= Obj_GetX(arrayDroppedPiece[D]) && Obj_GetY(arrayPieceAB[AB]) > Obj_GetY(arrayDroppedPiece[D]) - CELL * 1){ LeftCell = 1; } //右は空白か否か判定 if(Obj_GetX(arrayPieceAB[AB]) + CELL >= Obj_GetX(arrayDroppedPiece[D]) && Obj_GetX(arrayPieceAB[AB]) <= Obj_GetX(arrayDroppedPiece[D]) && Obj_GetY(arrayPieceAB[AB]) > Obj_GetY(arrayDroppedPiece[D]) - CELL * 1){ RightCell = 1; } //下は空白か否か判定 if(Obj_GetY(arrayPieceAB[AB]) + CELL >= Obj_GetY(arrayDroppedPiece[D]) && Obj_GetX(arrayPieceAB[AB]) - CELL*0.5 <= Obj_GetX(arrayDroppedPiece[D]) && Obj_GetX(arrayPieceAB[AB]) + CELL*0.5 >= Obj_GetX(arrayDroppedPiece[D])){ BottomCell = 1; } }// ------------------------------------------------------------------------------------------- }// ascent(D in 0..length(arrayDroppedPiece))========================================= // 下のマスが空白じゃなかったら停止(DroppedPieceをすり替える) if(BottomCell == 1){ DroppedFrag = "True"; } // キー操作により左へ移動 // 左押しで移動 if(GetKeyState(VK_LEFT) == KEY_PUSH && DroppedFrag != "True" && LeftCell == 0){ Obj_SetX(arrayPieceAB[AB], Obj_GetX(arrayPieceAB[AB]) - CELL); } // キー操作により右へ移動 // 右押しで移動 if(GetKeyState(VK_RIGHT) == KEY_PUSH && DroppedFrag != "True" && RightCell == 0){ Obj_SetX(arrayPieceAB[AB], Obj_GetX(arrayPieceAB[AB]) + CELL); } // キー操作により下へ移動 // 下押しっぱなしで下がる if(GetKeyState(VK_DOWN) == KEY_HOLD && DroppedFrag != "True" && BottomCell == 0){ Obj_SetY(arrayPieceAB[AB], Obj_GetY(arrayPieceAB[AB]) + DROP_SPEED_QUICK); QuickScoreCount++; if(CELL*1.5 <= DROP_SPEED_QUICK*QuickScoreCount){ AddScore(1); QuickScoreCount = 0; } } }// ascent(AB in 0..length(arrayPieceAB))=============================================================== //ピースが出るとこが塞がったらShootDownPlayer if(GameOver == "True"){ ShootDownPlayer; AddLife(-GetLife); ascent(D in 0..length(arrayDroppedPiece)){ Obj_Delete(arrayDroppedPiece[D]); } ascent(AB in 0..length(arrayPieceAB)){ Obj_Delete(arrayPieceAB[AB]); } } yield; } } //================================================================ // ピース削除を管理するファンクション function DeletePiece{ let arrayAngle = [0, 90, 180, 270]; let arrayDeletedID = []; let DeleteScore = 0; //++++++++++++++++++++ let arrayDeleteJ = []; //++++++++++++++++++++ ascent(D in 0..length(arrayDroppedPiece)){// ==================================================== let arrayStockedID = []; let arrayCheckedID = []; let DeletedFrag = "False"; ascent(DEL in 0..length(arrayDeletedID)){ if(arrayDroppedPiece[D] == arrayDeletedID[DEL]){ DeletedFrag = "True"; } } if(DeletedFrag != "True" && Obj_GetAngle(arrayDroppedPiece[D]) != CASE_J){// =============================================== arrayStockedID = arrayStockedID ~ [arrayDroppedPiece[D]]; arrayCheckedID = arrayCheckedID ~ [arrayDroppedPiece[D]]; loop{// arrayStockedIDが空になったら脱出=================================== let i = 0; while(i <= 3){ let GotID = GetAroundID(arrayStockedID[length(arrayStockedID) - 1], arrayAngle[i], "True"); if(GotID != 0 && Obj_GetAngle(GotID) != CASE_J && Obj_GetAngle(GotID) == Obj_GetAngle(arrayStockedID[length(arrayStockedID) - 1])){ let CheckFrag = "False"; ascent(C in 0..length(arrayCheckedID)){ if(GotID == arrayCheckedID[C]){ CheckFrag = "True"; i++; } } if(CheckFrag == "False"){ arrayStockedID = arrayStockedID ~ [GotID]; arrayCheckedID = arrayCheckedID ~ [GotID]; i = 0; } } else{ i++; } } arrayStockedID = erase(arrayStockedID, length(arrayStockedID) - 1); if(length(arrayStockedID) == 0){ break; } }// arrayStockedIDが空になったら脱出====================================== if(length(arrayCheckedID) >= DELETE_NUMBER){ //得点加算------------------------------------------------- let ChainBonus = 1; if(CHAIN_COUNT > 1){ ChainBonus = 2^(CHAIN_COUNT+1); } let MoreChains = 1; if(length(arrayCheckedID) > 4){ MoreChains = (length(arrayCheckedID)-4) + 1; } if(length(arrayCheckedID) > 10){ MoreChains = 10; } AddScore(10 * length(arrayCheckedID) * ChainBonus * MoreChains); DeleteScore = 10 * length(arrayCheckedID) * ChainBonus * MoreChains; //--------------------------------------------------------- ascent(C in 0..length(arrayCheckedID)){ arrayDeletedID = arrayDeletedID ~ [arrayCheckedID[C]]; //↓++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 削除するピースの周辺四方向のIDを取得してみる let i = 0; while(i <= 3){ //GetAroundID_Jで色は無差別にIDを取得 let GotID = GetAroundID(arrayCheckedID[C], arrayAngle[i], "False"); // 1:取得したピースがおじゃまぷよだったら arrayDeleteJ にIDを保存 // 下の"2:"で消す if(Obj_GetAngle(GotID) == CASE_J){ arrayDeleteJ = arrayDeleteJ ~ [GotID]; DeleteEffect(Obj_GetX(GotID), Obj_GetY(GotID), Obj_GetAngle(GotID)); } i++; } //↑++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DeleteEffect(Obj_GetX(arrayCheckedID[C]), Obj_GetY(arrayCheckedID[C]), Obj_GetAngle(arrayCheckedID[C])); } DeleteFrag = "True"; } }// ascent(D in 0..length(arrayDroppedPiece))=================================================== }// if(DeletedFrag != "True")=============================================== if(length(arrayDeletedID) != 0){ wait(50); } ascent(DEL in 0..length(arrayDeletedID)){ Obj_Delete(arrayDeletedID[DEL]); } //↓+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 2:保存したIDを持つおじゃまぷよを消す ascent(J in 0..length(arrayDeleteJ)){ Obj_Delete(arrayDeleteJ[J]); } //↑+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(DeleteScore != 0){ return DeleteScore; } } // 指定した方向の隣接同色ピースのIDを取得するfunction // Angle は探すマスがどの方向にあるか指定(0, 90, 180, 270) // SameColorが"True"なら同じ色のIDしか取得しない function GetAroundID(CenterID, Angle, SameColor){ let CenterX = Obj_GetX(CenterID); let CenterY = Obj_GetY(CenterID); let CenterColor = Obj_GetAngle(CenterID); let NextID = 0; ascent(D in 0..length(arrayDroppedPiece)){ let NextToX = Obj_GetX(arrayDroppedPiece[D]); let NextToY = Obj_GetY(arrayDroppedPiece[D]); let NextToColor = Obj_GetAngle(arrayDroppedPiece[D]); // SameColorが"False"なら色の判別を無効化する if(SameColor == "False"){ NextToColor = CenterColor; } let distance = ((CenterX - NextToX)^2 + (CenterY - NextToY)^2) ^ (1/2); if(distance <= CELL && CenterID != arrayDroppedPiece[D]){ //サーチ方向は右のセル if(Angle == 0){ if(CenterColor == NextToColor && CenterX < NextToX){ NextID = arrayDroppedPiece[D]; } } //サーチ方向は下のセル if(Angle == 90){ if(CenterColor == NextToColor && CenterY < NextToY){ NextID = arrayDroppedPiece[D]; } } //サーチ方向は左のセル if(Angle == 180){ if(CenterColor == NextToColor && CenterX > NextToX){ NextID = arrayDroppedPiece[D]; } } //サーチ方向は上のセル if(Angle == 270){ if(CenterColor == NextToColor && CenterY > NextToY){ NextID = arrayDroppedPiece[D]; } } } } return NextID; //下の※より、未使用値(ここでは0)がNextIDとして返った場合はIDを取得できなかったということになる。 } //めもちょう====================================================== //※弾オブジェクトのIDは257〜655359の間で変動し、655359を超えると257に戻る。 //↓通ってる場所をチェックしたいときに使ってね /* DeleteEffect(GetX,GetY,WHITE01); */ //↓デバッグしたいとき使ってね //CreateDebugWindow; //OutputDebugString(引数:3) //1) 情報を出力する位置(0-10程度) //2) 任意の文字列 //3) 情報を表示したい変数等 //================================================================ // 落ちるとこまで落としてみせるファンクション function FreeFall(ParentID){ let BottomCell = 0; while(BottomCell == 0){ BottomCell = 0; ascent(DD in 0..length(arrayDroppedPiece)){ if(Obj_GetY(ParentID) < Obj_GetY(arrayDroppedPiece[DD]) && ParentID != DD && Obj_GetY(ParentID) + CELL >= Obj_GetY(arrayDroppedPiece[DD]) && Obj_GetX(ParentID) - CELL*0.5 <= Obj_GetX(arrayDroppedPiece[DD]) && Obj_GetX(ParentID) + CELL*0.5 >= Obj_GetX(arrayDroppedPiece[DD])){ Obj_SetY(ParentID, Obj_GetY(arrayDroppedPiece[DD]) - CELL); BottomCell = 1; } } if(Obj_GetY(ParentID) >= FIELD_BOTTOM - CELL){ Obj_SetY(ParentID, FIELD_BOTTOM - CELL); BottomCell = 1; } if(BottomCell == 0){ Obj_SetY(ParentID, Obj_GetY(ParentID) + DROP_SPEED_QUICK); } yield; } return "Finished"; } // 自機を管理するためのtask task SetPlayerIni{ ForbidShot(true); ForbidBomb(true); loop{ SetPlayerX(GetCenterX); SetPlayerY(GetClipMaxY-30); yield; } } // ぷよぷよのゲームフィールドを分かりやすくするためのsub sub SetGameField{ // FIELD_BOTTOMを示すレーザーです CreateLaserA(01, GetClipMinX-60, FIELD_BOTTOM, 500, 5, WHITE01, 120); SetLaserDataA(01, 0, 0, 0, 0, 0, 0); FireShot(01); // FIELD_TOPを示すレーザーです CreateLaserA(01, GetClipMinX-60, FIELD_TOP, 500, 5, RED01, 120); SetLaserDataA(01, 0, 0, 0, 0, 0, 0); FireShot(01); // FIELD_LEFTを示すレーザーです CreateLaserA(01, FIELD_LEFT, GetClipMinY-60, 600, 5, WHITE01, 120); SetLaserDataA(01, 0, 90, 0, 0, 0, 0); FireShot(01); // FIELD_RIGHTを示すレーザーです CreateLaserA(01, FIELD_RIGHT, GetClipMinY-60, 600, 5, WHITE01, 120); SetLaserDataA(01, 0, 90, 0, 0, 0, 0); FireShot(01); // 塞いだらアウトのマスを示すレーザーです CreateLaserA(01, FIELD_CENTER + CELL*1, FIELD_TOP, 1, 1, RED01, 120); SetLaserDataA(01, 0, 0, 0, 0, 0, 0); FireShot(01); CreateLaserA(01, FIELD_CENTER + CELL*0, FIELD_TOP, 1, 1, RED01, 120); SetLaserDataA(01, 0, 0, 0, 0, 0, 0); FireShot(01); } // 消したときのエフェクトっぽいfunction function DeleteEffect(x, y, color){ CreateShotA(01, x, y, 60); SetShotDataA(01, 0, 0, 90, 0, 0, 0, color); SetShotKillTime(01, 0); FireShot(01); } // 次のピースABを示すObjectを作るtask task CreateNextPiece(x, y, typeA, typeB){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, x); Obj_SetY(obj, y); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, 90); ObjShot_SetGraphic(obj, typeA); ObjShot_SetDelay(obj, 10); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); Obj_SetAlpha(obj, 255);//グラフィック消さない Obj_SetCollisionToPlayer(obj, true);//攻撃判定ありでいいや Obj_SetCollisionToObject(obj, true); // Bをセット CreateNextPieceB(typeB, obj); while( DroppedFrag != "True" ){ yield; } Obj_Delete(obj); } // 次のピースBを示すObjectを作るtask(上のタスクの部品) task CreateNextPieceB(typeB, ParentID){ let obj = Obj_Create(OBJ_SHOT); Obj_SetX(obj, Obj_GetX(ParentID)); Obj_SetY(obj, Obj_GetY(ParentID) - CELL); Obj_SetSpeed(obj, 0); Obj_SetAngle(obj, 90); ObjShot_SetGraphic(obj, typeB); ObjShot_SetDelay(obj, 10); Obj_SetAutoDelete(obj, false); ObjShot_SetBombResist(obj, true); Obj_SetAlpha(obj, 255);//グラフィック消さない Obj_SetCollisionToPlayer(obj, true);//攻撃判定ありでいいや Obj_SetCollisionToObject(obj, true); while( !Obj_BeDeleted(ParentID) ){ yield; } Obj_Delete(obj); } //wait(待つフレーム); function wait(n) { loop(n) { yield; } } @DrawLoop { } @BackGround{ SetFontColor(128,128,128, 255,255,255); DrawText(NumToString(int(ENEMY_SCORE/OJAMA_RATE)-int(DeleteScore/OJAMA_RATE)), 180, FIELD_TOP-CELL*3, 32, 255); DrawText(NumToString(int(COUNT_E)/10), 300, FIELD_TOP-CELL*3, 16, 255); DrawText(NumToString(int(COUNT_E)), 330, FIELD_TOP-CELL*3+5, 12, 255); DrawText("/100", 320, FIELD_TOP-CELL*2, 18, 255); } function NumToString(num){ let leng = int(log10(num))+2;//整数部分の桁数を求める let string = ToString(num);//数字を文字列に変える return string[0..int(log10(num))+2];//文字列をスライシングして返す } @Finalize { } }