I'm trying to make a game called Egg Catcher currently, for personal reasons (just for fun) and I'm a little bit stuck on my code. I want my egg to reset each time it either gets caught by the basket or it reaches the bottom, but it only checks for contact once and then it stops checking.. Please help.
import pygame
import random
caught_egg = False
a = 0
egg_radius = 15
x_egg = 0
y_egg = 5 + egg_radius
x_star = []
y_star = []
x_pos = 200
y_pos = 650
x_speed = 5
x_size = 100
y_size = 70
red = [255, 0, 0]
white = [255, 255, 255]
black = [0,0,0]
yellow = [255, 255, 0]
cyan = [0, 255, 255]
magenta = [255, 0, 255]
beige = [245,245,220]
wheat = [245,222,179]
egg_color_choices = [beige,wheat]
WINDOW_HEIGHT = 800
WINDOW_WIDTH = 500
pygame.init() # initializes the graphics module
window = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT)) # define window size
pygame.display.set_caption('Egg Catcher') # title of program that
# appears on window
# frame
def InitSky(amount):
for i in range (0, amount):
x_star.append(random.randint(2, 495))
y_star.append(random.randint(2, 795))
def DrawSky(amount):
for i in range(0, amount):
pygame.draw.circle(window, white, (x_star[i], y_star[i]), 2, )
y_star[i] = y_star[i] + 1
if y_star[i] > WINDOW_HEIGHT:
y_star[i] = 0
def InitEgg():
x_egg = random.randint(1 + egg_radius, WINDOW_WIDTH - egg_radius)
return(x_egg)
def EggColor():
egg_color = random.choice(egg_color_choices)
return(egg_color)
def DrawEgg():
pygame.draw.circle(window, egg_color, (x_egg, y_egg), egg_radius,)
x_egg = InitEgg()
egg_color = EggColor()
# your code that draws to the window goes here
clock = pygame.time.Clock() # used to track time within the game (FPS)
quit = False
pygame.key.set_repeat(1)
while not quit: # main program loop
for event in pygame.event.get(): # check if there were any events
if event.type == pygame.QUIT: # check if user clicked the upper
quit = True # right quit button
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x_pos = x_pos + x_speed
if event.key == pygame.K_LEFT:
x_pos = x_pos - x_speed
if x_pos <= 0:
x_pos = x_pos + x_speed
if x_pos + x_size >= 500:
x_pos = x_pos - x_speed
if event.key == pygame.K_KP_MINUS:
x_speed = x_speed - 1
if event.key == pygame.K_KP_PLUS:
x_speed = x_speed + 1
if x_speed >= 8:
x_speed = x_speed - 1
if x_speed <= 4:
x_speed = x_speed + 1
window.fill(black)
InitSky(500)
DrawSky(500)
caught_egg = False
if caught_egg == False:
DrawEgg()
if y_egg - egg_radius <= WINDOW_HEIGHT and caught_egg == False:
y_egg = y_egg + 3
else:
y_egg = 0
x_egg = InitEgg()
if x_egg + egg_radius > x_pos and x_egg + egg_radius < x_pos + x_size and y_egg - egg_radius == y_pos:
caught_egg = True
y_egg = 0
x_egg = InitEgg()
print(y_egg)
pygame.draw.rect(window, magenta, (x_pos, y_pos, x_size, y_size))
pygame.display.update() # refresh your display
clock.tick(60) # wait a certain amount of time that
# ensures a frame rate of 60 fps
pygame.quit() # shutdown module
It's because of this condition: y_egg - egg_radius == y_pos. You start from 20 the first time (5 + egg_radius) so when you hit 665 that condition triggers. But then you reset y_egg to 0 instead of 20 so you never align on the exact condition again.
You could just replace the two y_egg = 0 resets by y_egg = 5 + egg_radius, but a better fix would be to detect if the egg geometry is contained in the bucket in the y-dimension as you do for the x:
if x_egg + egg_radius > x_pos and \
x_egg + egg_radius < x_pos + x_size and \
y_egg - egg_radius >= y_pos and \
y_egg + egg_radius <= y_pos + y_size:
caught_egg = True
y_egg = 0
x_egg = InitEgg()
Actually your x logic is only checking if the right edge is inside the bucket but I'll leave that for you to fix.
Related
This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I'm making a game environment for NEAT. The first two obstacles seem to collide with the players just fine, but none of the other obstacles do anything. The visuals won't work, but based on the size of the player list, yeah no it's not working. The collide class also wouldn't work before I started implementing NEAT, so there's that.
Anyway here's some (probably) irrelevant code:
import pygame
from pygame.locals import *
import random
import os
import neat
debugfun = 0
W = 300
H = 300
win = pygame.display.set_mode((W, H))
pygame.display.set_caption("bruv moment")
coords = [0, 60, 120, 180, 240]
class Player(object):
def __init__(self, x):
self.x = x
self.y = 600 - 60
self.width = 60
self.height = 60
self.pos = 0
self.left = False
self.right = False
def move(self):
if self.left:
self.pos -= 1
if self.right:
self.pos += 1
if self.pos < 0:
self.pos = 4
if self.pos > 4:
self.pos = 0
self.x = coords[self.pos]
class Block(object):
def __init__(self, pos, vel):
self.pos = pos
self.x = coords[self.pos]
self.y = -60
self.width = 60
self.height = 60
self.vel = vel
def move(self):
self.y += self.vel
def redraw_window():
pygame.draw.rect(win, (0, 0, 0), (0, 0, W, H))
for ob in obs:
pygame.draw.rect(win, (0, 255, 0), (ob.x, ob.y, ob.width, ob.height))
for ind in homies:
pygame.draw.rect(win, (255, 0, 0), (ind.x, ind.y, ind.width, ind.height))
pygame.display.update()
obs = []
homies = []
player_collision = False
ge = []
nets = []
And here's some relevant code:
def collide():
for ob in obs:
for x, ind in enumerate(homies):
if ind.y < ob.y + ob.height and ind.y + ind.height > ob.y and ind.x + ind.width > ob.x and ind.x < ob.x + ob.width:
ge[x].fitness -= 1
homies.pop(x)
nets.pop(x)
ge.pop(x)
def main(genomes, config):
speed = 30
pygame.time.set_timer(USEREVENT + 1, 550)
pygame.time.set_timer(USEREVENT + 2, 1000)
for _, g in genomes:
net = neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
homies.append(Player(0))
g.fitness = 0
ge.append(g)
clock = pygame.time.Clock()
ran = True
while ran and len(homies) > 0:
clock.tick(27)
collide()
for x, ind in enumerate(homies):
ind.move()
ge[x].fitness += 0.1
try:
output = nets[x].activate((ind.x, abs(obs[0].x - ind.x)))
except IndexError:
output = 50
try:
if output in range(5, 25):
ind.left = True
else:
ind.left = False
if output > 25:
ind.right = True
else:
ind.right = False
except TypeError:
if output[0] in range(5, 25):
ind.left = True
else:
ind.left = False
if output[1] > 25:
ind.right = True
else:
ind.right = False
for ob in obs:
ob.move()
if ob.x > H:
obs.pop(obs.index(ob))
for event in pygame.event.get():
if event.type == pygame.QUIT:
ran = False
pygame.quit()
if event.type == USEREVENT+1:
if speed <= 200:
speed += 3
if event.type == USEREVENT+2:
for g in ge:
g.fitness += 0.5
if len(obs) == 0:
obs.append(Block(round(random.randint(0, 4)), speed))
print(len(homies))
print(len(obs))
redraw_window()
def run(config_file):
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet,
neat.DefaultStagnation, config_path)
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main, 50)
if __name__ == "__main__":
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, "avoidpedofiles.txt")
run(config_path)
I'm trying to recreate a game of pong just for fun.
Here is my full code as of right now.
import pygame, random, math
pygame.init()
#colours:-------------------------------------------------------------
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
WHITE = (255, 255, 255)
GREEN = (39, 133, 20)
YELLOW = (252, 252, 25)
BLACK = (0, 0, 0)
BLUE = (30, 100, 225)
RED = (255,0,0)
RANDOM_COLOR = (R, B, G)
#Surface:-------------------------------------------------------------
width = 700
height = 600
size = (width, height)
screen = pygame.display.set_mode(size)
screen_rect = screen.get_rect()
pygame.display.set_caption("Pong Remake")
background = pygame.image.load("background.png").convert()
background = pygame.transform.scale(background, (width, height))
logo = pygame.image.load("logo.png").convert()
logo.set_colorkey((BLACK))
credits = pygame.image.load("credits.png")
credits.set_colorkey((BLACK))
#variables:-----------------------------------------------------------
clock = pygame.time.Clock()
done = False
text = pygame.font.Font(None,25)
display_instructions = True
instruction_page = 1
start_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF", 35)
instruction_font = pygame.font.Font(None, 17)
win_lose_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF",50)
score = pygame.font.Font(None, 100)
bounce = pygame.mixer.Sound("bounce.wav")
playerOne_score = 0
playerTwo_score = 0
playerOne = ""
playerTwo = ""
x = 350
y = 300
ball_rect = pygame.Rect(x,y,10,10)
paddleOne_rect = pygame.Rect(10, 250, 20, 60)
paddleTwo_rect = pygame.Rect(670, 250, 20, 60)
x_speed = random.randrange(5, 10)
y_speed = random.randrange(5,10)
def draw_background(screen, pic, x,y):
screen.blit(pic, (x,y))
#main loop
#INPUT v ---------------------------------------------------------
#Start Page
while not done and display_instructions:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 2:
display_instructions = False
#Shows the start of the page
if instruction_page == 1:
draw_background(screen, logo, 100,-150)
draw_background(screen, credits, 100,50)
instruction_text = instruction_font.render("How to Play. The objective to this game is to score the ball on the other side before the opponent can.", False, WHITE)
instruction_text_three = instruction_font.render("First Player to get 10 points wins, Have Fun and Good Luck!", False, WHITE)
instruction_text_two = instruction_font.render("For Player One, use the a and the z keys to move up and down, For Player Two, use the k and m keys.", False, WHITE)
continue_text= start_font.render("Click to Play...",True, WHITE)
screen.blit(continue_text, [200, 400])
screen.blit(instruction_text, [0,500])
screen.blit(instruction_text_three, [0,532])
screen.blit(instruction_text_two,[0,516])
if instruction_page == 2:
display_instructions = False
clock.tick(60)
pygame.display.flip()
while not done:
click = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
click = True
#INPUT ^ =========================================================
#PROCESS v -------------------------------------------------------
str(playerOne_score)
str(playerTwo_score)
scoreOne = text.render("Player One:" + str(playerOne_score), False, WHITE)
scoreTwo = text.render("Player Two:" + str(playerTwo_score), False, WHITE)
#moves paddles with keys on keyboar
key = pygame.key.get_pressed()
if key[pygame.K_a]: paddleOne_rect.move_ip(0, -10)
if key[pygame.K_z]: paddleOne_rect.move_ip(0, 10)
if key[pygame.K_k]: paddleTwo_rect.move_ip(0, -10)
if key[pygame.K_m]: paddleTwo_rect.move_ip(0, 10)
#makes sure paddles stay on screen
paddleOne_rect.clamp_ip(screen_rect)
paddleTwo_rect.clamp_ip(screen_rect)
ball_rect.move_ip(x_speed, y_speed)
if ball_rect.y + ball_rect.height> screen_rect.height or ball_rect.y < 0:
y_speed = y_speed * -1
bounce.play()
if ball_rect.collidelist([paddleOne_rect, paddleTwo_rect]) > -1:
x_speed = -x_speed
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
bounce.play()
if ball_rect.x >= 700:
x_speed * -1
playerOne_score += 1
pygame.display.flip
if ball_rect.x <= 0:
x_speed * -1
playerTwo_score += 1
#PROCESS ^ =======================================================
#DRAWING GOES BELOW HERE v ------------------------------------
draw_background(screen, background, 0,0)
screen.blit(scoreOne, (0,0))
screen.blit(scoreTwo, (500,0))
pygame.draw.ellipse(screen, WHITE,ball_rect )
pygame.draw.rect(screen,RANDOM_COLOR, paddleOne_rect)
pygame.draw.rect(screen,RANDOM_COLOR, paddleTwo_rect)
pygame.draw.line(screen, WHITE, (350,0),(350,700), 1)
#DRAWING GOES ABOVE HERE ^ ------------------------------------
pygame.display.flip()
clock.tick(60)
pygame.quit()
What I am currently having problems with at the moment is when the ball goes off the screen, I want it to go back to the middle again as someone has scored a point. But I'm a bit stuck on what to do.
If you guys can help me out, that would be amazing!!
There is a lot of code here, so this does not follow specific variables you used, but I hope this helps.
1) Find the width of you screen
2) Take the x and y coordinates that you use to know where to draw the ball
3) Make an if statement that essentially says
(pseudocode)
if x > 1000
score1 += 1
x = 500
if x < 0
score2 += 1
x = 500
``
I hope this can set you on the right track, and I suggest checking out the pygame docs.
Cheers!
So I was cleaning up my code by adding in classes, in order to put certain tools that I will be using in my game, into other files. SO as I was kinda learning and implementing, I stumbled upon an easy error that I can't find out for the life of me.
So I have my core.py and pyWMouse.py in the same folder. My pyWMouse.py just has my mouse tools that I created. I keep getting this error:
Traceback (most recent call last):
File "G:/Python/pygameDevelopment/core.py", line 115, in <module>
game_Loop()
File "G:/Python/pygameDevelopment/core.py", line 100, in game_Loop
if userMouse.MouseLeftClickDown and userMouse.MouseDrag:
AttributeError: type object 'MouseTools' has no attribute 'MouseLeftClickDown'
Here is the class in pyWMouse.py
import pygame
COLOR_RED = (255, 0, 0)
class MouseTools:
def __init__(self):
self.MouseInitXY = (0, 0)
self.MouseFinalXY = (0, 0)
self.MouseLeftClickDown = False
self.MouseRightClickDown = False
self.MouseDrag = False
self.CharacterSelected = False
self.CharacterMove = False
self.CharacterMoveTo = (0, 0)
def selection(self, screen, unitX, unitY):
# Draw lines #
pygame.draw.lines(screen, COLOR_RED, True, ((self.MouseInitXY[0], self.MouseInitXY[1]),
(self.MouseFinalXY[0], self.MouseInitXY[1]),
(self.MouseFinalXY[0], self.MouseFinalXY[1]),
(self.MouseInitXY[0], self.MouseFinalXY[1])), 3)
# Check if anything is inside the selection area from any direction the mouse highlights #
if unitX >= self.MouseInitXY[0] and unitX <= self.MouseFinalXY[0] and unitY >= \
self.MouseInitXY[1] and unitY <= self.MouseFinalXY[1]:
return True
elif unitX <= self.MouseInitXY[0] and unitX >= self.MouseFinalXY[0] and unitY <= \
self.MouseInitXY[1] and unitY >= self.MouseFinalXY[1]:
return True
elif unitX >= self.MouseInitXY[0] and unitX <= self.MouseFinalXY[0] and unitY <= \
self.MouseInitXY[1] and unitY >= self.MouseFinalXY[1]:
return True
elif unitX <= self.MouseInitXY[0] and unitX >= self.MouseFinalXY[0] and unitY >= \
self.MouseInitXY[1] and unitY <= self.MouseFinalXY[1]:
return True
else:
return False
And finally my core.py
import pygame
import pyWMouse
pygame.init()
pygame.display.set_caption('PyWorld')
DISPLAY_WIDTH = 1080
DISPLAY_HEIGHT = 920
COLOR_BLACK = (0, 0, 0)
COLOR_BROWN = (100, 50, 0)
COLOR_GREEN = (0, 102, 0)
COLOR_RED = (255, 0, 0)
COLOR_WHITE = (255, 255, 255)
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
fpsClock = pygame.time.Clock()
class Character:
def __init__(self, XPos, YPos): # Always called when object is created, always have self variable #
self.X = XPos
self.Y = YPos
self.ImageUnselected = pygame.image.load('mainChar.png')
self.ImageSelected = pygame.image.load('mainCharSelected.png')
self.Speed = 2.5
self.YChange = 0
self.XChange = 0
def render_Unselected(self):
screen.blit(self.ImageUnselected, (self.X, self.Y))
def render_Selected(self):
screen.blit(self.ImageSelected, (self.X, self.Y))
class Worker:
def __init__(self, XPos, YPos):
self.X = XPos
self.Y = YPos
self.ImageUnselected = pygame.image.load('worker.png')
self.ImageSelected = pygame.image.load('workerSelected.png')
def worker_Unselected(self):
screen.blit(self.ImageUnselected, (self.X, self.Y))
def worker_Selected(self):
screen.blit(self.ImageSelected, (self.X, self.Y))
character = Character(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2)
userMouse = pyWMouse.MouseTools
def game_Loop():
gameExit = False
while not gameExit:
screen.fill(COLOR_BROWN)
# Keyboard Handling #
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_w]:
character.YChange = -character.Speed
if keys_pressed[pygame.K_a]:
character.XChange = -character.Speed
if keys_pressed[pygame.K_s]:
character.YChange = character.Speed
if keys_pressed[pygame.K_d]:
character.XChange = character.Speed
if keys_pressed[pygame.K_w] and keys_pressed[pygame.K_a]:
character.XChange = (-character.Speed/1.5)
character.YChange = (-character.Speed/1.5)
if keys_pressed[pygame.K_a] and keys_pressed[pygame.K_s]:
character.XChange = (-character.Speed / 1.5)
character.YChange = (character.Speed / 1.5)
if keys_pressed[pygame.K_s] and keys_pressed[pygame.K_d]:
character.XChange = (character.Speed / 1.5)
character.YChange = (character.Speed / 1.5)
if keys_pressed[pygame.K_d] and keys_pressed[pygame.K_w]:
character.XChange = (character.Speed / 1.5)
character.YChange = (-character.Speed / 1.5)
# Event handling #
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key != pygame.K_a or event.key != pygame.K_d:
character.XChange = 0
if event.key != pygame.K_w or event.key != pygame.K_s:
character.YChange = 0
# Mouse Handling #
if event.type == pygame.MOUSEBUTTONDOWN:
if userMouse.CharacterSelected:
userMouse.CharacterSelected = False
if event.button == 1:
userMouse.MouseLeftClickDown = True
userMouse.MouseInitXY = pygame.mouse.get_pos()
if event.button == 2:
userMouse.MouseRightClickDown = True
userMouse.CharacterMoveTo = pygame.mouse.get_pos()
if event.type == pygame.MOUSEMOTION:
userMouse.MouseDrag = True
if event.type == pygame.MOUSEBUTTONUP:
if userMouse.MouseLeftClickDown:
userMouse.MouseLeftClickDown = False
userMouse.MouseDrag = False
if event.type == pygame.QUIT:
pygame.quit()
quit()
# Mouse Tools #
if userMouse.MouseLeftClickDown and userMouse.MouseDrag:
userMouse.MouseFinalXY = pygame.mouse.get_pos()
# Check if user's character is inside selection tool #
if userMouse.selection(screen, character.X, character.Y):
character.render_Selected()
else:
character.render_Unselected()
else:
character.render_Unselected()
# Update Display and next frame variables #
character.X += character.XChange
character.Y += character.YChange
pygame.display.update()
fpsClock.tick(144)
game_Loop()
pygame.quit()
quit()
Thanks for your time everyone. Much appreciated.
I believe the problem can be found in core.py. Try changing :
userMouse = pyWMouse.MouseTools
to the following:
userMouse = pyWMouse.MouseTools()
Adding the missing parentheses should do the trick.
I'm a student and this game is one of my task. when the player win or loose, pressanykeytostart() doesn't work. however in the beginning it works. Also I get this error massage (Pygame Error: Video System not Initialized) every time I play.
How can I add a Pause function in my game?
###########################Set up the screen, background image and sound
import random,pygame,sys,math
pygame.init()
from pygame.locals import*
WIDTH = 600
HEIGHT = 600
TEXTCOLOR = (255, 255, 255)
Yellow = (255, 255, 0)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Pacman')
pygame.mouse.set_visible(False)
background_image = pygame.image.load('leaves.jpg')
backgroundmusic = pygame.mixer.Sound('lost.wav')
backgroundmusic.play()
##################################################Set up the score font
font_name = pygame.font.match_font('arial')
def draw_text(surf, text, size, x, y):
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, Yellow)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
###################################################SET UP the images and Sound
pacman = pygame.sprite.Sprite()
ghost = pygame.sprite.Sprite()
eatingsound = pygame.mixer.Sound('pacman_eatfruit.wav')
pacman.image = pygame.image.load('pacman1.png')
pacman.rect = pacman.image.get_rect()
pacman_group = pygame.sprite.GroupSingle(pacman)
over_image = pygame.image.load('game.jpg')
deathsound = pygame.mixer.Sound('pacman_death.wav')
##################################################press a key to start
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
return
def drawText(text, font, surface, x, y):
screen.blit(background_image, (0,0))
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
screen.blit(textobj, textrect)
font = pygame.font.SysFont(None, 48)
drawText('Pacman Game', font, screen, (WIDTH / 3), (HEIGHT / 3))
drawText('Press a key to start.', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
######################################Adding Ghost in different position with different speed
class Ghost(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('ghost.png')
self.rect = self.image.get_rect()
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
def update(self):
self.rect.y += self.speedy
if self.rect.top > HEIGHT + 10:
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
all_sprites = pygame.sprite.Group()
ghosts = pygame.sprite.Group()
for i in range(2):
g = Ghost()
all_sprites.add(g)
ghosts.add(g)
#################################################### Adding the Coins
TILE_SIZE = pacman.rect.width
NUM_TILES_WIDTH = WIDTH / TILE_SIZE
NUM_TILES_HEIGHT = HEIGHT / TILE_SIZE
candies = pygame.sprite.OrderedUpdates()
for i in range(50):
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('coin.png')
candy.rect = candy.image.get_rect()
candy.rect.left = random.uniform(0, NUM_TILES_WIDTH - 1) * TILE_SIZE
candy.rect.top = random.uniform(0, NUM_TILES_HEIGHT - 1) * TILE_SIZE
candies.add(candy)
###########################################Game Loop
score = 0
pause = False
gameOver = False
running = True
win = False
while running :
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.QUIT:
running = False
###########################################Move the pacman
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
pacman.rect.top -= TILE_SIZE
elif event.key == pygame.K_DOWN:
pacman.rect.top += TILE_SIZE
elif event.key == pygame.K_RIGHT:
pacman.rect.right += TILE_SIZE
elif event.key == pygame.K_LEFT:
pacman.rect.right -= TILE_SIZE
##############################################Keep the pacman on the screen
if pacman.rect.left < 0:
pacman.rect.left = 0
elif pacman.rect.right > 600:
pacman.rect.right = 600
elif pacman.rect.top <= 0:
pacman.rect.top = 0
elif pacman.rect.bottom >= 600:
pacman.rect.bottom = 600
###############################################Able to use mouse
if event.type == MOUSEMOTION:
pacman.rect.move_ip(event.pos[0] - pacman.rect.centerx, event.pos[1] - pacman.rect.centery)
###############################################Adding coins randomly
if event.type == pygame.USEREVENT:
if win == False:
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('coin.png')
candy.rect = candy.image.get_rect()
candy.rect.left = random.uniform(0, NUM_TILES_WIDTH - 1) * TILE_SIZE
candy.rect.top = random.uniform(0, NUM_TILES_HEIGHT - 1) * TILE_SIZE
candies.add(candy)
################################################Collecting the coins and set the score
collides = pygame.sprite.groupcollide(pacman_group, candies, False, True)
if len(collides) > 0:
eatingsound.play()
score += 1
if len(candies) == 0:
win = True
screen.blit(background_image, (0,0))
#################################################Wining the game
if win:
drawText('You Win!', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
winingsound = pygame.mixer.Sound('applause3.wav')
winingsound.play()
backgroundmusic.stop()
waitForPlayerToPressKey()
##################################################################### Game Over screen
candies.draw(screen)
pacman_group.draw(screen)
all_sprites.draw(screen)
draw_text(screen, str(score), 18, WIDTH / 2, 10)
pygame.display.flip()
all_sprites.update()
hits = pygame.sprite.spritecollide(pacman, ghosts, False)
if hits:
gameOver = True
if gameOver == True:
drawText('Game Over!', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
drawText('Press a key to start again.', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
deathsound.play()
backgroundmusic.stop()
waitForPlayerToPressKey()
#############################################Drwing everything on the screen
pygame.quit()
Try with pygame.time.wait(time)
Or Pygame.event.wait (). The first wait the amount of time in brakets, and the second wait until a new event received.
I can not figure out how to generate the food for the snake to eat. I know the position of the snake at line 97 and 98, I have created a class to generate a pixel where I want to draw a peace of food at line 22 (EDIT: should probably be a function, commented #def (?) in the code). All I have to do is add 15 pixels at the x and y coordinates from the position that is randomly allocated and print it to get a block.
The problem is to check if I eat it or not. It should be something like:
if x >= x_food && x <= x_food + 15 || y >= y_food && y <= y_food + 15:
...add a point and make snake longer...
The problem is putting it all together for some reason.. Can some one give me a hint or solve how I should write this class so I can continue with other problems? Thank you!
import pygame
import random
#Global variables
#Color
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
#Start length of snake
snake_length = 3
#Set the width of the segments of the snake
segment_width = 15
segment_height = 15
# Margin within each segment
segment_margin = 3
#Set initial speed
x_change = segment_width + segment_margin
y_change = 0
#def (?)
class Food():
#Class to print food
x_food = random.randint(0, 785)
y_food = random.randint(0, 585)
class Segment(pygame.sprite.Sprite):
""" Class to represent the segment of the snake. """
# Methods
# Constructer function
def __init__(self, x, y):
#Call the parents constructor
super().__init__()
#Set height, width
self.image = pygame.Surface([segment_width, segment_height])
self.image.fill(WHITE)
#Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#Call this function so the Pygame library can initialize itself
pygame.init()
#Create an 800x600 size screen
screen = pygame.display.set_mode([800, 600])
#Set the title of the window
pygame.display.set_caption("Snake")
allspriteslist = pygame.sprite.Group()
#Create an initial snake
snake_segments = []
for i in range(snake_length):
x = 250 - (segment_width + segment_margin) * i
y = 30
segment = Segment(x, y)
snake_segments.append(segment)
allspriteslist.add(segment)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#Set the speed based on the key pressed
#We want the speed to be enough that we move a full
#Segment, plus the margin
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = (segment_width + segment_margin) * -1
y_change = 0
if event.key == pygame.K_RIGHT:
x_change = (segment_width + segment_margin)
y_change = 0
if event.key == pygame.K_UP:
x_change = 0
y_change = (segment_height + segment_margin) * -1
if event.key == pygame.K_DOWN:
x_change = 0
y_change = (segment_width + segment_margin)
#Get rid of last segment of the snake
#.pop() command removes last item in list
old_segment = snake_segments.pop()
allspriteslist.remove(old_segment)
#Figure out where new segment will be
x = snake_segments[0].rect.x + x_change
y = snake_segments[0].rect.y + y_change
segment = Segment(x, y)
#Insert new segment to the list
snake_segments.insert(0, segment)
allspriteslist.add(segment)
#Draw
#Clear screen
screen.fill(BLACK)
allspriteslist.draw(screen)
#Flip screen
pygame.display.flip()
#Pause
clock.tick(5)
pygame.quit()
i took your code and i think i work something out, pls note that this only monitors when the snake goes over the block, then it prints: yummy, so you will have to add the detail, also note that i dont use your class to generate the food:
import pygame
import random
#Global variables
#Color
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
#Start length of snake
snake_length = 3
#Set the width of the segments of the snake
segment_width = 15
segment_height = 15
# Margin within each segment
segment_margin = 3
#Set initial speed
x_change = segment_width + segment_margin
y_change = 0
#def (?)
class Food():
#Class to print food
x_food = random.randint(0, 785)
y_food = random.randint(0, 585)
class Segment(pygame.sprite.Sprite):
""" Class to represent the segment of the snake. """
# Methods
# Constructer function
def __init__(self, x, y):
#Call the parents constructor
super().__init__()
#Set height, width
self.image = pygame.Surface([segment_width, segment_height])
self.image.fill(WHITE)
#Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
#Call this function so the Pygame library can initialize itself
pygame.init()
#Create an 800x600 size screen
screen = pygame.display.set_mode([800, 600])
#Set the title of the window
pygame.display.set_caption("Snake")
allspriteslist = pygame.sprite.Group()
#Create an initial snake
snake_segments = []
for i in range(snake_length):
x = 250 - (segment_width + segment_margin) * i
y = 30
segment = Segment(x, y)
snake_segments.append(segment)
allspriteslist.add(segment)
clock = pygame.time.Clock()
done = False
x_food = random.randint(0, 785)
y_food = random.randint(0, 585)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
#Set the speed based on the key pressed
#We want the speed to be enough that we move a full
#Segment, plus the margin
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = (segment_width + segment_margin) * -1
y_change = 0
if event.key == pygame.K_RIGHT:
x_change = (segment_width + segment_margin)
y_change = 0
if event.key == pygame.K_UP:
x_change = 0
y_change = (segment_height + segment_margin) * -1
if event.key == pygame.K_DOWN:
x_change = 0
y_change = (segment_width + segment_margin)
if y < y_food+30:
if x > x_food and x < x_food+30 or x+20 > x_food and x+20<x_food+30:
print('yummy')
#Get rid of last segment of the snake
#.pop() command removes last item in list
old_segment = snake_segments.pop()
allspriteslist.remove(old_segment)
#Figure out where new segment will be
x = snake_segments[0].rect.x + x_change
y = snake_segments[0].rect.y + y_change
segment = Segment(x, y)
#Insert new segment to the list
snake_segments.insert(0, segment)
allspriteslist.add(segment)
#Draw
#Clear screen
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, [x_food, y_food, 30, 30])
allspriteslist.draw(screen)
#Flip screen
pygame.display.flip()
#Pause
clock.tick(5)
pygame.quit()
hope this helped, thanks!
if x >= x_food && x <= x_food + 15 || y >= y_food && y <= y_food + 15:
Why do you OR these pairs of conditions? Don't all 4 tests have to be true at the same time?
if x >= x_food && x <= x_food + 15 && y >= y_food && y <= y_food + 15:
how about using:
if snake_headx == foodx and snake_heady == foody:
food_eated()
snake_grow()
just a suggestion though
didnt read all ur code, just thought u might find it usefull.
actuely ive came to a solution, so basicly what you want is a square, and when the snake comes near that square something should happen?, well ive got a racegame that makes you crash when you hit a square car, so il just copy the code here:
if y < thing_starty+thing_height:
if x > thing_startx and x < thing_startx+thing_width or x+car_width > thing_startx and x+car_width<thing_startx+thing_width:
snake_eated()
snake_grow()
this monitors the x and y of your car (or snake) and checks when the thing (or food) 's y is smaller than your car, then it checks the x's and alot of other things, and basicly it creates a big line all around your square that you cannot cross in your case you'd just need to add the rest, would this work?
Make your food a sprite with a simple filled rectangle as the image, and then use sprite collision pygame.sprite.spritecollide() to check if your snake collides with your food. Pygame will take care of the actual logic whether two rectangles overlap for you.
Also, since you are already using sprite groups, I suggest you write an update function for your snake segments which moves them instead of creating a new segment every turn. Then you can simply call allspriteslist.update() in your main game loop, which will call the update function for every snake segment.
Finally, you might want to have a look at the numerous snake examples on the pygame website.