Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
8.2k views
in Technique[技术] by (71.8m points)

python 3.x - Making an object reappear on opposite side in Asteroid Turtle module game

I'm working Turtle module game based on Asteroids and I have most of the code done. I just need to figure out how to make turtle objects reappear on the opposite side on the border when it collides with it. I made them turn 180 degrees when then collide until I figure out a way. I know I'm supposed to check for change in Xcor and Ycor, but other then that I'm a but lost honestly.

Edit: To clarify, I'm looking to have the objects like the player and asteroids continue to wrap around the main window when they cross the border

import math
import random
import turtle
import winsound

# screen setup
scr = turtle.Screen()
scr.setup(600, 600, 0, 0)
scr.bgpic('space_bg.gif')
scr.tracer(2)
speed = 1  # global movement speed

# Drawing a border around the canvas
border = turtle.Turtle()
border.penup()
border.setpos(-250, -250)
border.pendown()
border.pencolor('yellow')
border.pensize(3)
for side in range(4):
    border.forward(500)
    border.lt(90)
    border.hideturtle()

# create points on upper left screen
points = 0
# creating player object
player = turtle.Turtle()
player.color('white')
player.penup()
player.speed(1)
turtle.register_shape('cursor', ((5, -15), (0, 5), (-5, -15)))
player.shape('cursor')

# create asteroids(random amount between 5-6)
max_asteroids = random.randint(5, 6)
asteroids = []
for i in range(max_asteroids):
    asteroids.append(turtle.Turtle())
    asteroids[i].color('red')
    asteroids[i].shape('circle')
    asteroids[i].penup()
    asteroids[i].speed(1)
    asteroids[i].setpos(random.randint(-240, 240), random.randint(-240, 240))

# creating black holes
max_blackholes = random.randint(3, 4)
blackhole = []
for i in range(max_blackholes):
    blackhole.append(turtle.Turtle())
    blackhole[i].color('green')
    blackhole[i].shape('circle')
    blackhole[i].fillcolor('black')
    blackhole[i].penup()
    blackhole[i].setpos(random.randint(-240, 240), random.randint(-240, 240))


# movement functions when player turns left
def left_turn():  
    player.lt(30)


# movement functions when player turns right
def right_turn():  
    player.rt(30)


# Increasing movement speed
def speed_up(): 
    global speed
    speed += 1


# Decreasing movement speed
def slow_down():  
    global speed
    speed -= 1


# Collision with asteroid
def aster_collide(obj1, obj2):  
    distance = math.sqrt(math.pow(obj1.xcor() - obj2.xcor(), 2) + math.pow(obj1.ycor() - obj2.ycor(), 2))
    if distance < 20:
        return True
    else:
        return False


def hyperspace(obj1, obj2):  # collision with black hole
    distance = math.sqrt(math.pow(obj1.xcor() - obj2.xcor(), 2) + math.pow(obj1.ycor() - obj2.ycor(), 2))
    if distance < 20:
        return True
    else:
        return False


# set keyboard bindings
turtle.listen()
turtle.onkey(left_turn, "Left")
turtle.onkey(right_turn, "Right")
turtle.onkey(speed_up, "Up")
turtle.onkey(slow_down, "Down")


while True:
    player.fd(speed)

    # boundry collision check for player
    if player.xcor() > 248 or player.xcor() < -248:
        player.right(180)
    if player.ycor() > 248 or player.ycor() < -248:
        player.right(180)

    # boundary checking for asteroids
    for i in range(max_asteroids):
        asteroids[i].fd(1)  # move the asteroid
        if asteroids[i].xcor() > 240 or asteroids[i].xcor() < -240:
            asteroids[i].right(180)
        if asteroids[i].ycor() > 240 or asteroids[i].ycor() < -240:
            asteroids[i].right(180)
        # if player collides with asteroid
        if aster_collide(player, asteroids[i]):
            asteroids[i].setpos(random.randint(-240, 240), random.randint(-240, 240))
            # winsound.PlaySound('collision_sound.wav', winsound.SND_NOWAIT)
            points += 1
            # Adding score to top of the screen
            border.undo()
            border.penup()
            border.hideturtle()
            border.setpos(-230, 260)
            scores = "Score: %s" % points
            border.write(scores, False, align="left", font=("Arial", 14, "normal"))
            winsound.PlaySound('point_up.wav', winsound.SND_ASYNC)

     for count in range(max_blackholes):
            if hyperspace(player, blackhole[count]):
                 player.setpos(random.randint(-240, 240), random.randint(-240, 240))
# boundry collision check for player
    if player.xcor() > 248 or player.xcor() < -248:
        player.right(180)
    if player.ycor() > 248 or player.ycor() < -248:
        player.right(180)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can reset the x and y coordinates if the collision is detected:

    if player.xcor() > 248:
        player.setx(-248)
    if player.xcor() < -248:
        player.setx(248)
    if player.ycor() > 248:
        player.sety(-248)
    if player.ycor() < -248:
        player.sety(248)

You can also use the built-in abs() method to see if the absolute value of the player.xcor() and player.ycor() are out of the boundaries, and the copysign() method from the built-in math module to set the x and y coordinates to the opposite sign:


from math import copysign

# Your code

    if abs(player.xcor()) > 248:
        player.setx(copysign(248, player.xcor() * -1))
    if abs(player.ycor()) > 248:
        player.setx(copysign(248, player.ycor() * -1))


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...