Snake Game - obstacle problem - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: Snake Game - obstacle problem (/thread-21856.html) |
Snake Game - obstacle problem - Samira - Oct-17-2019 Hi everyone, I'm a relatively new in python programming and I tried to make a Snake game using a turtle graphics, partly following a tutorial on the internet. Everything worked fine, but then I decided I wanted to add obstacles/bushes. The problem is, that both the food and the bush spawn randomly, which is good, but I don't know how to exclude the coordinates of the bush from the possible coordinates of the food. In different words, I don't want the food to ever spawn inside the bush or touch it. But I can't figure out how to do it. food = turtle.Turtle() food.color("violetred4") food.shape("circle") food.speed(0) food.penup() x = random.randint(-280, 280) y = random.randint(-280, 280) food.goto(x, y) bush = turtle.Turtle() bush.color("olivedrab4") bush.shape("square") bush.speed(0) bush.penup() bush.shapesize(10, 10) x = random.randint(-280, 280) y = random.randint(-280, 280) bush.goto(x, y)I tried to put into the code something like this, but it didn't work. I assume that's because it will refresh the window and change the coordinates after the snake eats the food and not before. if food.distance(bush) < 50: x = random.randint(-280, 280) y = random.randint(-280, 280) food.goto(x, y)Can someone help me with this? Here is the whole code: import turtle import time import random delay = 0.1 # makes the snake go slower score = 0 high_score = 0 game = turtle.Screen() # creates a game board game.bgcolor("darkslategray1") game.title("Snake Game") game.setup(width=600, height=600) game.tracer(0) # turns off the screen updates # creates the snake's head head = turtle.Turtle() head.color("black") head.shape("square") head.speed(0) head.penup() # won't draw lines where the snake goes head.goto(0, 0) # makes the head begin at the center of the board head.direction = "stop" # the head won't move until we press a key # creates a food for the snake food = turtle.Turtle() food.color("violetred4") food.shape("circle") food.speed(0) # the food is not moving food.penup() x = random.randint(-280, 280) y = random.randint(-280, 280) food.goto(x, y) # the food will start at random position # creates an obstacles bush = turtle.Turtle() bush.color("olivedrab4") bush.shape("square") bush.speed(0) bush.penup() bush.shapesize(10, 10) x = random.randint(-280, 280) y = random.randint(-280, 280) bush.goto(x, y) segments = [] # we create segments so every time the snake eats a food, it will grow # score counter - pen allows us to draw on the board pen = turtle.Turtle() pen.speed(0) pen.shape("square") pen.color("black") # the color of the text pen.penup() pen.hideturtle() pen.goto(0, 260) pen.write("SCORE: 0 HIGH SCORE: 0", align="center", font=("Georgia", 20, "bold",)) # this function allows our snake to move in desired direction def move(): if head.direction == "up": y = head.ycor() head.sety(y + 20) if head.direction == "down": y = head.ycor() head.sety(y - 20) if head.direction == "left": x = head.xcor() head.setx(x - 20) if head.direction == "right": x = head.xcor() head.setx(x + 20) # these functions won't allow the snake to move from up to down, from left to right etc. without turning first def go_up(): if head.direction != "down": head.direction = "up" def go_down(): if head.direction != "up": head.direction = "down" def go_left(): if head.direction != "right": head.direction = "left" def go_right(): if head.direction != "left": head.direction = "right" # let's bind keyboards to the 'move' function game.listen() game.onkeypress(go_up, "w") game.onkeypress(go_down, "s") game.onkeypress(go_left, "a") game.onkeypress(go_right, "d") # we create an always true loop, so the game keeps going while True: game.update() if food.distance(bush) < 50: x = random.randint(-280, 280) y = random.randint(-280, 280) food.goto(x, y) # we check if the snake will touch the border on both x and y coordinates - if yes, game over if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290: time.sleep(1.5) head.goto(0, 0) # the head will go to the center and the game starts again head.direction = "stop" for segment in segments: # it will hide the segments of the snake, meaning he died segment.goto(1000, 1000) segments.clear() # will remove the segments score = 0 # will reset the score delay = 0.1 pen.clear() # will clear the score counter pen.write("SCORE: {} HIGH SCORE: {}".format(score, high_score), align="center", font=("Georgia", 20, "bold")) if head.distance(food) < 25: # checking if snake 'ate' the food x = random.randint(-280, 280) # the food will move to random place y = random.randint(-280, 280) food.goto(x, y) # when snakes eat food, both food and bushes will change position # Add a segment new_segment = turtle.Turtle() new_segment.speed(0) new_segment.color("cyan4") new_segment.shape("square") new_segment.penup() segments.append(new_segment) # will add a new segment delay -= 0.002 # it will shorten the delay every time the snake gets new segment, making game faster # will increase the score score += 10 if score > high_score: high_score = score # sets a new high score pen.clear() pen.write("SCORE: {} HIGH SCORE: {}".format(score, high_score), align="center", font=("Georgia", 20, "bold")) for index in range(len(segments) - 1, 0, -1): # reverse the order of segments x = segments[index - 1].xcor() y = segments[index - 1].ycor() segments[index].goto(x, y) if len(segments) > 0: # move first segment to the place of head x = head.xcor() y = head.ycor() segments[0].goto(x, y) move() # will check if the snake collided with his own body for segment in segments: if segment.distance(head) < 20: time.sleep(1) head.goto(0, 0) head.direction = "stop" # hide the segments after death so they don't stay here for segment in segments: segment.goto(1000, 1000) # clears the segments list so the snakes starts with just his head segments.clear() # resets the score to zero score = 0 # resets the delay to the original one delay = 0.1 pen.clear() # clears the score pen.write("SCORE: {} HIGH SCORE: {}".format(score, high_score), align="center", font=("Georgia", 20, "bold")) time.sleep(delay) game.mainloop() RE: Snake Game - obstacle problem - Aurthor_King_of_the_Brittons - Oct-18-2019 I found something that appears to work okay from what I could tell. I'm sure there's a more efficient way to do it, but the code is as follows. You may want to include more logic to make sure the bush doesn't spawn on the center (snake) as well. # creates an obstacles bush = turtle.Turtle() bush.color("olivedrab4") bush.shape("square") bush.speed(0) bush.penup() bush.shapesize(10, 10) t = random.randint(-280, 280) u = random.randint(-280, 280) if t - 250 < x or t + 250 > x: if t > 0: t -= 250 else: t += 250 if u - 250 < y or u + 250 > y: if u > 0: u -= 250 else: u += 250 RE: Snake Game - obstacle problem - Aurthor_King_of_the_Brittons - Oct-19-2019 Just wanted to give you a heads up: my solution above didn't work out once tested enough times. Not sure if it's on the right track or not, but just didn't want to cause any additional headaches by my previous statement which said that it worked. RE: Snake Game - obstacle problem - Samira - Oct-31-2019 Thanks for trying to help me out :) eventually I figured it out. So for anyone with the same problem, this is what I did: while True: game.update() if food.distance(bomb1) < 40 or food.distance(bomb2) < 40 or food.distance(bomb3) < 40 \ or food.distance(bomb4) < 40 or food.distance(bomb5) < 40: food.goto(random.randint(-250, 250), random.randint(-250, 250)) game.update()I tested it and it works - if the apple spawns too close to the bomb, it will immediately spawn again somewhere else. |