函数式编程中的 Python 弹跳球游戏
这是一款常见的街机游戏,目标是尽可能多地击中所有目标以获得最高分。每次球击中“石头”,您将获得 1 分,如果击中 2 个“石头”,您将获得 2 分。如果玩家未能接住横杆或“杆”上的球,则游戏结束。
我的任务就是把这个用面向对象编程编写的游戏变成函数式编程。
import time
class Ball:
def __init__(self, cvs, pole, stones, scre):
self.stones = stones
self.cvs = cvs
self.pole = pole
self.scre = scre
self.bottom_hit = False
self.hit = 0
self.id = canvas.create_oval(10, 10, 25, 25, fill="cadetblue", width=1)
self.cvs.move(self.id, 230, 461)
self.a = 3
self.b = -3
self.cvs.move(self.id, self.a, self.b)
self.cvs_height = canvas.winfo_height()
self.cvs_width = canvas.winfo_width()
def stone_strike(self, push):
for stone_line in self.stones:
for stone in stone_line:
stone_push = self.cvs.coords(stone.id)
try:
if push[2] >= stone_push[0] and push[0] <= stone_push[2]:
if push[3] >= stone_push[1] and push[1] <= stone_push[3]:
canvas.bell()
self.hit += 1
self.scre.configure(text="Score: " + str(self.hit))
self.cvs.delete(stone.id)
return True
except:
continue
return False
def pole_strike(self, push):
pole_push = self.cvs.coords(self.pole.id)
if push[2] >= pole_push[0] and push[0] <= pole_push[2]:
if push[3] >= pole_push[1] and push[1] <= pole_push[3]:
return True
return False
def draw(self):
self.cvs.move(self.id, self.a, self.b)
push = self.cvs.coords(self.id)
if self.stone_strike(push):
self.b = 3
if push[1] <= 0:
self.b = 3
if push[3] >= self.cvs_height:
self.bottom_hit = True
if push[0] <= 0:
self.a = 3
if push[2] >= self.cvs_width:
self.a = -3
if self.pole_strike(push):
self.b = -3
class Pole:
def __init__(self, cvs):
self.cvs = cvs
self.id = canvas.create_rectangle(0, 0, 100, 10, fill="darkgoldenrod")
self.cvs.move(self.id, 200, 485)
self.a = 0
self.cvs_width = canvas.winfo_width()
self.cvs.bind_all("<Left>", self.turn_left)
self.cvs.bind_all("<Right>", self.turn_right)
def draw(self):
push = self.cvs.coords(self.id)
if push[0] + self.a <= 0:
self.a = 0
if push[2] + self.a >= self.cvs_width:
self.a = 0
self.cvs.move(self.id, self.a, 0)
def turn_left(self, event):
self.a = -5
def turn_right(self, event):
self.a = 5
class Stone:
def __init__(self):
self.id = canvas.create_rectangle(5, 5, 25, 25, fill="firebrick")
def start_game(event):
score.configure(text="Score: 00")
canvas.delete("all")
pole = Pole(canvas)
stones = []
for i in range(0, 5):
b = []
for j in range(0, 19):
tmp = Stone()
b.append(tmp)
stones.append(b)
for i in range(0, 5):
for j in range(0, 19):
canvas.move(stones[i][j].id, 25 * j, 25 * i)
ball = Ball(canvas, pole, stones, score)
root.update()
time.sleep(1)
while 1:
if not ball.bottom_hit:
ball.draw()
pole.draw()
root.update()
time.sleep(0.01)
if ball.hit == 95:
canvas.create_text(250, 250, text="YOU WON!!", fill="darkolivegreen", font="Calibri 24")
break
else:
canvas.create_text(250, 250, text="GAME OVER!!", fill="darkolivegreen", font="Calibri 24")
break
root = Tk()
root.title("Bounce Ball Game")
root.geometry("500x570")
root.resizable(0, 0)
canvas = Canvas(root, width=500, height=500, bd=0, bg="black")
canvas.pack(padx=10, pady=10)
canvas.create_text(250, 250, text="Press Enter to start Game!!", fill="darkolivegreen", font="Calibri 18")
score = Label(height=50, width=80, text="Score: 00", font="Calibri 14 italic")
score.pack(side="left")
root.bind_all("<Return>", start_game)
root.mainloop()
这是我写的代码。肯定存在逻辑错误,因为它不起作用。有什么想法吗?
import time
def startgame(event):
score.configure(text="score:00")
canvas.delete("all")
canvas_width = canvas.winfo_width()
canvas_height = canvas.winfo_height()
pole = canvas.create_rectangle(0, 0, 100, 10, fill="darkgoldenrod")
canvas.move(pole, 200, 425)
pa = 0
def turn_left(event):
pa = -5
def turn_right(event):
pa = 5
def stone_strike(push):
for stone_line in stones:
for stone in stone_line:
stone_push = canvas.coords(stone)
try:
if push[2] >= stone_push[0] and push[0] <= stone_push[2]:
if push[3] >= stone_push[1] and push[1] <= stone_push[3]:
canvas.bell()
hit += 1
score.configure(text="score:" + str(hit))
stonaki.delete()
return True
except:
continue
return False
def pole_strike(push_b):
pole_push = canvas.coords(pole)
if push_b[2] >= pole_push[0] and push_b[0] <= pole_push[2]:
if push_b[3] >= pole_push[1] and push_b[1] <= pole_push[3]:
return True
return False
canvas.bind_all("<Left>", turn_left)
canvas.bind_all("<Right>", turn_right)
push_p = canvas.coords(pole)
if push_p[0] + pa <= 0:
pa = 0
if push_p[2] + pa >= canvas_width:
pa = 0
stones = []
for i in range(0, 5):
lista = []
for j in range(0, 19):
stonaki = canvas.create_rectangle(5, 5, 25, 25, fill="firebrick")
lista.append(stonaki)
stones.append(lista)
for i in range(0, 5):
for j in range(0, 19):
canvas.move(stones[i][j], 25 * j, 25 * i)
root.update()
bottom_hit = False
hit = 0
ball = canvas.create_oval(10, 10, 25, 25, fill="cadetblue", width=1)
canvas.move(ball, 230, 461)
ba = 3
bb = -3
canvas.move(ball, ba, bb)
push_b = canvas.coords(ball)
if stone_strike(push_b):
bb = 3
if push_b[1] <= 0:
bb = 3
if push_b[3] >= canvas_height:
bottom_hit = True
if push_b[0] <= 0:
ba = 3
if push_b[2] >= canvas_width:
ba = -3
if pole_strike(push_b):
bb = -3
time.sleep(1)
while 1:
if not bottom_hit:
root.update()
time.sleep(0.01)
if hit == 95:
canvas.create_text(250, 250, text="YOU WON!!", fill="darkolivegreen", font="Calibri 24")
break
else:
canvas.create_text(250, 250, text="GAME OVER!!", fill="darkolivegreen", font="Calibri 24")
break
root = Tk()
root.title("Bounce Ball Game")
root.geometry("500x570")
root.resizable(0, 0)
canvas = Canvas(root, width=500, height=500, bd=0, bg="black")
canvas.pack(padx=10, pady=10)
canvas.create_text(250, 250, text="Press Enter to start Game!!", fill="darkolivegreen", font="Calibri 18")
score = Label(height=50, width=80, text="Score: 00", font="Calibri 14 italic")
score.pack(side="left")
root.bind_all("<Return>", startgame)
root.mainloop()
This is a common arcade game, the goal is to hit all targets as many times as you can to earn the highest score. Every time the ball hits a "stone" you earn 1 point, and if it hits 2 you earn 2 points, respectively. If the player fails to catch the ball on the bar or "pole" then the game is over.
My assignment is to turn this game written in object-oriented programming into functional programming.
import time
class Ball:
def __init__(self, cvs, pole, stones, scre):
self.stones = stones
self.cvs = cvs
self.pole = pole
self.scre = scre
self.bottom_hit = False
self.hit = 0
self.id = canvas.create_oval(10, 10, 25, 25, fill="cadetblue", width=1)
self.cvs.move(self.id, 230, 461)
self.a = 3
self.b = -3
self.cvs.move(self.id, self.a, self.b)
self.cvs_height = canvas.winfo_height()
self.cvs_width = canvas.winfo_width()
def stone_strike(self, push):
for stone_line in self.stones:
for stone in stone_line:
stone_push = self.cvs.coords(stone.id)
try:
if push[2] >= stone_push[0] and push[0] <= stone_push[2]:
if push[3] >= stone_push[1] and push[1] <= stone_push[3]:
canvas.bell()
self.hit += 1
self.scre.configure(text="Score: " + str(self.hit))
self.cvs.delete(stone.id)
return True
except:
continue
return False
def pole_strike(self, push):
pole_push = self.cvs.coords(self.pole.id)
if push[2] >= pole_push[0] and push[0] <= pole_push[2]:
if push[3] >= pole_push[1] and push[1] <= pole_push[3]:
return True
return False
def draw(self):
self.cvs.move(self.id, self.a, self.b)
push = self.cvs.coords(self.id)
if self.stone_strike(push):
self.b = 3
if push[1] <= 0:
self.b = 3
if push[3] >= self.cvs_height:
self.bottom_hit = True
if push[0] <= 0:
self.a = 3
if push[2] >= self.cvs_width:
self.a = -3
if self.pole_strike(push):
self.b = -3
class Pole:
def __init__(self, cvs):
self.cvs = cvs
self.id = canvas.create_rectangle(0, 0, 100, 10, fill="darkgoldenrod")
self.cvs.move(self.id, 200, 485)
self.a = 0
self.cvs_width = canvas.winfo_width()
self.cvs.bind_all("<Left>", self.turn_left)
self.cvs.bind_all("<Right>", self.turn_right)
def draw(self):
push = self.cvs.coords(self.id)
if push[0] + self.a <= 0:
self.a = 0
if push[2] + self.a >= self.cvs_width:
self.a = 0
self.cvs.move(self.id, self.a, 0)
def turn_left(self, event):
self.a = -5
def turn_right(self, event):
self.a = 5
class Stone:
def __init__(self):
self.id = canvas.create_rectangle(5, 5, 25, 25, fill="firebrick")
def start_game(event):
score.configure(text="Score: 00")
canvas.delete("all")
pole = Pole(canvas)
stones = []
for i in range(0, 5):
b = []
for j in range(0, 19):
tmp = Stone()
b.append(tmp)
stones.append(b)
for i in range(0, 5):
for j in range(0, 19):
canvas.move(stones[i][j].id, 25 * j, 25 * i)
ball = Ball(canvas, pole, stones, score)
root.update()
time.sleep(1)
while 1:
if not ball.bottom_hit:
ball.draw()
pole.draw()
root.update()
time.sleep(0.01)
if ball.hit == 95:
canvas.create_text(250, 250, text="YOU WON!!", fill="darkolivegreen", font="Calibri 24")
break
else:
canvas.create_text(250, 250, text="GAME OVER!!", fill="darkolivegreen", font="Calibri 24")
break
root = Tk()
root.title("Bounce Ball Game")
root.geometry("500x570")
root.resizable(0, 0)
canvas = Canvas(root, width=500, height=500, bd=0, bg="black")
canvas.pack(padx=10, pady=10)
canvas.create_text(250, 250, text="Press Enter to start Game!!", fill="darkolivegreen", font="Calibri 18")
score = Label(height=50, width=80, text="Score: 00", font="Calibri 14 italic")
score.pack(side="left")
root.bind_all("<Return>", start_game)
root.mainloop()
Here is the code I have written.. There must be logical errors since it's not working. Any ideas??
import time
def startgame(event):
score.configure(text="score:00")
canvas.delete("all")
canvas_width = canvas.winfo_width()
canvas_height = canvas.winfo_height()
pole = canvas.create_rectangle(0, 0, 100, 10, fill="darkgoldenrod")
canvas.move(pole, 200, 425)
pa = 0
def turn_left(event):
pa = -5
def turn_right(event):
pa = 5
def stone_strike(push):
for stone_line in stones:
for stone in stone_line:
stone_push = canvas.coords(stone)
try:
if push[2] >= stone_push[0] and push[0] <= stone_push[2]:
if push[3] >= stone_push[1] and push[1] <= stone_push[3]:
canvas.bell()
hit += 1
score.configure(text="score:" + str(hit))
stonaki.delete()
return True
except:
continue
return False
def pole_strike(push_b):
pole_push = canvas.coords(pole)
if push_b[2] >= pole_push[0] and push_b[0] <= pole_push[2]:
if push_b[3] >= pole_push[1] and push_b[1] <= pole_push[3]:
return True
return False
canvas.bind_all("<Left>", turn_left)
canvas.bind_all("<Right>", turn_right)
push_p = canvas.coords(pole)
if push_p[0] + pa <= 0:
pa = 0
if push_p[2] + pa >= canvas_width:
pa = 0
stones = []
for i in range(0, 5):
lista = []
for j in range(0, 19):
stonaki = canvas.create_rectangle(5, 5, 25, 25, fill="firebrick")
lista.append(stonaki)
stones.append(lista)
for i in range(0, 5):
for j in range(0, 19):
canvas.move(stones[i][j], 25 * j, 25 * i)
root.update()
bottom_hit = False
hit = 0
ball = canvas.create_oval(10, 10, 25, 25, fill="cadetblue", width=1)
canvas.move(ball, 230, 461)
ba = 3
bb = -3
canvas.move(ball, ba, bb)
push_b = canvas.coords(ball)
if stone_strike(push_b):
bb = 3
if push_b[1] <= 0:
bb = 3
if push_b[3] >= canvas_height:
bottom_hit = True
if push_b[0] <= 0:
ba = 3
if push_b[2] >= canvas_width:
ba = -3
if pole_strike(push_b):
bb = -3
time.sleep(1)
while 1:
if not bottom_hit:
root.update()
time.sleep(0.01)
if hit == 95:
canvas.create_text(250, 250, text="YOU WON!!", fill="darkolivegreen", font="Calibri 24")
break
else:
canvas.create_text(250, 250, text="GAME OVER!!", fill="darkolivegreen", font="Calibri 24")
break
root = Tk()
root.title("Bounce Ball Game")
root.geometry("500x570")
root.resizable(0, 0)
canvas = Canvas(root, width=500, height=500, bd=0, bg="black")
canvas.pack(padx=10, pady=10)
canvas.create_text(250, 250, text="Press Enter to start Game!!", fill="darkolivegreen", font="Calibri 18")
score = Label(height=50, width=80, text="Score: 00", font="Calibri 14 italic")
score.pack(side="left")
root.bind_all("<Return>", startgame)
root.mainloop()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在将这个用面向对象编程编写的游戏转变为函数式编程的过程中,我们需要照顾每个函数正在使用的变量/小部件。如果我们要对本地函数中的某些变量进行更改,并希望保留函数调用结束后所做的更改,那么我将将这些变量/小部件设为全局。
此外,在 OOP 代码中,每次使用函数
draw()
在画布中对“球”和“杆”进行更改。因此,为相同的drawB()
和drawP()
创建两个函数:您可以进一步优化此代码。
In the process of turning this game written in object-oriented programming into functional programming, we need to take care of variables/widgets which are being used by every function. If we are making changes to some variable in a local function and want to retain the changes made after the function call ends, so I will be making those variables/widgets global.
Also, in the OOP code, changes are being made every time in the canvas using functions
draw()
for both "ball" and "pole". Hence making two functions for the samedrawB()
anddrawP()
:You may further optimize this code.