gpt4 book ai didi

python - Kivy - 试图理解 Clock.schedule_interval

转载 作者:太空宇宙 更新时间:2023-11-04 05:57:16 28 4
gpt4 key购买 nike

我是 Kivy 的新手,我在做乒乓球教程,一切都很顺利,我将它改编为 4 个玩家,每个 Racket 都有自己的颜色,如果球击中 Racket ,它就会得到它的颜色,这样如果球离开屏幕,最后一名击球手将获得得分。

我在 Ubuntu 14,04 中运行,带有 virtualenv。

为了方便下载和检查,所有代码都可以在这里找到:Pong_kivy

有什么问题?

游戏结束后,一旦它重新开始,球似乎每次都在增加速度,直到它崩溃,这不是由速度矢量引起的,我检查了它,因此我认为我处理错误的 Clock.Schedule 函数.我似乎找不到问题所在,因此不胜感激。

pong.py 文件

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.graphics import *
from kivy.uix.button import Button, Label
from random import randint


class PongPaddle(Widget):
score = NumericProperty(0)
orientation = ObjectProperty([0, 0])
color = ObjectProperty([0,0,0,1])

def bounce_ball(self, ball):
if self.collide_widget(ball):
vx, vy = ball.velocity
ball.color = self.color
ball.last_hit = int(self.custom_id)
if self.orientation[0] == 25:
offset = (ball.center_y - self.center_y) / (self.height / 2)
bounced = Vector(-1 * vx, vy)
vel = bounced * 1.1
ball.velocity = vel.x, vel.y + offset
else:
offset = (ball.center_x - self.center_x) / (self.width / 2)
bounced = Vector(vx, -1 * vy)
vel = bounced * 1.1
ball.velocity = vel.x + offset, vel.y

class PongBall(Widget):
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(0)
last_hit = 0
color = ObjectProperty([0,0,0,1])
velocity = ReferenceListProperty(velocity_x, velocity_y)

def move(self):
self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
ball = ObjectProperty(None)
player1 = ObjectProperty(None)
player2 = ObjectProperty(None)
player3 = ObjectProperty(None)
player4 = ObjectProperty(None)
l = Label()
btn1 = Button(text='Restart')
win_game = 1

def start(self):
Clock.schedule_interval(self.update, 1.0 / 60.0)

def stop(self):
# Stop updating
Clock.unschedule(self.update)

def init(self):
## Setup players
self.player1.orientation = [25, 200]
self.player1.color = [1,0,0,1]
self.player1.score = 0
# Player 2
self.player2.orientation = [25, 200]
self.player2.color = [0,1,0,1]
self.player2.score = 0
# Player 3
self.player3.orientation = [200, 25]
self.player3.color = [0,0,1,1]
self.player3.score = 0
# Player 4
self.player4.orientation = [200, 25]
self.player4.color = [1,1,0,1]
self.player4.score = 0

def serve_ball(self):
# Ball velocity - Add 2 to avoid 0
vel = (randint(-8,6)+2, randint(-8,6)+2)

# Setup ball
self.ball.center = self.center
self.ball.velocity = vel
self.ball.last_hit = 0
self.ball.color = [1,1,1,1]

def update(self, dt):
self.ball.move()

#Bounce out the of paddles - Why do all check? Only can bounce on one any given time
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
self.player3.bounce_ball(self.ball)
self.player4.bounce_ball(self.ball)

#bounce ball off bottom or top - This is for 2 players game
# if (self.ball.y < self.y) or (self.ball.top > self.top):
# self.ball.velocity_y *= -1

# Went of any side? - Last hitter gets a goal
if self.ball.x < self.x or self.ball.x > self.width or self.ball.y < self.y or self.ball.y > self.height:
if self.ball.last_hit == 1:
self.player1.score += 1
elif self.ball.last_hit == 2:
self.player2.score += 1
elif self.ball.last_hit == 3:
self.player3.score += 1
elif self.ball.last_hit == 4:
self.player4.score += 1
self.serve_ball()

if self.player1.score >= self.win_game:
self.player_win(1)
elif self.player2.score >= self.win_game:
self.player_win(2)
elif self.player3.score >= self.win_game:
self.player_win(3)
elif self.player4.score >= self.win_game:
self.player_win(4)

def player_win(self, player_int):
# Remove Ball and players
self.clear_widgets()
# Configure Label and Btn
self.l.text ='Player ' + str(player_int) + ' Wins!!'
self.l.top = self.top-50
self.l.font_size = 50
self.l.center_x = self.width/2
self.btn1.bind(on_press=self.restart)
self.btn1.center_x = self.width/2
self.btn1.top = self.top/2
self.add_widget(self.l)
self.add_widget(self.btn1)
self.stop()


def on_touch_move(self, touch):
if touch.x < self.width / 3 and touch.y > self.height / 6 \
and touch.y < 5 * self.height/6:
self.player1.center_y = touch.y
if touch.x > self.width - self.width / 3 and touch.y > self.height / 6 \
and touch.y < 5 * self.height / 6:
self.player2.center_y = touch.y
if touch.y < self.height / 3 and touch.x > self.width / 6 \
and touch.x < 5 * self.width / 6:
self.player4.center_x = touch.x
if touch.y > 2* self.height / 3 and touch.x > self.width / 6 \
and touch.x < 5 * self.width / 6:
self.player3.center_x = touch.x

# Method update layout
def update_rect(instance, value):
instance.rect.pos = instance.pos
instance.rect.size = instance.size

def restart(self, instance):
# Remove btn and labels
self.clear_widgets()

# Add what I want
self.add_widget(self.ball)
self.add_widget(self.player1)
self.add_widget(self.player2)
self.add_widget(self.player3)
self.add_widget(self.player4)
self.init()
self.serve_ball()
self.start()

class PongApp(App):
def build(self):
game = PongGame()
game.init()
game.serve_ball()
game.start()
return game


if __name__ == '__main__':
PongApp().run()

pong.kv 文件

#:kivy 1.0.9

<PongBall>:
size: 50, 50
canvas:
Color:
rgba: self.color[0], self.color[1], self.color[2], self.color[3]
Ellipse:
pos: self.pos
size: self.size

<PongPaddle>:
size: root.orientation[0], root.orientation[1]
canvas:
Color:
rgba: self.color[0], self.color[1], self.color[2], self.color[3]
Rectangle:
pos:self.pos
size:self.size

<PongGame>:
ball: pong_ball
player1: player_left
player2: player_right
player3: player_top
player4: player_bottom

canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'black.jpg'

Label:
font_size: 15
center_x: root.width / 8
top: self.height*0.95
text: "P1: " + str(root.player1.score)
Label:
font_size: 15
center_x: root.width / 8
top: self.height*0.80
text: "P2: " + str(root.player2.score)
Label:
font_size: 15
center_x: root.width / 5
top: self.height*0.95
text: "P3: " + str(root.player3.score)
Label:
font_size: 15
center_x: root.width / 5
top: self.height*0.80
text: "P4: " + str(root.player4.score)


PongBall:
id: pong_ball
center: self.parent.center

PongPaddle:
id: player_left
custom_id: "1"
x: root.x
center_y: root.center_y

PongPaddle:
id: player_right
custom_id: "2"
x: root.width-self.width
center_y: root.center_y

PongPaddle:
id: player_top
custom_id: "3"
y: root.height - self.height
center_x: root.center_x

PongPaddle:
id: player_bottom
custom_id: "4"
y: root.y
center_x: root.center_x

最佳答案

问题似乎不是时钟。 restart 方法被多次调用,这似乎是因为您每次调用 init() 时都绑定(bind)了 on_press 调用如果将该行移动到 __init__ 函数,则 bind 仅调用一次,按钮每次按下时仅调用一次重新启动,并且不会发生错误:

def __init__(self, **kwargs):
super(PongGame, self).__init__(**kwargs)
self.btn1.bind(on_press=self.restart)

关于python - Kivy - 试图理解 Clock.schedule_interval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27027942/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com