Мой враг застыл в воздухе и не двигается - PullRequest
0 голосов
/ 29 июня 2019

Я думаю, что моя игра должна работать без сбоев, но она просто заморожена.Я не знаю, с чего начать, потому что нет сообщения об ошибке:

import turtle
import random

# create sprite
class Sprite(turtle.Turtle):
    def __init__(self, sprite_shape, color, startx, starty):
        super().__init__( shape=sprite_shape)

        self.speed(0)
        self.penup()
        self.color(color)
        self.goto(startx, starty)

        self.speed = 1

    def move(self):
        self.forward(self.speed)

        # Boundary detection
        if self.xcor() > 300:
            self.setx(300)
            self.rt(90)
        elif self.xcor() < -300:
            self.setx(-300)
            self.lt(120)

        if self.ycor() > 300:
            self.sety(300)
            self.lt(90)
        elif self.ycor() < -300:
            self.sety(-300)
            self.lt(120)


    def is_collision(self, other):
        return self.distance(other) < 20

# create enemy
class Enemy(Sprite):
    def __init__(self ,  spriteshape, color, startx, starty):
        Sprite.__init__(self  , spriteshape, color, startx, starty)
        self.speed = 4
        self.setheading(random.randint(0,360))  

#Set up the screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("Space Invaders")

#Draw border
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300,-300)
border_pen.pendown()
border_pen.pensize(6)
border_pen.fd(600)
border_pen.lt(90)
border_pen.fd(600)
border_pen.lt(90)
border_pen.fd(600)
border_pen.lt(90)
border_pen.fd(600)
border_pen.lt(90)
border_pen.hideturtle()

#create the base
base = turtle.Turtle()
base.speed(0)
base.color("blue")
base.penup()
base.setposition(0, -280)
base.pendown()
base.pensize(3)
base.forward(295)
base.right(90)
base.forward(15)
base.right(90)
base.forward(592)
base.right(90)
base.forward(15)
base.right(90)
base.forward(390)
base.hideturtle()


#Create the player turtle
player = turtle.Turtle()
player.color("yellow")
player.shape("square")
player.penup()
player.speed(0)
player.setposition(0, -250)
player.setheading(90)
player.shapesize(2.5)

playerspeed = 15






#Create the player turtle

player = turtle.Turtle()
player.color("yellow")
player.shape("square")
player.penup()
player.speed(0)
player.setposition(0, -250)
player.shapesize(2.3)

player_speed = 35

# player movement

def move_left():
    x = player.xcor() - player_speed

    if x < -280:
        x = - 280

    player.setx(x)

def move_right():
    x = player.xcor() + player_speed

    if x > 280:
        x = 280

    player.setx(x)


# keybindings
turtle.listen()
turtle.onkey(move_left, "Left")
turtle.onkey(move_right, "Right")

# create sprite
enemy = Enemy('circle', 'red', -200, 250)

# main game loop
def play():
    enemy.move()

    # check for collision
    if enemy.is_collision(player):
         x = random.randint(-250, 250)
         y = random.randint(-250, 250)
         enemy.setposition(-250, 250)
         enemy.setheading(250)

         wn.ontimer(play, 10 )

play()


if enemy.is_collision(base):
    player.hideturtle()
    enemy.hideturtle()
    base.hideturtle()
    print ("Game Over")


play()


Я бы ожидал, что противник двинется, но он застыл в воздухе.Игрок перемещается, но оставляет дубликат позади.Я не могу проверить, работает ли система респауна после столкновения с базой.

Ответы [ 2 ]

1 голос
/ 29 июня 2019

вижу две проблемы

  1. вам нужно mainloop(), чтобы черепаха (точнее, tkinter, используемая черепахой) могла запустить цикл, который получает события клавиатуры / мыши из системы (снова и снова) и запускает слушатель. Он также использует этот цикл для запуска элементов, добавленных с timer().

  2. у вас неправильные отступы в соответствии с wn.ontimer(play, 10). Вы должны использовать его в конце play(), чтобы запустить его снова, но он есть внутри if enemy.is_collision(player):, поэтому он не выполняется.

Код, который перемещает красный круг, и я могу использовать клавиши для перемещения желтого квадрата

# main game loop
def play():
    enemy.move()

    # check for collision
    if enemy.is_collision(player):
         x = random.randint(-250, 250)
         y = random.randint(-250, 250)
         enemy.setposition(-250, 250)
         enemy.setheading(250)

    if enemy.is_collision(base):
        player.hideturtle()
        enemy.hideturtle()
        base.hideturtle()
        print ("Game Over")

    wn.ontimer(play, 10)

# start
play()
turtle.mainloop()
0 голосов
/ 29 июня 2019

Я переработал ваш код ниже, решая несколько проблем и стилей.Основные проблемы, которые я отметил: вы спутали столкновение с формой , нарисованной base черепахой, со столкновением с base черепахой;в Sprite вы переопределили метод speed() черепахи как переменную экземпляра;те проблемы, которые решает @furas (+1), хотя play() необходимо ontimer() в предложении else для правильного выхода игры:

from turtle import Screen, Turtle
from random import randint

CURSOR_SIZE = 20

WIDTH, HEIGHT = 600, 600
MARGIN = 50
BASE_HEIGHT = 15
PEN_SIZE = 5
PLAYER_SIZE = 50
SPRITE_SIZE = CURSOR_SIZE

PLAYER_SPEED = PLAYER_SIZE/2
ENEMY_SPEED = SPRITE_SIZE/4

# Create sprite
class Sprite(Turtle):
    def __init__(self, sprite_shape, color, startx, starty):
        super().__init__(shape=sprite_shape)
        self.hideturtle()

        self.speed('fastest')
        self.penup()
        self.color(color)
        self.goto(startx, starty)

        self.showturtle()

        self.steps = 1

    def move(self):
        self.forward(self.steps)

        # Boundary detection
        if self.xcor() > WIDTH/2 - SPRITE_SIZE/2:
            self.setx(WIDTH/2 - SPRITE_SIZE/2)
            self.rt(90)
        elif self.xcor() < SPRITE_SIZE/2 - WIDTH/2:
            self.setx(SPRITE_SIZE/2 - WIDTH/2)
            self.lt(120)

        if self.ycor() > HEIGHT/2 - SPRITE_SIZE/2:
            self.sety(HEIGHT/2 - SPRITE_SIZE/2)
            self.lt(90)
        elif self.ycor() < SPRITE_SIZE/2 - HEIGHT/2:
            self.sety(SPRITE_SIZE/2 - HEIGHT/2)
            self.lt(120)

    def is_collision(self, other):
        return self.distance(other) < SPRITE_SIZE/2

# Create enemy
class Enemy(Sprite):
    def __init__(self, spriteshape, color, startx, starty):
        super().__init__(spriteshape, color, startx, starty)
        self.steps = ENEMY_SPEED
        self.setheading(randint(0, 360))

    def is_collision(self, other):
        return self.distance(other) < PLAYER_SIZE/2

# Set up the screen
wn = Screen()
wn.setup(WIDTH + MARGIN * 2, HEIGHT + MARGIN * 2)
wn.bgcolor('black')
wn.title("Space Invaders")

# Draw border
border_pen = Turtle()
border_pen.hideturtle()
border_pen.speed('fastest')
border_pen.color('white')
border_pen.pensize(PEN_SIZE)

border_pen.penup()
border_pen.setposition(-WIDTH/2, -HEIGHT/2)
border_pen.pendown()

for _ in range(2):
    border_pen.fd(WIDTH)
    border_pen.lt(90)
    border_pen.fd(HEIGHT)
    border_pen.lt(90)

# Create the base
base = Turtle()
base.hideturtle()
base.shape('square')
base.color('blue', 'black')
base.penup()
base.setposition(0, BASE_HEIGHT/2 - HEIGHT/2 + PEN_SIZE)
base.shapesize(BASE_HEIGHT / CURSOR_SIZE, (WIDTH - PEN_SIZE*2) / CURSOR_SIZE, PEN_SIZE)
base.showturtle()

# Create the player turtle
player = Turtle()
player.hideturtle()
player.shape('square')
player.shapesize(PLAYER_SIZE / CURSOR_SIZE)
player.color('yellow')
player.speed('fastest')
player.penup()
player.setposition(0, PLAYER_SIZE/2 - HEIGHT/2 + BASE_HEIGHT + PEN_SIZE)
player.setheading(90)
player.showturtle()

# player movement

def move_left():
    x = player.xcor() - PLAYER_SPEED

    if x < PLAYER_SIZE - WIDTH/2:
        x = PLAYER_SIZE/2 - WIDTH/2

    player.setx(x)

def move_right():
    x = player.xcor() + PLAYER_SPEED

    if x > WIDTH/2 - PLAYER_SIZE:
        x = WIDTH/2 - PLAYER_SIZE/2

    player.setx(x)

# Keybindings
wn.onkey(move_left, 'Left')
wn.onkey(move_right, 'Right')
wn.listen()

# Create sprite
enemy = Enemy('circle', 'red', randint(SPRITE_SIZE - WIDTH/2, WIDTH/2 - SPRITE_SIZE), randint(0, HEIGHT/2 - SPRITE_SIZE))

# main game loop
def play():
    enemy.move()

    # check for collision
    if enemy.is_collision(player):
        x = randint(SPRITE_SIZE - WIDTH/2, WIDTH/2 - SPRITE_SIZE)
        y = randint(0, HEIGHT/2 - SPRITE_SIZE)
        enemy.setposition(x, y)
        enemy.setheading(randint(0, 360))

    if enemy.ycor() <= BASE_HEIGHT - HEIGHT/2 + SPRITE_SIZE/2:
        player.hideturtle()
        enemy.hideturtle()
        base.hideturtle()
        print("Game Over")
    else:
        wn.ontimer(play, 25)

# start
play()
wn.mainloop()
...