我是Python的新手,但是我已经用其他语言编码,主要用于硬件。我用乌龟在Python中制作了Pong,但是有点毛病。我想知道是否有人可以检查一下并提供建议。我也想添加开始屏幕和结束屏幕,但是有点不确定如何。另外,如果您对如何改进碰撞检测有任何建议,请告诉我。
我在下面粘贴代码
private async void StartClient()
{
String sName = "<server ip>";
int port = <server port>;
WaveOut waveout = new WaveOut();
TcpClient conn = new TcpClient();
try
{
int counter = 0;
conn.Connect(sName, port);
stream = conn.GetStream();
by = new byte[2560]; // new byte array to store received data
var bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(16000, 16, 2));
bufferedWaveProvider.BufferLength = 2560 * 16; //16 is pretty good
bufferedWaveProvider.DiscardOnBufferOverflow = true;
while (true)
{
//wait until buffer has data, then returns buffer length
int bytesAvailable = await stream.ReadAsync(by, 0, 2560);
if (counter == 0)
{
msg = Encoding.UTF8.GetString(by, 0, bytesAvailable);
devicehash = msg.TrimEnd();
DispatchMethod(by[0].ToString());
counter++;
}
else
{
//send to speakers
bufferedWaveProvider.AddSamples(by, 0, 2560);
if (counter == 1)
{
waveout.Init(bufferedWaveProvider);
waveout.Play();
counter++;
}
}
}
}
catch (Exception e)
{
}
}
答案 0 :(得分:1)
我看到一些问题:
您已经将20 x 20平方拉伸为10 x 80:
AIplayer.shapesize(0.5,4)
但是您的碰撞距离中心只有20,所以您的球可以 越过桨叶的底部或顶部而没有实际 碰撞。
您的isCollision()
函数对于乌龟自己的函数几乎是多余的
.collision()
方法。
在像乌龟这样的事件驱动世界中,您不应该拥有while True:
因为它有可能阻止某些事件的触发。更好地
将其替换为计时器事件。
您的某些碰撞在应该改变x和y增量的同时 只需更改其中之一即可。
您应该避免在主循环中重复查询乌龟,并避免检查其他逻辑子句所否定的条件。即在主循环中尽力而为。
以下是我根据上述内容对您的游戏进行的重做,以及许多其他样式和逻辑更改:
from turtle import Turtle, Screen
FONT = ("Arial", 16, "normal")
def isCollision(t1, t2):
return t1.distance(t2) < 15
# set up screen
screen = Screen()
screen.bgcolor("darkgreen")
screen.title("Pong")
# set up border
border_pen = Turtle(visible=False)
border_pen.speed('fastest')
border_pen.color('white')
border_pen.pensize(3)
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
for _ in range(4):
border_pen.forward(600)
border_pen.left(90)
# set score to 0
score = 0
# set time to zero
seconds = 0
# Draw score
score_pen = Turtle(visible=False)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 310)
score_pen.write("Score {}".format(score), False, align="left", font=FONT)
# Draw timer
time_pen = Turtle(visible=False)
time_pen.color("white")
time_pen.penup()
time_pen.setposition(260, 310)
time_pen.write("Time {}".format(int(seconds)), False, align="left", font=FONT)
# create the player turtle
player = Turtle("square", visible=False)
player.shapesize(0.5, 3)
player.speed('fastest')
player.setheading(90)
player.color("blue")
player.penup()
player.setposition(-280, -250) # (x,y)
player.showturtle()
playerspeed = 15
# create the AIplayer turtle
AIplayer = Turtle("square", visible=False)
AIplayer.shapesize(0.5, 3)
AIplayer.speed('fastest')
AIplayer.setheading(90)
AIplayer.color("black")
AIplayer.penup()
AIplayer.setposition(280, 250) # (x,y)
AIplayer.showturtle()
AIplayerspeed = 15
# create the pong
pong = Turtle("circle", visible=False)
pong.shapesize(0.5, 0.5)
pong.speed('fast')
pong.color("red")
pong.penup()
pong.sety(265)
pong.showturtle()
pongspeed = 15
pong_dx, pong_dy = 5, -5
# Move player up and down
def move_up():
player.forward(playerspeed)
y = player.ycor()
if y > 265:
y = 260
player.sety(y)
screen.update()
def move_down():
player.backward(playerspeed)
y = player.ycor()
if y < -265:
y = -260
player.sety(y)
screen.update()
# keyboard bindings
screen.onkey(move_up, "Up")
screen.onkey(move_down, "Down")
screen.listen()
# main game loop
def move():
global pong_dx, pong_dy, AIplayerspeed, seconds, score
# move pong ball
x, y = pong.position()
x += pong_dx
y += pong_dy
pong.setposition(x, y)
if isCollision(pong, player): # collision pong and player
pong_dx *= -1
# Update the score
score += 10
score_pen.undo()
score_pen.write("Score: {}".format(score), align="left", font=FONT)
elif isCollision(pong, AIplayer): # collision pong and AIplayer
pong_dx *= -1
elif y < -300 or y > 300: # check for bounce and redirect it
pong_dy *= -1
elif x > 300:
pong_dx *= -1
elif x < -300:
print("Game Over")
screen.bye()
return
# move AI paddle (might speed up pong movement)
AIplayer.forward(AIplayerspeed)
y = AIplayer.ycor()
if y < -250 or y > 250:
AIplayerspeed *= -1
# display timer
seconds += 0.05
time_pen.undo()
time_pen.write("Time: {}".format(int(seconds)), False, align="Left", font=FONT)
screen.ontimer(move, 50)
screen.update()
screen.tracer(False)
move()
screen.mainloop()
我无法理解您的“提高球速”逻辑,因此我将其遗漏了。我使用了较深的背景颜色,因为难以在屏幕上查看原始图像。
答案 1 :(得分:0)
与乒乓球/球速相关的问题可能是由于您的CPU引起的。每次屏幕更新时,球都在(x和y)两个方向上移动5个像素,并且更新速率取决于CPU速度。 CPU执行的进程不是恒定的,因此CPU速度会波动。另外,因为我们将screen.tracer()
设置为False
,所以它不显示动画。 因此,由于缺乏动画效果和CPU速度不一致,我们看到乒乓/球的速度在增加/减少。
有关screen.tracer()
的解释,请参见https://youtu.be/LH8WgrUWG_I?t=123
有关“增加速度”的说明,请参见https://youtu.be/Hw1H3rG3POM?t=40
要获得更一致的行为,可以在循环中添加足够长的暂停时间,以抵消计算时间的可变性并避免绘制无用的帧。您可以使用time
import time
# Initialization
...
while True:
time.sleep(1 / 60)
# The rest of your game logic
...