ブロック崩しの当たり判定

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
もやもや

ブロック崩しの当たり判定

#1

投稿記事 by もやもや » 14年前

ブロック崩しをつくっているのですが、以下のようにかいたところ、ボールがブロックのところで跳ね返ってきません。
どのようにかけば、ボールがブロックのところで跳ね返るのでしょうか。わかるかた、教えてください。お願いします。

codeタグを追加されていただきました。 by softya(ソフト屋)

コード:

#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


#define WALL_R (COLS - 15)  /* 右の壁 */
#define WALL_L 0           /* 左の壁 */
#define TOP 0              /* 上の壁 */
#define BELOW (LINES - 1)  /* 下の壁 */



/*ブロック*/
struct s_block{
  int X;                     /* 左端のX座標 */
  int Y;                     /* Y座標 */
  struct s_block *next;/* 次のブロックへのポインタ */
};

void go();

/*ブロック作成*/
void makeblock(struct s_block **block_ptr, int x, int y){
  struct s_block *ptr;
  struct s_block *p;

  if((ptr =(struct s_block *)malloc(sizeof(struct s_block)))!= NULL){
    if(*block_ptr == NULL){
      *block_ptr = ptr;
    }else{
      p = *block_ptr;
      while(p->next != NULL){
	p = p->next;
      }
      p->next = ptr;
    }
    ptr->X = x;     /*各値に代入*/
    ptr->Y = y;
    ptr->next = NULL;
  }
}

/*ブロック表示*/
void printblock(struct s_block *block){
  while(block != NULL){
    mvaddstr(block->Y, block->X, "#####");
    block = block->next;
  }
}


/* ボールによるブロックの破壊 */
int break_byball(struct s_block **block_ptr){
  struct s_block *ptr;/* 破壊するブロックのポインタ */
  struct s_block *pre;/* 破壊するブロックの前のブロックのポインタ */
  int ref = 0;/* 破壊したかどうかの判定 */

  int blocX, blocY;
  int blocDX, blocDY;

  blocX = COLS/2;
  blocY = LINES/2;
  blocDX = 1;
  blocDY = -1;


  ptr = *block_ptr;

  /* ボールを跳ね返した後ブロックを破壊する */
  while(ptr != NULL){
    if(blocY == ptr->Y){
      if(blocX >= ptr->X + 1 && blocX <= ptr->X + 3){
        blocDY *= -1;
        blocY += blocDY;
        ref = 1;
        break;
      }
      if(blocX == ptr->X){
        if(blocDX == 1){
          blocDX *= -1;
          blocDY *= -1;
          blocX += blocDX;
          blocY += blocDY;
          ref = 1;
          break;
        }else{
          blocDY *= -1;
          blocY += blocDY;
          ref = 1;
          break;
        }
      }
      if(blocX == ptr->X + 4){
        if(blocDX == 1){
          blocDY *= -1;
          blocY += blocDY;
          ref = 1;
          break;
	}else{
          blocDX *= -1;
          blocDY *= -1;
          blocX += blocDX;
          blocY += blocDY;
          ref = 1;
          break;
	}
      }
    }
    ptr = ptr->next;
  }
  if(ref == 1){
    if(ptr == *block_ptr){/* 先頭を破壊する場合 */
      *block_ptr = ptr->next;/* 2番目を新しい先頭にする */
    }else{/* 先頭以外を破壊する場合 */
      pre = *block_ptr;
      while(pre->next != ptr){
        pre = pre->next;
      }
      pre->next = ptr ->next;  /* 前のブロックと後のブロックをnextでつなげる */
    }
    free(ptr);                 /* 削除するブロックの記憶域を解放 */
  }
  return ref;
}




/*メイン関数*/
int main(int argc, char **argv){

  initscr();
  noecho();
  cbreak();
  keypad(stdscr,TRUE);
  go();
  endwin();
  return 0;
}

void go(){
  struct s_block *block = NULL;

  int locX, locY;
  int blocX, blocY;
  int blocDX, blocDY;
  int ch;
  int delay=0;
  int waitCount = 9000;
  int i,j;
  int count=0;
  int x, y;

  locY = LINES - 5;
  locX = COLS/2;
  blocX = COLS/2;
  blocY = LINES/2;
  blocDX = 1;
  blocDY = -1;
  timeout(0);

  for(y = 3; y <= 7; y += 2){/* ブロックを作成 */
    for(x = ((WALL_R - 8)% 9) / 2 + 2;
        x <= WALL_R - 5;
	x += 9){
      makeblock(&block ,x , y);
    }
  }


  while((ch=getch())!='Q'){

    printblock(block);


    mvaddstr(locY,locX,"     ");
    mvaddch(blocY,blocX,' ');

    if(delay%waitCount==0){
      blocX += blocDX;
      blocY += blocDY;
      if(blocX<=WALL_L+1){
        blocX =WALL_L+1;
        blocDX = 1;
      }
      if(blocX>=WALL_R-1){
	blocX =WALL_R-2;
        blocDX = -1;
      }
      if(blocY<1){
        blocY =1;
        blocDY = 1;
      }
      if((blocY>=locY)&&(blocX>=locX)&&(blocX<=locX+4)){
        blocY = locY-1;
        blocDY = -1;
      }
      
    }
    break_byball(&block);

    delay++;
    switch(ch){
    case KEY_LEFT:
      if(locX<=2) locX = 2;
      locX -=1;
      break;
    case KEY_RIGHT:
      if(locX >= WALL_R - 6) locX = WALL_R - 6;
      locX +=1;
      break;
    case KEY_UP:
      locY-=1;
      if(locY<=3*LINES/4) locY=3*LINES/4;
      waitCount-=100;
      break;
    case KEY_DOWN:
      locY+=1;
      if(locY>=LINES) locY=LINES-1;
      waitCount+=100;
      break;
    default:
      break;
    }
    if(locX<0) locX=0;
    if(locX>=COLS) locX = COLS-1;
    mvaddstr(locY,locX,"=====");
    mvaddch(blocY,blocX,'@');
  }
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ブロック崩しの当たり判定

#2

投稿記事 by softya(ソフト屋) » 14年前

マルチポストになってしまっていますので、フォーラムルールに則って相互リンクをお願いします。
http://dixq.net/board/board.html
なお、無闇に質問の削除をすることは失礼にあたりますのでお避け下さい。

「C言語に関する質問です。 ブロック崩しをつくっているのですが、以下のように関数... - Yahoo!知恵袋」
http://detail.chiebukuro.yahoo.co.jp/qa ... 1268261042
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る