[c言語 Handy Graphic] クリック処理について
Posted: 2018年11月19日(月) 12:00
はじめまして、c言語およびプログラミングを学び始めて1年近くになるの者です。
現在、
[時限爆弾]
・赤、緑、青色の3つの色球がそれぞれ違う速度で決まった範囲内で移動しており、それらはあらかじめ「起爆」、「解除」、「増殖」の役割を持っている。色球は壁に跳ね返るごとに、赤→緑→青→赤の順に変色していく。3つの役割は球自体にではなく、各色にランダムに割り当てられる。壁に跳ね返ると球のもつ役割も変更される。これらをすべてクリックによって選択していき「解除」の色球を選択するとクリアとなる。「起爆」の色球を選択すると、ゲームオーバーとなり、時間以内に「解除」を選択できなくても同じである。「増殖」を選沢すると、色球が1つ増加され、各役割が再度割り当てられる。また色球が10個((7個増加))になったらゲームオーバーとなる(後に変更する予定)。
のような内容の簡単なゲーム制作をしているのですが、クリック処理が思いのほか上手くいかず
1.プログラム終了時にエラーが出る。または途中で落ちる。
2.色球がおかしな場所に出現する。
といった問題が起きています。
自分だけでは、いくら考えてもどのように手をつけて良いか分からないので、本掲示板でご相談を願った次第です。
差し支えなければご教授の方お願いします。
環境は、MacOS10.14.1 です。
現在、
[時限爆弾]
・赤、緑、青色の3つの色球がそれぞれ違う速度で決まった範囲内で移動しており、それらはあらかじめ「起爆」、「解除」、「増殖」の役割を持っている。色球は壁に跳ね返るごとに、赤→緑→青→赤の順に変色していく。3つの役割は球自体にではなく、各色にランダムに割り当てられる。壁に跳ね返ると球のもつ役割も変更される。これらをすべてクリックによって選択していき「解除」の色球を選択するとクリアとなる。「起爆」の色球を選択すると、ゲームオーバーとなり、時間以内に「解除」を選択できなくても同じである。「増殖」を選沢すると、色球が1つ増加され、各役割が再度割り当てられる。また色球が10個((7個増加))になったらゲームオーバーとなる(後に変更する予定)。
のような内容の簡単なゲーム制作をしているのですが、クリック処理が思いのほか上手くいかず
1.プログラム終了時にエラーが出る。または途中で落ちる。
2.色球がおかしな場所に出現する。
といった問題が起きています。
自分だけでは、いくら考えてもどのように手をつけて良いか分からないので、本掲示板でご相談を願った次第です。
差し支えなければご教授の方お願いします。
環境は、MacOS10.14.1 です。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <handy.h>
/* ウィンドウ画面サイズ */
#define WindowX 800
#define WindowY 600
/* 色球を動かす範囲(プレイエリア) */
#define AreaX 400
#define AreaY 200
/* 爆弾サイズ */
#define BombX 600.0
#define BombY 400.0
/* 爆弾とプレイエリアの幅 */
#define WideX 200
#define WideY 50
#define Time rand()%45+10 //制限時間
#define Memory 10 //配色の記憶
#define Radius 20 // 色球の半径
#define Speed rand()%20+1 //色球の移動速度
#define Burn 0 //爆発
#define Stop 1 //解除
#define More 2 //増殖
/* 爆発シーンの描画関数 */
void Explosion(){
int gid = HgImageLoad("bakuhatsu.png");
HgImagePut(WindowX/2, WindowY/2, gid, 1.0, 0);
printf("Game Over!!\n");
}
/* クリア画面の描画関数 */
void Fanfare(){
int gid = HgImageLoad("fanfare.png");
HgImagePut(WindowX/2, WindowY/2, gid, 1.0, 0);
printf("Game Clear!!\n");
}
/* 爆弾の描画関数 */
void DrawBomb(){
HgSetFillColor(HG_GRAY);
HgBoxFill(100, 0, BombX, BombY, 1);
}
/* 爆発・解除・増殖判定の設定*/
void Shuffle(int judge[], int cir_color[]){
int i;
int ballcount = 3;
for(i = 0; i < 3; i++){
int j = rand()%3;
int t = judge[i];
judge[i] = judge[j];
judge[j] = t;
}
/* 爆発・解除・増殖判定を各色に割り当てる */
for(i = 0; i < ballcount; i++){
cir_color[i] = judge[i];
}
}
/* メイン処理 */
int main(){
srand(time(NULL));
double tl = Time; //制限時間
/* 色球の初期位置・移動速度 */
int x[3] = {220, 220, 220}, vx[3];
int y[3] = {220, 220, 220}, vy[3];
/* 色球の配色、配色を覚える配列(「増殖」判定があるので、10個分用意) */
int color[3], cir_color[Memory] = {0, 0, 0};
int judge[3] = {Burn, Stop, More}; //役割を配列に入れる
int i, ballcount = 3; // カウンタ変数、球の個数
HgOpen(WindowX, WindowY);
printf("Game Start!!\n");
color[0] = HG_RED; //赤着色
color[1] = HG_GREEN; //青着色
color[2] = HG_BLUE; //緑着色
for(i = 0; i < 3; i++){
vx[i] = Speed;// x 方向の移動速度
vy[i] = Speed; // y 方向の移動速度
}
/* 爆発・解除・増殖判定を設定する */
Shuffle(judge, cir_color);
HgSetEventMask(HG_MOUSE_DOWN);
for(;;){
HgSleep(0.1); //描画表示時間
HgClear(); //描画削除
DrawBomb(); //爆弾描画
/* 制限時間表示 */
HgSetColor(HG_BLACK);
HgText(500, 500, "%.1f", tl);
tl -= 0.1; //0.1秒毎に時間を減らす
/* 制限時間終了後、爆発の演出をさせる */
if(tl <= 0.0){
HgClear(); //前の描画(爆弾)を削除
Explosion(); //爆発シーン
break;
}
/* プレイエリア描画 */
HgSetFillColor(HG_WHITE);
HgBoxFill(WideX, WideY, AreaX, AreaY, 1);
for(i = 0; i < ballcount; i++){
HgSetFillColor(color[cir_color[i]]);
HgCircleFill(x[i], y[i], Radius, 1);
/* 色球を選択した場合の処理 */
hgevent *event = HgEventNonBlocking();
if(event != NULL){
x[i] = event->type;
y[i] = event->type;
/*「爆発」のとき*/
if(judge[i] == Burn){
printf("Game Over!!\n");
HgClear(); // 描画削除
HgClose(); // プログラム終了
return 0;
/*「解除」のとき*/
}else if(judge[i] == Stop){
printf("Game Clear!!\n");
HgClear(); // 描画削除
HgClose(); // プログラム終了
return 0;
/*「増殖」のとき*/
}else{
printf("I Increaced Balls\n");
printf("And Shuffle Judge Now...\n");
ballcount++; //球の個数を増やす
Shuffle(judge, cir_color); //役割を割り当てる
HgSetFillColor(color[cir_color[i]]);
HgCircleFill(x[i], y[i], Radius, 1);
}
}
/* 色球が10以上になったら、ゲームオーバーとして終了 */
if(ballcount == Memory){
printf("Game Over!!\n");
HgClear();
HgClose();
}
/* x, y 方向に移動させる */
x[i] += vx[i];
y[i] += vy[i];
/* 色球のバウンド処理 */
if(x[i] >= AreaX + WideX - Radius){
vx[i] = -vx[i];
}else if(x[i] < WideX + Radius){
vx[i] = -vx[i];
}
if(y[i] >= AreaY + WideY - Radius){
vy[i] = -vy[i];
}else if(y[i] < WideY + Radius){
vy[i] = -vy[i];
}
/* 壁に当たる毎に色を変えていく */
if(x[i] >= AreaX + WideX - Radius || x[i] < WideX + Radius
|| y[i] >= AreaY + WideY - Radius || y[i] < WideY + Radius)
{
cir_color[i]++;
/* 青の次を赤にする */
if(cir_color[i] == 3){
cir_color[i] = 0;
}
}
}
}
HgClose();
return 0;
}