ということで新年早々、まずは簡単なものから作り、徐々に自信を取り戻していこうかと。(カブトムシ感
簡単なものなので、ソースファイル分けずにまるっと作っちゃいました。
しかし、やはり作りこんでいくほどに不便になりますね(;^ω^)
↓ソースコード
► スポイラーを表示
#include "DxLib.h"
//ウィンドウ
static const int WINDOW_WIDTH = 416;
static const int WINDOW_HEIGHT = 320;
//パズル
static const int PIECE_NUM = 16;
static const int PUZZLE_LENGTH = 4;
static const int PIECE_SIZE = 64;
static const int PIECE_BASE_POS_X = 32;
static const int PIECE_BASE_POS_Y = 32;
//ボタン
static const int BTN_WIDTH = 96;
static const int BTN_HEIGHT = 32;
static const int BTN_BASE_POS_X = (PIECE_BASE_POS_X + PIECE_SIZE*PUZZLE_LENGTH + 16);
static const int BTN_BASE_POS_Y = (320 - 32 * 4);
enum {
MOVE_RIGHT,
MOVE_LEFT,
MOVE_UP,
MOVE_DOWN,
MOVE_DIR,
};
int graphic_handle[2][PIECE_NUM];//ピースのグラフィックハンドル
int background_gh;//背景のグラフィックハンドル
int select_handle;
int in_piece[PIECE_NUM]; //ピースの並び順データ
int area[MOVE_DIR]; //空ピース4方向のエリア番号を格納する用
int empty_area;
//マウス操作==========
int MouseState;
int MousePushState;
int MousePosX ;
int MousePosY;
//=================
//四角形の座標
struct BoxPos {
int x;
int y;
int w;
int h;
};
struct Button{
BoxPos pos;
int push_state;
char* name;
};
enum {
BTN_IMAGE_CHNGE,
BTN_SHUFFLE,
BTN_EXIT,
BTN_NUM,
};
Button btn[BTN_NUM];
char* btn_name[BTN_NUM] = {
"画像変更","シャッフル","終了",
};
void GameInit();
bool CheckClear();
bool Point_Box_Collision(int pointX,int pointY,BoxPos box);//座標と四角形の判定
void MovingArea_Update();//動かせるピースの更新
int GetEmptyArea();//空ピースのエリア番号を得る
void Piece_Shuffle(int num);//ピースを混ぜる
void Swap_Piece(int area);
//ボタン関係
void ButtonInit();
void ButtonUpdate();
//デバッグ用================
BoxPos GetBoxPos(int area);
void DrawAreaBox(int area,int color);
//=======================
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
SetGraphMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32);//ウィンドウのサイズ変更
SetWindowText("15Puzzle"); //ウィンドウのタイトル変更
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定
//画像をロード
background_gh = LoadGraph("backImage.png");
LoadDivGraph("wan_dot.png", PIECE_NUM, PUZZLE_LENGTH, PUZZLE_LENGTH, PIECE_SIZE, PIECE_SIZE, graphic_handle[0]);
LoadDivGraph("nyan_dot.png", PIECE_NUM, PUZZLE_LENGTH, PUZZLE_LENGTH, PIECE_SIZE, PIECE_SIZE, graphic_handle[1]);
select_handle = 0;
GameInit();
ButtonInit();
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
//コントロール========================================================
//マウスポインタの座標を取得
GetMousePoint(&MousePosX,&MousePosY);
//マウスの左クリックの状態を取得
MouseState=GetMouseInput();
if (MouseState == MOUSE_INPUT_LEFT)
MousePushState++;
else
MousePushState = 0;
//================================================================
//ピースの制御=======================================================
MovingArea_Update();
if (MousePushState == 1) {
for (int i = 0; i box.x&&pointY > box.y && (box.w) > pointX && (box.h) > pointY)
return true;
return false;
}
void MovingArea_Update() {
empty_area = GetEmptyArea();
int emp_col=(empty_area%PUZZLE_LENGTH);
int emp_row = (empty_area /PUZZLE_LENGTH);
area[MOVE_UP] = (emp_row - 1)*PUZZLE_LENGTH + emp_col;
area[MOVE_DOWN]= (emp_row + 1)*PUZZLE_LENGTH + emp_col;
area[MOVE_RIGHT]= emp_row *PUZZLE_LENGTH + (emp_col+1);
area[MOVE_LEFT] = emp_row *PUZZLE_LENGTH + (emp_col - 1);
if (emp_row < 1)
area[MOVE_UP] = -1;
if (emp_row == PUZZLE_LENGTH-1)
area[MOVE_DOWN] = -1;
if (emp_col < 1)
area[MOVE_LEFT] = -1;
if (emp_col == PUZZLE_LENGTH-1)
area[MOVE_RIGHT] = -1;
/*デバッグ用
if (area[MOVE_UP] != -1)
DrawAreaBox(area[MOVE_UP],GetColor(255,0,0));
if (area[MOVE_DOWN] != -1)
DrawAreaBox(area[MOVE_DOWN], GetColor(255, 255, 0));
if (area[MOVE_LEFT] != -1)
DrawAreaBox(area[MOVE_LEFT], GetColor(0, 255, 0));
if (area[MOVE_RIGHT] != -1)
DrawAreaBox(area[MOVE_RIGHT], GetColor(0, 0, 255));
*/
}
int GetEmptyArea() {
for (int i = 0; i < PIECE_NUM; i++) {
if (in_piece[i] == 0)
return i;
}
return -1;
}
void Piece_Shuffle(int num) {
for (int i = 0; i <= num; i++) {
int select_area = area[GetRand(3)];
MovingArea_Update();
if (select_area != -1)
Swap_Piece(select_area);
}
}
void Swap_Piece(int area) {
int tmp = in_piece[area];
in_piece[area] = 0;
in_piece[empty_area] = tmp;
}
void GameInit() {
//ピース初期化
for (int i = 0; i < PIECE_NUM; i++) {
in_piece[i] = i;
}
MovingArea_Update();
Piece_Shuffle(20);
if (CheckClear())//もし初期状態ならもう一度シャッフルする
Piece_Shuffle(20);
}
bool CheckClear() {
for (int i = 0; i < PIECE_NUM; i++) {
if (in_piece[i] != i)
return false;
}
return true;
}
BoxPos GetBoxPos(int area) {
BoxPos box;
box.x = area%PUZZLE_LENGTH*PIECE_SIZE + PIECE_BASE_POS_X;
box.y = area / PUZZLE_LENGTH*PIECE_SIZE + PIECE_BASE_POS_Y;
box.w = area%PUZZLE_LENGTH * PIECE_SIZE + PIECE_SIZE + PIECE_BASE_POS_X;
box.h = area / PUZZLE_LENGTH * PIECE_SIZE + PIECE_SIZE + PIECE_BASE_POS_Y;
return box;
}
void DrawAreaBox(int area, int color) {
DrawBox(area%PUZZLE_LENGTH*PIECE_SIZE + PIECE_BASE_POS_X, area / PUZZLE_LENGTH*PIECE_SIZE + PIECE_BASE_POS_Y,
area%PUZZLE_LENGTH * PIECE_SIZE + PIECE_SIZE + PIECE_BASE_POS_X, area / PUZZLE_LENGTH * PIECE_SIZE + PIECE_SIZE + PIECE_BASE_POS_Y, color, false);
}
void ButtonInit() {
for (int i = 0; i < BTN_NUM;i ++) {
btn[i].pos.x =BTN_BASE_POS_X ;
btn[i].pos.y = BTN_BASE_POS_Y+(i*(BTN_HEIGHT+10));
btn[i].pos.w = btn[i].pos.x+BTN_WIDTH;
btn[i].pos.h= btn[i].pos.y+BTN_HEIGHT;
btn[i].name = btn_name[i];
btn[i].push_state = 0;
}
}
void ButtonUpdate() {
for (int i = 0; i < BTN_NUM; i++) {
if (MouseState == 1 && Point_Box_Collision(MousePosX, MousePosY, btn[i].pos))
btn[i].push_state++;
else
btn[i].push_state = 0;
}
}
動かせるピースをランダムに選んで混ぜていくという方法を使えば絶対解けるだろうと思ったのですが、
私はパズルが得意じゃないので、まったく解けず、クリア不可かどうかがわかりません(笑)
しかもシャッフル具合にたいへんムラがあります(;^ω^)
- スクリーンショット (60).png (7.74 KiB) 閲覧数: 301 回