파이썬 gui프로그래밍중 tkinter에 대한 질문입니다.
조회수 5712회
누구나 쉽게 배우는 파이썬 프로그래밍 이라는 책을 보며
아래의 이미지 같은 벽돌깨기 게임을 만드는 중입니다.
공이 움직이다 블록을 만나면 부딪히고 싶은데 공이 블록을 통과합니다.
벽돌깨기를 하려면 일단 부딪히는거라도 해야 할 텐데요 ㅋㅋㅋ
이 부분 도와주세요 아래 소스는 책의 소스중 바와 공의 충돌에 관한 부분입니다.
class Ball:
def __init__(self,canvas,paddle,score,color):
self.canvas = canvas
self.paddle = paddle
self.score = score
self.id = canvas.create_oval(10,10,25,25,fill = color)
self.canvas.move(self.id,245,100)
starts = [-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x = starts[0]
self.y = -3
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
self.x += self.paddle.x
self.score.hit()
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.y = 3
if pos[3] >= self.canvas_height:
self.hit_bottom = True
if self.hit_paddle(pos) == True:
self.y = -3
if pos[0] <= 0:
self.x = 3
if pos[2] >= self.canvas_width:
self.x = -3
이 부분이 책에 나와있는 공과 바가 부딪히는 부분입니다.
여기서부터는 제가 생각한대로 몇줄 추가해 보았습니다.
class Ball:
def __init__(self,canvas,paddle,score,block,color):
self.canvas = canvas
self.paddle = paddle
self.block = block
self.score = score
self.id = canvas.create_oval(10,10,25,25,fill = color)
self.canvas.move(self.id,245,100)
starts = [-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x = starts[0]
self.y = -3
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
self.hit_bottom = False
self.hit_block = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
self.x += self.paddle.x
self.score.hit()
return True
return False
def hit_block(self,pos):
block_pos = self.canvas.coords(self.block.id)
if pos[2] >= block_pos[0] and pos[0] <= block_pos[2]:
if pos[3] >= block_pos[1] and pos[3] <= block_pos[3]:
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id)
# pos2 = self.block.coords(self.id)
if pos[1] <= 0:
self.y = 3
if pos[3] >= self.canvas_height:
self.hit_bottom = True
if self.hit_paddle(pos) == True:
self.y = -3
if pos[0] <= 0:
self.x = 3
if pos[2] >= self.canvas_width:
self.x = -3
if self.hit_block(pos) == True:
self.x = -3
제가 몇줄 추가하면 이렇게 오류가 발생합니다. hit_block 부분에서 문제가 생기는거 같은데....
잘 모르겠지만 논리적으로?? 안맞는다는거죠?
다음은 책의 소스입니다.
from tkinter import *
import random
import time
class Ball:
def __init__(self,canvas,paddle,score,color):
self.canvas = canvas
self.paddle = paddle
self.score = score
self.id = canvas.create_oval(10,10,25,25,fill = color)
self.canvas.move(self.id,245,100)
starts = [-3,-2,-1,1,2,3]
random.shuffle(starts)
self.x = starts[0]
self.y = -3
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
self.hit_bottom = False
def hit_paddle(self,pos):
paddle_pos = self.canvas.coords(self.paddle.id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
self.x += self.paddle.x
self.score.hit()
return True
return False
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.y = 3
if pos[3] >= self.canvas_height:
self.hit_bottom = True
if self.hit_paddle(pos) == True:
self.y = -3
if pos[0] <= 0:
self.x = 3
if pos[2] >= self.canvas_width:
self.x = -3
class Paddle:
def __init__(self,canvas,color):
self.canvas = canvas
self.id = canvas.create_rectangle(0,0,100,10,fill=color)
self.canvas.move(self.id,200,300)
self.x = 0
self.canvas_width = self.canvas.winfo_width()
self.started = False
self.canvas.bind_all('<KeyPress-Left>',self.turn_left)
self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
self.canvas.bind_all('<Button-1>',self.start_game)
def draw(self):
self.canvas.move(self.id,self.x,0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0
elif pos[2] >= self.canvas_width:
self.x = 0
def turn_left(self,evt):
self.x = -2
def turn_right(self,evt):
self.x = 2
def start_game(self,evt):
self.started = True
class Score:
def __init__(self,canvas,color):
self.score = 0
self.canvas = canvas
self.id = canvas.create_text(450,10,text = self.score,\
fill = color)
def hit(self):
self.score +=1
self.canvas.itemconfig(self.id,text = self.score)
tk = Tk()
tk.title("Game") #게임 창에 제목 부여
tk.resizable(0,0)# 창 크기 고정
tk.wm_attributes("-topmost",1) #화면 제일 앞에 고정
canvas = Canvas(tk,width = 500,height=500,bd=0,highlightthickness=0) #캔버스 이쁘게
canvas.pack()
tk.update() #필수!! 애니메이션을 위해 자기초기화
score = Score(canvas,'green')
paddle = Paddle(canvas,'black')
ball = Ball(canvas,paddle,score,'red')
game_over_text = canvas.create_text(250,200,text='GAME OVER',\
state = 'hidden')
while 1: #메인 루프
if ball.hit_bottom == False and paddle.started == True:
ball.draw()
paddle.draw()
if ball.hit_bottom == True: #공이 바닥에 닿으면 0.1초 쉬고 gameover 출력->숨김모드->보이는 모드로
time.sleep(0.1)
canvas.itemconfig(game_over_text,state='normal')
# time.sleep(2)
# exit()
tk.update_idletasks()
tk.update()
time.sleep(0.0000001)
글이 너무 길어서 읽는데 고생하셨습니다. 다 읽어주셔서 감사해요
잘 몰라도요 조금이라도 도움이 되지 않을까? 싶으면 다 댓글 달아주세요 감사합니다.
1 답변
-
클래스에
hit_block
이라는 이름의 멤버를 중복해서 쓰셨네요.__init__
에 Boolean typehit_block
- 멤버함수
def hit_block
둘 중 하나의 이름을 바꿔주세요. 코드를 보니 2번, 함수를 쓰고 싶어서 hit_block(...)을 쓰셨는데 python interpreter는 hit_block을 메소드가 아니라 1번 variable로 받아들여 에러가 발생합니다.
예를 들어
def __init__(self,canvas,paddle,score,block,color): self.canvas = canvas self.paddle = paddle self.block = block self.score = score self.id = canvas.create_oval(10,10,25,25,fill = color) self.canvas.move(self.id,245,100) starts = [-3,-2,-1,1,2,3] random.shuffle(starts) self.x = starts[0] self.y = -3 self.canvas_height = self.canvas.winfo_height() self.canvas_width = self.canvas.winfo_width() self.hit_bottom = False #self.hit_block = False # 주석처리
이렇게 init에 선언된 hit_block을 제거하시거나, hit_block의 이름을 다른 걸로 바꾸세요.
-
(•́ ✖ •̀)
알 수 없는 사용자
댓글 입력