実現したいこと
ボールと衝突したブロックが消えるようにしたい
前提
初心者なので、必要なものと不必要なものがハッキリしないため、載せるコードが長くなってしまいます。ご了承ください。
Pygameにて、基本的なブロック崩しを作成しています。
発生している問題・エラーメッセージ
ゲーム開始直後、ボールが一番下の行のブロックのどれかに当たります。当たったブロックと同じy座標にある、x座標が一番小さい(一番奥のブロック)が消えてしまいます。当然、ボールに当たったブロックが消えるようにしたい
該当のソースコード
Python
1import pygame 2import setting as s 3import random 4from block import Block 5 6class Ball(pygame.sprite.Sprite): 7 def __init__(self, groups, x, y, racket_group, block_group): 8 super().__init__(groups) 9 self.screen = pygame.display.get_surface() 10 11 # グループ 12 self.racket_group = racket_group 13 self.block_group = block_group 14 15 # ラケット 16 self.image = pygame.Surface((10, 10)) 17 self.image.fill(s.RED) 18 self.rect = self.image.get_rect(center = (x, y)) 19 20 # 移動 21 move_list = [-1, 1] 22 self.direction = pygame.math.Vector2((random.choice(move_list), -1)) 23 self.speed = 4 24 25 def move(self): 26 if self.rect.right >= s.screen_width or self.rect.left <= 0: 27 self.direction.x *= -1 28 self.rect.x += self.speed * self.direction.x 29 if self.rect.top <= 0: 30 self.direction.y *= -1 31 self.rect.y += self.speed * self.direction.y 32 33 def check_off_screen(self): 34 if self.rect.top >= s.screen_height: 35 self.kill() 36 37 def reflection_racket(self): # ラケット反射 38 for racket in self.racket_group: 39 if self.rect.bottom >= racket.rect.top: 40 if self.rect.top <= racket.rect.bottom: 41 if self.rect.right <= racket.rect.right and self.rect.left >= racket.rect.left: 42 self.direction.y *= -1 43 44 def reflection_block(self): # ブロック反射 45 for block in self.block_group: 46 if self.rect.right >= block.rect.left and self.rect.left <= block.rect.right: # ブロックのx範囲内にボール 47 if self.rect.top <= block.rect.bottom <= self.rect.bottom:# # ブロックの下側衝突 48 self.direction.y *= -1 49 if self.rect.top <= block.rect.top <= self.rect.bottom: # ブロックの上側衝突 50 self.direction.y *= -1 51 52 53 if self.rect.top <= block.rect.bottom and self.rect.bottom >= block.rect.top: # ブロックのy範囲内にボール 54 if self.rect.left <= block.rect.left <= self.rect.right: 55 self.direction.x *= -1 56 if self.rect.left <= block.rect.right <= self.rect.right: 57 self.direction.x *= -1 58 59 def getCoords(self): # 左上と右下の座標取得 60 return (self.rect.x, self.rect.y, self.rect.x + s.block_width - 5, self.rect.y + s.block_height - 5) 61 62 63 64 def getCollisionCoords(self, object): 65 # ボールとオブジェクトの座標取得 66 ball_x1, ball_y1, ball_x2, ball_y2 = self.getCoords() 67 object_x1, object_y1, object_x2, object_y2 = object.getCoords() 68 69 # 短形の座標取得 70 x1 = max(ball_x1, object_x1) 71 y1 = max(ball_y1, object_y1) 72 x2 = min(ball_x2, object_x2) 73 y2 = min(ball_y2, object_y2) 74 75 if x1 < x2 and y1 < y2: 76 return (x1, y1, x2, y2) 77 else: 78 return None 79 80 def collision(self): 81 max_area = 0 82 x = None 83 y = None 84 for block in self.block_group: 85 collision_rect = self.getCollisionCoords(block) 86 if collision_rect != None: # 当たった場合 87 x1, y1, x2, y2 = collision_rect 88 area = (x2 - x1) * (y2 - y1) 89 if max_area < area: 90 max_area = area 91 x = x1 // s.block_width 92 y = y1 // s.block_height 93 return x, y 94 95 96 97 def update(self): 98 self.move() 99 self.check_off_screen() 100 self.reflection_racket() 101 self.reflection_block() 102 self.collision() 103 104class Block(pygame.sprite.Sprite): 105 def __init__(self, groups, position, ball_group): 106 super().__init__(groups) 107 self.screen = pygame.display.get_surface() 108 109 # グループ 110 self.ball_group = ball_group 111 112 # ブロック 113 self.position = position 114 self.image = pygame.Surface((s.block_width - 5, s.block_height - 5)) 115 self.image.fill(s.GREEN) 116 self.rect = self.image.get_rect(topleft = (self.position)) 117 118 # 体力 119 self.health = 1 120 self.alive = True 121 122 def getCoords(self): # 左上と右下の座標取得 123 return (self.rect.x, self.rect.y, self.rect.x + s.block_width - 5, self.rect.y + s.block_height - 5) 124 125 def update(self): 126 self.getCoords() 127 128class Game: 129 def __init__(self): 130 self.screen = pygame.display.get_surface() 131 132 # グループの作成 133 self.create_group() 134 135 # ラケット 136 racket = Racket(self.racket_group, s.screen_width / 2, s.screen_height - 10) 137 138 # ボール 139 self.ball = Ball(self.ball_group, s.screen_width / 2, s.screen_height / 2, self.racket_group, self.block_group) 140 141 142 143 def create_group(self): 144 self.racket_group = pygame.sprite.GroupSingle() 145 self.ball_group = pygame.sprite.Group() 146 self.block_group = pygame.sprite.Group() 147 148 149 def set_up(self): # ブロック生成 150 self.field = [] 151 for row in range(s.row_num): 152 block_list = [] 153 for col in range(s.col_num): 154 self.block = Block(self.block_group, (col * s.block_width + 2.5, row * s.block_height), self.ball_group) 155 block_list.append(self.block) 156 self.field.append(block_list) 157 158 159 def delete(self): # ブロック削除 160 collided_block = None 161 x, y = self.ball.collision() 162 if x != None and y != None: 163 collided_block = self.field[x][y] 164 165 if collided_block != None: 166 collided_block.kill() 167 168 169 170 171 172 def run(self): 173 self.racket_group.draw(self.screen) 174 self.racket_group.update() 175 self.ball_group.draw(self.screen) 176 self.ball_group.update() 177 self.block_group.draw(self.screen) 178 self.block_group.update() 179 self.delete()
試したこと
ボールと衝突したブロックの座標を取得しようとGameクラス内のdelete()においてprint(x, y)を実行したところ、表示された座標の値自体は想定通りのものが出力された
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/09/21 00:29