2017-09-13 90 views
1

我目前正在尝试使用龟图形在python中制作蛇游戏,并且遇到游戏打破错误时,如果您使用a和d键打开乌龟,前一回合。它似乎正在执行代码乱序,但我不知道发生了什么。代码以奇怪的顺序与乌龟图形执行

整个代码如下

import turtle 
import random 
import math 

x = 400 
y = 400 
global speed 
global points 
points = 0 
speed = 2 
posList = [''] 

# turns your character left 
def left(): 
    global speed 
    global posList 
    key = True 
    char.fd(speed) 
    char.left(90) 
    char.fd(speed) 

# turns your character left 
def right(): 
    global speed 
    global posList 
    key = True 
    char.fd(speed) 
    char.right(90) 
    char.fd(speed) 

# adds one box to the point counter 
def point(): 
    global points 
    points += 1 
    wall.speed(0) 
    wall.pendown() 
    wall.forward(50) 
    wall.seth(90) 
    wall.forward(10) 
    wall.seth(180) 
    wall.forward(50) 
    wall.seth(270) 
    wall.forward(10) 
    wall.penup() 
    wall.seth(90) 
    wall.forward(12) 
    wall.seth(0) 
    dot.setx(random.randint(-200,200)) 
    dot.sety(random.randint(-200,200)) 
    print(points) 

# checks if curren posisition is anywhere you have ever been 
def checkBracktrack(pos, poslist): 
    found = False 
    for thing in posList: 
     if thing == pos: 
      found=True 
    return found 

# creates the box that the game occurs in 
turtle.colormode(255) 
screen = turtle.Screen() 
dot = turtle.Turtle() 
dot.penup() 
dot.speed(0) 
dot.shape('turtle') 
dot.setx(random.randint(-200,200)) 
dot.sety(random.randint(-200,200)) 
wall = turtle.Turtle() 
wall.speed(0) 
wall.penup() 
wall.goto(x/2,y/2) 
wall.pendown() 
wall.seth(180) 
wall.forward(400) 
wall.seth(270) 
wall.forward(400) 
wall.seth(0) 
wall.forward(400) 
wall.seth(90) 
wall.forward(400) 
wall.seth(270) 
wall.forward(400) 
wall.seth(0) 
wall.penup() 
wall.forward(100) 
char = turtle.Turtle() 
x = 0 
y = 0 

# updates the position of the player turtle 
while True: 
    screen.onkey(left,"a") 
    screen.onkey(right,"d") 
    char.hideturtle() 
    char.forward(speed) 
    char.speed(0) 
    turtle.listen(xdummy=None, ydummy=None) 
    print(char.pos()) 
    print(posList[(len(posList)-1)]) 

    # checks if current position is the same as any position it has ever been in !this is the bit that is having problems! 
    if checkBracktrack(char.pos(),posList): 
     speed = 0 
     break 

    # checks if it is close enough to a point marker to 
    if char.ycor() in range(dot.ycor()-10,dot.ycor()+10) and char.xcor() in range(dot.xcor()-10,dot.xcor()+10): 
     point() 

    # checks if in the box 
    if char.ycor() not in range(-200,200) or char.xcor() not in range(-200,200): 
     speed = 0 

    # adds current location to the list 
    posList.append(char.pos()) 
    char.fd(speed) 


print('you travelled',len(posList),'pixels') 
print('collided with yourself') 
print(char.pos()) 
print(posList) 
name = input('quit') 
screen.mainloop() 

回答

1

有许多与你的代码的小问题:你需要重读有关何时使用global;您的checkBracktrack()函数将poslist作为参数,但在全局posList上运行(case typo);由于额外的fd()调用和speed大于1,您的像素行进距离计算不正确;使用龟的.distance()方法可以大大简化您的接近测试;您在游戏板上显示点的代码根本不起作用;当你只需要为每个键调用一次时,你可以一次又一次地呼叫onkey();您的checkBracktrack()函数有一个不必要的循环。

我在代码中遇到的最大问题是while True:,这不应该发生在基于事件的代码中。我已经重写,以下简化代码,解决上述问题以及其他:

from turtle import Turtle, Screen 
from random import randint 

FONT = ('Arial', 24, 'normal') 
WIDTH, HEIGHT = 400, 400 
SPEED = 1 

def left(): 
    """ turns your character left """ 
    char.left(90) 

def right(): 
    """ turns your character right """ 
    char.right(90) 

def point(): 
    """ adds one box to the point counter """ 
    global points 

    points += 1 

    wall.undo() 
    wall.write(points, font=FONT) 

    dot.setpos(randint(-WIDTH/2, WIDTH/2), randint(-HEIGHT/2, HEIGHT/2)) 

def checkBracktrack(pos, poslist): 
    """ checks if current posiition is anywhere you have ever been """ 

    return pos in poslist 

def move_char(): 
    """ updates the position of the player turtle """ 

    over = False 
    char.forward(SPEED) 

    # checks if current position is the same as any position it has ever been at 
    if checkBracktrack(char.pos(), posList): 
     over = True 

    # checks if in the box 
    elif not (-200 <= char.ycor() <= 200 and -200 <= char.xcor() <= 200): 
     over = True 

    if over: 
     print('you travelled', len(posList), 'pixels') 
     return 

    # adds current location to the list 
    posList.append(char.pos()) 

    # checks if it is close enough to a point marker 
    if char.distance(dot) < 20: 
     point() 

    screen.ontimer(move_char, 10) 

points = 0 
posList = [] 

# creates the box in which the game occurs 
screen = Screen() 
screen.onkey(left, "a") 
screen.onkey(right, "d") 
screen.listen() 

dot = Turtle('turtle') 
dot.speed('fastest') 
dot.penup() 
dot.setpos(randint(-WIDTH/2, WIDTH/2), randint(-HEIGHT/2, HEIGHT/2)) 

wall = Turtle(visible=False) 
wall.speed('fastest') 
wall.penup() 
wall.goto(WIDTH/2, HEIGHT/2) 
wall.pendown() 

for _ in range(4): 
    wall.right(90) 
    wall.forward(400) 

wall.penup() 
wall.forward(100) 
wall.write("0", font=FONT) 

char = Turtle(visible=False) 
char.speed('fastest') 

move_char() 

screen.mainloop() 

我的信念是促使你原来的问题的问题得到了固定的再处理代码的过程。

enter image description here

+0

你设法解决我是有重大错误,但在你的代码中的碰撞检测似乎是在我的测试不可靠。感谢您一直以来的帮助 –