たのしいプログラミング Pythonではじめよう!の第II部 Bounce!ゲーム(第13章、第14章)を変更しましたが、実行した際にpaddleに当たった時のボールの挙動がおかしいという現象が起きています。

バーではなく、ボールがバーに当たった時に上に移動せずに、斜め下に移動してしまうので、ボールがpaddleに反射して上に動くようにしたいと考えていますが、意図したとおりに動作しません。

from tkinter import *
import random
import time
from sys import exit
#必要なモジュールをインポート


tk = Tk()
tk.title('Game')#ウインドウのタイトル
tk.resizable(0, 0)#ウインドウのサイズ変更を不可能に
tk.wm_attributes('-topmost', 1)#ウインドウを一番上に表示
canvas = Canvas(tk, width=1000, height=800, bd=0, highlightthickness=0)#キャンバスを配置

canvas.pack()#キャンバスの表示
#my_image = PhotoImage(file='bg_yozora_night_sky.gif')
canvas.create_image(0, 0, anchor=NW)#image=my_image
tk.update()#アニメーションのためにtkinterを初期化


count = 0
global colors
colors=['red','blue','black','yellow','green','purple','magenta']
random.shuffle(colors)
color=colors[0]
color2=colors[2]
color3=colors[3]
color4=colors[4]

lost = False
scores = canvas.create_text(800, 10, text="Score: " + str(count), fill = "red",font=('Blackoak Std',10))

###ボール###
class Ball:
#クラスをボールに設定
    def __init__(self, canvas, paddle, board, board2, color):
        #canvas,color,paddle,score引数を受け取る__init__関数を作成
        self.canvas = canvas
        self.paddle = paddle
        self.board = board
        self.board2 = board2
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        #create_oval関数を呼び出し、引数[左上角の座標(10,10)、右下角の座標(25,25)、円の色}]をセット
        self.canvas.move(self.id, 470, 200)
        #円の識別番号(オブジェクトの変数id)を用いてキャンバスのほぼ中央(235,100)に円を移動
        starts = [-3, -2, -1, 1, 2, 3]#数字のリストをセットしたstarts関数をセット
        random.shuffle(starts)#starts関数の値の順序をシャッフル
        self.x = starts[0]#リストの先頭をxにセット
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        #キャンバスのwinfo_height関数が返す値をオブジェクトの変数canvas_heightにセット
        self.canvas_width = self.canvas.winfo_width()
        #キャンバスのwinfo_width関数が返す値をオブジェクトの関数canvas_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
                global count
                count +=1
                score()

        if pos[3] <= self.canvas_height:
            self.canvas.after(5, self.draw)
        else:
            self.canvas.move(self.id, 245, 200) #added this line
            game_over()
            global lost
            lost = True

    def hit_bottom(self, pos):
        paddle2_pos = self.canvas.coords(self.paddle2.id)
        if pos[2] >= paddle2_pos[0] and pos[0] <= paddle2_pos[2]:
            if pos[1] >= paddle2_pos[1] and pos[1] <= paddle2_pos[3]:
                return True
            return False

    def hit_board(self, pos):#障害物の判定
        board_pos = self.canvas.coords(self.board.id)
        if pos[2]>= board_pos[0] and pos[0] <= board_pos[2]:
            if pos[3] >= board_pos[1] and pos[3] <= board_pos[3]:
                return True
        return False

    def hit_board2(self, pos):
        board2_pos = self.canvas.coords(self.board2.id)
        if pos[2]>= board2_pos[0] and pos[0] <= board2_pos[2]:
            if pos[3] >= board2_pos[1] and pos[3] <= board2_pos[3]:
                return True
        return False

    def hit_board_bottom(self, pos):
        board_pos = self.canvas.coords(self.board.id)
        if pos[2]>= board_pos[0] and pos[0] <= board_pos[2]:
            if pos[1] <= board_pos[3] and pos[1] >= board_pos[1]:
                return True
        return False

    def hit_board2_bottom(self, pos):#board2の下側の当たり判定
        board2_pos = self.canvas.coords(self.board2.id)
        if pos[2]>= board2_pos[0] and pos[0] <= board2_pos[2]:
            if pos[1] <= board2_pos[3] and pos[1] >= board2_pos[1]:
                return True
        return False

    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        pos = self.canvas.coords(self.id)
        speed=[1,2,3,4,5]
        speed2=[-1,-2,-3,-4,-5]
        random.shuffle(speed)
        random.shuffle(speed2)
        colors=['red','blue','black','yellow','green','purple','magenta']
        random.shuffle(colors)



        if pos[1] <= 0:
            self.y = speed[0]
            canvas.itemconfig(self.id,fill=colors[0])
        if self.hit_board(pos)==True:
            self.y=-6
        if self.hit_board_bottom(pos)==True:
            self.y=6
        if self.hit_board2(pos)==True:
            self.y=-6
        if self.hit_board2_bottom(pos)==True:
            self.y=6

        if self.hit_paddle(pos) == True:
            self.y = -6

##            global count
##            count +=1
##            score()
##
##            if count == 0:
##                canvas.create_text(250, 200, text='YOU WIN!')
##                tk.update_idletasks()
##                tk.update()
##                while 1:
##                    if ball.hit_bottom ==True:
##                        ball.draw()
##                        paddle.draw()
##                        paddle2.draw()
##                        paddle3.draw()


        if pos[3] >= self.canvas_height:
            self.hit_bottom = True
            canvas.itemconfig(self.id,fill=colors[0])
        if pos[0] <= 0:
            self.x = speed[1]
            canvas.itemconfig(self.id,fill=colors[0])
        if pos[2] >= self.canvas_width:
            self.x = speed2[1]
            canvas.itemconfig(self.id,fill=colors[0])
            zahyou=self.canvas.coords(self.id)##←壁に当たったらワープ←座標取り出し
            a=[-500,-450,-400,-350]##←壁に当たったらワープ
            random.shuffle(a)##←壁に当たったらワープ
            self.canvas.move(self.id,a[0],-(zahyou[1]))##←壁に当

###障害物1###
class Board:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(150, -200, 250, -210, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.started = False

    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
###障害物2###
class Board2:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(-100, -150, 0, -160, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()

    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

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 150, 10, fill=color)
        self.canvas.move(self.id, 400, 700)
        self.x = 0
        self.y = 0

        self.canvas_width = self.canvas.winfo_width()
        self.started = False
        self.canvas.bind_all('<Up>', self.turn_up)
        self.canvas.bind_all('<Down>', self.turn_down)
        self.canvas.bind_all('<Left>', self.turn_left)
        self.canvas.bind_all('<Right>', self.turn_right)
        self.canvas.bind_all('<s>', self.start_game)#クリックしたときにスタート



    def draw(self):#ラケットの描画
        self.canvas.move(self.id, self.x, self.y)
        pos =self.canvas.coords(self.id)
        if pos[0] <= 0:##←パドルが壁を貫通しないようにする
            self.x =0
        elif pos[2] >= self.canvas_width:##←パドルが壁を貫通しないようにする
            self.x = 0
        #こうすべきかな。
            pos =self.canvas.coords(self.id)
        elif pos[1] <= 0:##←パドルが壁を貫通しないようにする
            self.y =0
        elif pos[3]>= 800:##←パドルが壁を貫通しないようにする
            self.y = 0
        global lost
        if lost == False:
            self.canvas.after(10, self.draw)

    def turn_up(self, evt):
        self.canvas.move(self.id, self.x, self.y)##←動く範囲指定
        pos = self.canvas.coords(self.id)##←動く範囲指定
        if pos[1] >0:##←動く範囲指定
            self.y = -6
        elif pos[1] <=0:##←動く範囲指定
            self.y =0##←動く範囲指定

    def turn_down(self, evt):
        self.canvas.move(self.id, self.x, self.y)##←動く範囲指定
        pos = self.canvas.coords(self.id)##←動く範囲指定
        if pos[3]<800:##←動く範囲指定
            self.y = 6
        elif pos[3]>=800:##←動く範囲指定
            self.y=0##←動く範囲指定

    def turn_left(self, evt):
        self.canvas.move(self.id, self.x, self.y)##←動く範囲指定
        pos = self.canvas.coords(self.id)##←動く範囲指定
        if pos[0]>0:
            self.x = -6
        elif pos[0]<=0:##←動く範囲指定
            self.x=0##←動く範囲指定

    def turn_right(self, evt):
        self.canvas.move(self.id, self.x, self.y)##←動く範囲指定
        pos = self.canvas.coords(self.id)##←動く範囲指定
        if pos[2]< self.canvas_width:##←動く範囲指定
            self.x = 6
        elif pos[2]>= self.canvas_width:##←動く範囲指定
            self.x=0##←動く範囲指定

    def start_game(self, evt):#スタートする関数
        self.started = True
        self.onemore(evt)

    def end(self, evt):
        tk.destroy()

    def onemore(self, evt):
        while True:#常にループ実行
            if ball.hit_bottom == False and paddle.started == True:#ゲームを続ける条件
                ball.draw()#ballオブジェクトのdraw関数の呼び出し
                paddle.draw()#paddleオブジェクトのdraw関数の呼び出し
                board.draw()
                board2.draw()

            if ball.hit_bottom == True:
                time.sleep(1)
                canvas.itemconfig(game_over, state = 'normal')
                canvas.itemconfig(retry1, state = 'normal')#テキストを表示する条件
                canvas.itemconfig(retry2, state = 'normal')
                self.canvas.bind_all('<n>', self.end)
                self.canvas.bind_all('<y>', self.restart)



            tk.update_idletasks()
            tk.update()
            time.sleep(0.01)
    def restart(self,evt):
        ball.hit_bottom == False
        paddle.started == True

def game_over():
    game_over =canvas.create_text(150, 150, text ='GAME OVER!', font =('Courier', 30), fill='yellow', state ='hidden')
    #ゲームオーバーのテキスト表示,hiddenで隠しておく
    retry1 = canvas.create_text(200, 250, text ='もう一度、ゲームを行いますか', font =('Courier', 20),fill='yellow', state ='hidden')
    retry2 = canvas.create_text(300, 300, text ='(Yes/No)', font =('Courier', 20),fill='yellow', state ='hidden')


def start_game_menu():
    global lost, count, ball 
    if lost == True: 
        ball = Ball(canvas, paddle, paddle2,paddle3,"red")


    lost = False 
    board.draw()
    board2.draw()
    paddle.draw()
    ball.draw()
    count = 0

    score()
    canvas.itemconfig(game, text=" ")
    time.sleep(1)

def score():
    canvas.itemconfig(scores, text="Score:"+ str(count))

def start_game(event):
    global lost, count, ball ,paddle
    if lost == True: 
        ball = Ball(canvas, paddle, board2, board,color2)


    canvas.move(paddle, 400, 600)
    lost = False 
    board.draw()
    board2.draw()
    paddle.draw()
    ball.draw()
    count = 0

    score()
    canvas.itemconfig(game, text=" ")

    time.sleep(1)

def out():
    tk.destroy()
def out_keypress(event):
    tk.destroy()

####
menu=Menu(tk)
tk.config(menu=menu)
filemenu=Menu(menu)
menu.add_cascade(label="Menu", menu=filemenu)
filemenu.add_cascade(label="Exit",command=out)
filemenu.add_cascade(label="Restart",command=start_game_menu)


###各種設定###

paddle = Paddle(canvas, color2)
board = Board(canvas, color3)
board2 = Board2(canvas, color4)
#ラケットの色を青色に設定
ball = Ball(canvas, paddle, board, board2, color)
#ボールの色を赤に設定

game = canvas.create_text(500, 300, text=" ", fill="red", font=("Arial", 20))

canvas.bind_all("<s>", start_game)
canvas.bind_all("<y>", start_game)
canvas.bind_all("<n>", out_keypress)




tk.mainloop()

原著のページに元となったソースコードのダウンロードリンクがあります