PyGame detecting collisions even though they are not happening [duplicate] - python

This question already has an answer here:
Why is my collision test always returning 'true' and why is the position of the rectangle of the image always wrong (0, 0)?
(1 answer)
Closed 2 years ago.
I want to make a Snake game in Python but when I want to detect collision with rects, it seems the game detects collisions even though they are not happening:
if snake_rect.colliderect(jablko_rect):
print("Mniam!")
This collision check prints out text infinitely. How can it print out text when obviously these 2 separate objects are not touching each other. It's not a while loop problem I think. The collision check is for the images which are 49 x 49 px
The whole code:
import random
import pygame
from time import sleep
pygame.init()
SZEROKOSC = 800
WYSOKOSC = 600
plansza = pygame.display.set_mode((SZEROKOSC, WYSOKOSC)) # rozmiar okna gry
pygame.display.update()
pygame.display.set_caption("Snake") # tytuł okna gry
KROK = 25 # o ile "kroków" ma się przemieszczać snake
snake = pygame.image.load("snake_element.png").convert() # nasz snake
jablko = pygame.image.load("apple.png").convert() # nasze jabłko
snake_rect = snake.get_rect()
jablko_rect = jablko.get_rect()
clock = pygame.time.Clock()
czcionka = pygame.font.SysFont(None, 50)
def wiadomosc(msg, color):
wiad = czcionka.render(msg, True, color)
plansza.blit(wiad, [SZEROKOSC / 2 - 100, WYSOKOSC / 2 - 25])
def petla_gry():
przegrana = False
zamkniecie = False
x1 = SZEROKOSC / 2 # koordynaty
y1 = WYSOKOSC / 2 # koordynaty
x1_zmiana = 0
y1_zmiana = 0
jablko_x = round(random.randrange(0, SZEROKOSC - 25) / 25.0) * 25.0 # 25 to połowa rozmiaru naszych obrazków
jablko_y = round(random.randrange(0, WYSOKOSC - 25) / 25.0) * 25.0 # 25 to połowa rozmiaru naszych obrazków
print(jablko_x)
print(jablko_y)
while not przegrana:
while zamkniecie:
plansza.fill(white)
wiadomosc("Przegrałeś! Q - wyjście z gry, C - restart gry", (255, 0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
przegrana = True
zamkniecie = False
if event.key == pygame.K_c:
petla_gry()
for event in pygame.event.get():
if event.type == pygame.QUIT:
przegrana = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
x1_zmiana = -KROK
y1_zmiana = 0
elif event.key == pygame.K_d:
x1_zmiana = KROK
y1_zmiana = 0
elif event.key == pygame.K_w:
x1_zmiana = 0
y1_zmiana = -KROK
elif event.key == pygame.K_s:
x1_zmiana = 0
y1_zmiana = KROK
if x1 >= SZEROKOSC or x1 <= 0 or y1 >= WYSOKOSC or y1 <= 0:
przegrana = True
wiadomosc("Przegrałeś!", (255, 0, 0))
pygame.display.update()
sleep(2)
x1 += x1_zmiana
y1 += y1_zmiana
plansza.fill((255, 255, 255))
plansza.blit(snake, (x1 - 25, y1 - 25)) # 25 to połowa rozmiaru naszych obrazków
plansza.blit(jablko, (jablko_x, jablko_y))
pygame.display.update()
if snake_rect.colliderect(jablko_rect):
print("Mniam!")
'''if x1 == jablko_x and y1 == jablko_y:
print("Mniam!")'''
clock.tick(8) # czas odświeżania - ruch snake'a
pygame.quit()
quit()
petla_gry()

pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.
The Surface is placed at a position on the display with the blit function.
You've to set the location of the rectangle,, e.g:
snake_rect.topleft = (x1 - 25, y1 - 25)
jablko_rect.topleft = (jablko_x, jablko_y)
if snake_rect.colliderect(jablko_rect):
print("Mniam!")

Related

Python Snake doesn't grow [duplicate]

This question already has an answer here:
How do I get the snake to grow and chain the movement of the snake's body?
(1 answer)
Closed 1 year ago.
I'm new to python and only now the basics, I'm trying to make a snake game but I can't seem to figure out how to make my snake grow 1 extra square each time it eats an apple. My reasoning is that I keep a list of all the old positions but only show the last one on the screen, and each time the snakes eats another apple it shows 1 extra old positions making the snake 1 square longer.
This is my code:
import pygame
from random import randint
WIDTH = 400
HEIGHT = 300
dis = pygame.display.set_mode((WIDTH,HEIGHT))
white = (255,255,255)
BACKGROUND = white
blue = [0,0,255]
red = [255,0,0]
class Snake:
def __init__(self):
self.image = pygame.image.load("snake.bmp")
self.rect = self.image.get_rect()
self.position = (10,10)
self.direction = [0,0]
self.positionslist = [self.position]
self.length = 1
pygame.display.set_caption('Snake ')
def draw_snake(self,screen):
screen.blit(self.image, self.position)
def update(self):
self.position = (self.position[0] + self.direction[0],self.position[1] + self.direction[1])
self.rect = (self.position[0],self.position[1],5, 5 )
self.positionslist.append(self.position)
if self.position[0]< 0 :
self.position = (WIDTH,self.position[1])
elif self.position[0] > WIDTH:
self.position = (0,self.position[1])
elif self.position[1] > HEIGHT:
self.position = (self.position[0],0)
elif self.position[1] < 0 :
self.position = (self.position[0],HEIGHT)
class Food:
def __init__(self):
self.image = pygame.image.load("appel.png")
self.rect = self.image.get_rect()
apple_width = -self.image.get_width()
apple_height = -self.image.get_height()
self.position = (randint(0,WIDTH+apple_width-50),randint(0,HEIGHT+apple_height-50))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
def draw_appel(self,screen):
screen.blit(self.image, self.position)
def eat_appel (self, snake):
if self.rect.colliderect(snake.rect) == True:
self.position = (randint(0,WIDTH),randint(0,HEIGHT))
self.rect.x = self.position[0]
self.rect.y = self.position[1]
snake.length += 1
def main():
game_over = False
while not game_over:
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
snake = Snake()
food = Food()
while True:
screen.fill(BACKGROUND)
font = pygame.font.Font('freesansbold.ttf', 12)
text = font.render(str(snake.length), True, red, white)
textRect = text.get_rect()
textRect.center = (387, 292)
screen.blit(text,textRect)
snake.update()
#snake.update_list()
snake.draw_snake(screen)
food.draw_appel(screen)
food.eat_appel(snake)
pygame.display.flip()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
snake.direction = [0,1]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
snake.direction = [1,0]
if event.key == pygame.K_LEFT:
snake.direction = [-1,0]
if event.key == pygame.K_UP:
snake.direction = [0,-1]
if event.key == pygame.K_DOWN:
snake.direction = [0,1]
if __name__ == "__main__":
main()
This can have multiple reasons. Firstly, I saw you tried to increase the length of the snake by typing snake.length += 1, which may work (probably won't because the module pygame allows the snake to hover around, but not like the loop or conditional statements). One of my tips would be, to increase the length of the snake by using the idea of adding the score with your present snake.length every time (because once your score is 1 by eating an apple, your snake.length would be 2. And it increases with the score). This is my code (a few modifications might be needed):
import pygame
import time
import random
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
orange = (255, 165, 0)
width, height = 600, 400
game_display = pygame.display.set_mode((width, height))
pygame.display.set_caption("Snake Mania")
clock = pygame.time.Clock()
snake_size = 10
snake_speed = 15
message_font = pygame.font.SysFont('ubuntu', 30)
score_font = pygame.font.SysFont('ubuntu', 25)
def print_score(score):
text = score_font.render("Score: " + str(score), True, orange)
game_display.blit(text, [0,0])
def draw_snake(snake_size, snake_pixels):
for pixel in snake_pixels:
pygame.draw.rect(game_display, white, [pixel[0], pixel[1], snake_size, snake_size])
def run_game():
game_over = False
game_close = False
x = width / 2
y = height / 2
x_speed = 0
y_speed = 0
snake_pixels = []
snake_length = 1
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
while not game_over:
while game_close:
game_display.fill(black)
game_over_message = message_font.render("Game Over!", True, red)
game_display.blit(game_over_message, [width / 3, height / 3])
print_score(snake_length - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
game_over = True
game_close = False
if event.key == pygame.K_2:
run_game()
if event.type == pygame.QUIT:
game_over = True
game_close = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_speed = -snake_size
y_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = snake_size
y_speed = 0
if event.key == pygame.K_UP:
x_speed = 0
y_speed = -snake_size
if event.key == pygame.K_DOWN:
x_speed = 0
y_speed = snake_size
if x >= width or x < 0 or y >= height or y < 0:
game_close = True
x += x_speed
y += y_speed
game_display.fill(black)
pygame.draw.rect(game_display, orange, [target_x, target_y, snake_size, snake_size])
snake_pixels.append([x, y])
if len(snake_pixels) > snake_length:
del snake_pixels[0]
for pixel in snake_pixels[:-1]:
if pixel == [x, y]:
game_close = True
draw_snake(snake_size, snake_pixels)
print_score(snake_length - 1)
pygame.display.update()
if x == target_x and y == target_y:
target_x = round(random.randrange(0, width - snake_size) / 10.0) * 10.0
target_y = round(random.randrange(0, height - snake_size) / 10.0) * 10.0
snake_length += 1
clock.tick(snake_speed)
pygame.quit()
quit()
run_game()

pygame function only works once, doesn't loop

I have a pause menu for a game im working on for school. If the user clicks 'p' it launches the pause menu. And the pause menu has a function that if a user clicks a button the user will be launched back into the game. Problem is after they are launched into the game the 'p' function to pause doesn't work anymore. I'm not sure if i looped it correctly.
the pong game
import pygame
black = (0,0,0)
white = (255,255,255)
pygame.init()
size = 800,600
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Basketball Shootout")
done = False
clock = pygame.time.Clock()
def player1(x1, y1, xsize, ysize):
pygame.draw.rect(screen, black, [x1, y1, xsize, ysize])
def player2(x2, y2, xsize, ysize):
pygame.draw.rect(screen, black, [x2,y2,xsize,ysize])
def ball(ballx, bally):
pygame.draw.circle(screen, black, [ballx,bally],20)
def Score1(score1):
font = pygame.font.Font("Minecraft.ttf" ,50)
text = font.render(str(score1), True, white)
screen.blit(text, [160, 550])
def Score2(score2):
font = pygame.font.Font("Minecraft.ttf" ,50)
text = font.render(str(score2), True, white)
screen.blit(text, [610, 550])
x1 = 20
y1 = 175
xsize = 35
ysize = 150
speed1 = 0
x2 = 740
y2 = 175
speed2 = 0
ballx = 550
bally = 250
speedx = 8
speedy = 5
score1 = 0
score2 = 0
bg = pygame.image.load("pongbg2.png")
rect1 = pygame.Rect(50,510,100,50)
def pausescreen():
import pausescreen
display_game = True
game_page = 1
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.draw.rect(screen, (255, 255, 255), rect1)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
speed1 = -10
if event.key == pygame.K_s:
speed1 = 10
if event.key == pygame.K_UP:
speed2 = -10
if event.key == pygame.K_DOWN:
speed2 = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
speed1 = 0
if event.key == pygame.K_s:
speed1 = 0
if event.key == pygame.K_UP:
speed2 = 0
if event.key == pygame.K_DOWN:
speed2 = 0
if event.key == pygame.K_p:
pausescreen()
screen.blit(bg, (0, 0))
player1(x1, y1, xsize, ysize)
player2(x2, y2, xsize, ysize)
ball(ballx,bally)
Score1(score1)
Score2(score2)
y1 += speed1
y2 += speed2
ballx += speedx
bally += speedy
if y1 < 0:
y1 = 0
if y1 > 350:
y1 = 350
if y2 < 0:
y2 = 0
if y2 > 350:
y2 = 350
if ballx+20 > x2 and bally-20 > y2 and bally+20 < y2+ysize and ballx < x2+3:
speedx = -speedx
if ballx-20 < x1+35 and bally-20 > y1 and bally+20 < y1+ysize and ballx > x1+38:
speedx = -speedx
if bally > 477 or bally < 23:
speedy = -speedy
if ballx < 13:
score2 += 1
ballx = 350
bally = 250
if ballx > 750:
score1 += 1
ballx = 350
bally = 250
pygame.display.flip()
clock.tick(60)
pygame.quit()
now here is my pause menu code.
import pygame
import sys
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the height and width of the screen
size = [800, 600 ]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Basketball Shootout")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
#Rectangles
rect1 = pygame.Rect(300,300,205,80)
rect2 = pygame.Rect(300,400,205,80)
#Font
font3 = pygame.font.Font("Minecraft.ttf", 40)
def playerpong():
import playerpong
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
pygame.draw.rect(screen, GREEN, rect1)
pygame.draw.rect(screen, RED, rect2)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if rect1.collidepoint(event.pos):
playerpong()
if rect2.collidepoint(event.pos):
pygame.quit()
clock.tick(60)
pygame.display.update()
pygame.quit()
The problem is that you are importing your pause screen from another program which creates a problem as you can import a library only once. You can try to put your pause screen code in the function instead of calling it but if you insist, you can put your pause_screen code in a function and do a from pausescreen import name_of_function so whenever you need to call that code just write name_of_funtion()

Python sprite not moving when key is held down

I'm working on the basics of a game right now, but for some reason I cannot get my sprite to move. I know that it's registering when I'm pressing the key down, but the sprite for some reason just stays still.
import pygame
import sys
from pygame.locals import *
import time
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("RADICAL")
screen.fill(black)
imga = pygame.image.load('coina.png')
imgb = pygame.image.load('coinb.png')
sound = pygame.mixer.Sound('coin.mp3')
FPS = 80
imgx = 10
imgy = 10
pixMove = 10
steps = 0
x1 = 0
y1 = 0
keystate = pygame.key.get_pressed()
GameOver = False
while not GameOver:
screen.fill(white)
points = (steps)
font = pygame.font.SysFont(None, 30)
text = font.render('Score: '+str(points), True, black)
screen.blit(text, (0,0))
if steps % 2 == 0:
screen.blit(imga, (imgx, imgy))
else:
screen.blit(imgb, (imgx, imgy))
for event in pygame.event.get():
print event
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if keystate[pygame.K_UP]:
y1 -= pixMove
elif keystate[pygame.K_DOWN]:
y1 += pixMove
elif keystate[pygame.K_LEFT]:
x1 -= pixMove
elif keystate[pygame.K_RIGHT]:
x1 += pixMove
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x1 = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y1 = 0
steps +=1
if event.type == K_SPACE:
sound.play()
time.sleep(1)
sound.stop()
pygame.display.update()
fpsTime.tick(FPS)
Generally you blit() images on to the screen (pygame.display.set_mode()), for the changes to to reflect on the screen we call pygame.display.update(), In your case the game never comes the statement, which is out of while loop.

Pygame Sprite doesn't reset

I am making a platformer type game but I have run into two problems.
My Sprite is confined to a small box in the centered in the window. How do I make it so he can cover the entire window?
When I move the old sprite is not removed. It make it appear that there is a tail following the sprite.
Help for either would be appreciated!
import random, sys, copy, os, pygame, time, math
from pygame.locals import *
TILESIZE = 20
WINDOWWIDTH = 1280
WINDOWHEIGHT = 720
FPS = 30
floorx = (WINDOWHEIGHT - (TILESIZE))
floory = (WINDOWWIDTH / TILESIZE)
TileOffset = 20
tilesNeeded = (WINDOWWIDTH / TILESIZE)
floorSize = TILESIZE * 2
OUTSIDE_DECORATION_PCT = 20
HALF_WINDOWHEIGHT = (WINDOWHEIGHT / 2)
HALF_WINDOWWIDTH = (WINDOWWIDTH / 2)
CAMERASLACK = 25
MOVERATE = 9
BOUNCERATE = 6
BOUNCEHEIGHT = 30
INVULTIME = 2
GAMEOVERTIME = 4
MAXHEALTH = 3
STARTSIZE = 30
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
LIGHTGRAY = (174, 174, 174)
DARKGRAY = ( 41, 41, 41)
MEDGRAY = (101, 101, 101)
SKYBLUE = (200, 210, 255)
DARKTURQUOISE = ( 3, 54, 73)
GREEN = ( 0, 92, 7)
LIGHTGREEN = ( 0, 135, 15)
BGCOLOR = LIGHTGRAY
TEXTCOLOR = BLACK
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, TILESIZE, floorx, floory, floorCovered, tilesNeeded, OUTSIDEDECOMAPPING, L_Monster, R_Monster, BGIMAGE
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
FPSCLOCK = pygame.time.Clock()
pygame.display.set_caption('Alpha One')
# Set up the background image.
boardImage = pygame.image.load('bg.png')
# Use smoothscale() to stretch the board image to fit the entire board:
boardImageRect = boardImage.get_rect()
boardImageRect.topleft = (0, 0)
BGIMAGE = pygame.image.load('bg.png')
# Use smoothscale() to stretch the background image to fit the entire window:
BGIMAGE = pygame.transform.smoothscale(BGIMAGE, (WINDOWWIDTH, WINDOWHEIGHT))
BGIMAGE.blit(boardImage, boardImageRect)
#Draw the background
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
#Draw the Floor
drawFloor()
L_Monster = pygame.image.load('monster.png')
L_Monster = pygame.transform.scale(L_Monster, (1000, 600))
R_Monster = pygame.transform.flip(L_Monster, True, False)
pygame.display.flip()
#Main Game Loop
while True:
runGame()
#pygame.display.update()
def runGame():
invulnerableMode = False
invulnerableStartTime = 0
gameOverMode = False
gameOverStartTime = 0
winMode = False
camerax = 0
cameray = 0
playerObj = {'surface': pygame.transform.scale(L_Monster,(STARTSIZE, STARTSIZE)),
'facing': LEFT,
'size': STARTSIZE,
'x': HALF_WINDOWWIDTH,
'y': HALF_WINDOWHEIGHT,
'bounce':0,
'health': MAXHEALTH}
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
while True:
DISPLAYSURF.blit(BGIMAGE, BGIMAGE.get_rect())
drawFloor()
#DISPLAYSURF.fill(WHITE)
if invulnerableMode and time.time() - invulnerableStartTime > INVULNTIME:
invulnerableMode = False
playerCenterx = playerObj['x'] + int(playerObj['size'] / 2)
playerCentery = playerObj['y'] + int(playerObj['size'] / 2)
if (camerax + HALF_WINDOWWIDTH) - playerCenterx > CAMERASLACK:
camerax = playerCenterx + CAMERASLACK - HALF_WINDOWWIDTH
elif playerCenterx - (camerax +HALF_WINDOWWIDTH) > CAMERASLACK:
camerax = playerCenterx - CAMERASLACK - HALF_WINDOWWIDTH
if (cameray + HALF_WINDOWHEIGHT) - playerCentery > CAMERASLACK:
cameray = playerCentery + CAMERASLACK - HALF_WINDOWHEIGHT
elif playerCentery - (cameray +HALF_WINDOWHEIGHT) > CAMERASLACK:
cameray = playerCentery - CAMERASLACK - HALF_WINDOWHEIGHT
flashIsOn = round(time.time(), 1) * 10 % 2 == 1
if not gameOverMode and not (invulnerableMode and flashIsOn):
playerObj['rect'] = pygame.Rect((playerObj['x'] - camerax,
playerObj['y'] - cameray - getBounceAmount(playerObj['bounce'], BOUNCERATE, BOUNCEHEIGHT),
playerObj['size'],
playerObj['size']))
DISPLAYSURF.blit(playerObj['surface'], playerObj['rect'])
for event in pygame.event.get():
if event.type == QUIT:
terminate()
elif event.type == KEYDOWN:
if event.key in (K_UP, K_w):
moveDown = False
moveUp = True
elif event.key in (K_DOWN, K_s):
moveUp = False
moveDown = True
elif event.key in (K_LEFT, K_a):
moveRight = False
moveLeft = True
if playerObj['facing'] == RIGHT:
playerObj['surface'] = pygame.transform.scale(L_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] == LEFT
elif event.key in (K_RIGHT, K_d):
moveLeft = False
moveRight = True
if playerObj['facing'] == LEFT:
playerObj['surface'] = pygame.transform.scale(R_Monster, (playerObj['size'], playerObj['size']))
playerObj['facing'] = RIGHT
elif winMode and event.key == K_r:
return
elif event.type == KEYUP:
if event.key in (K_LEFT, K_a):
moveLeft = False
elif event.key in (K_RIGHT, K_d):
moveRight = False
elif event.key in (K_UP, K_w):
moveUp = False
elif event.key in (K_DOWN, K_s):
moveDown = False
elif event.key == K_ESCAPE:
terminate()
if not gameOverMode:
if moveLeft:
playerObj['x'] -= MOVERATE
if moveRight:
playerObj['x'] += MOVERATE
if moveUp:
playerObj['y'] -= MOVERATE
if moveDown:
playerObj['y'] += MOVERATE
if (moveLeft or moveRight or moveUp or moveDown) or playerObj['bounce'] != 0:
playerObj['bounce'] += 1
if playerObj['bounce'] > BOUNCERATE:
playerObj['bounce'] = 0
else:
# game is over, show "game over" text
DISPLAYSURF.blit(gameOverSurf, gameOverRect)
if time.time() - gameOverStartTime > GAMEOVERTIME:
return
if winMode:
DISPLAYSURF.blit(winSurf, winRect)
DISPLAYSURF.blit(winSurf2, winRect2)
pygame.display.update()
FPSCLOCK.tick(FPS)
def getBounceAmount(currentBounce, bounceRate, bounceHeight):
return int(math.sin( (math.pi / float(bounceRate)) * currentBounce ) * bounceHeight)
def getRandomOffCameraPos(camerax, cameray, objWidth, objHeight):
# create a Rect of the camera view
cameraRect = pygame.Rect(camerax, cameray, WINDOWWIDTH, WINDOWHEIGHT)
while True:
x = random.randint(camerax - WINDOWWIDTH, camerax + (2 * WINDOWWIDTH))
y = random.randint(cameray - WINDOWHEIGHT, cameray + (2 * WINDOWHEIGHT))
# create a Rect object with the random coordinates and use colliderect()
# to make sure the right edge isn't in the camera view.
objRect = pygame.Rect(x, y, objWidth, objHeight)
if not objRect.colliderect(cameraRect):
return x, y
def isOutsideActiveArea(camerax, cameray, obj):
boundsLeftEdge = camerax - WINDOWWIDTH
boundsTopEdge = cameray - WINDOWHEIGHT
boundsRect = pygame.Rect(boundsLeftEdge, boundsTopEdge, WINDOWWIDTH * 3, WINDOWHEIGHT * 3)
objRect = pygame.Rect(obj['x'], obj['y'], obj['width'], obj['height'])
return not boundsRect.colliderect(objRect)
def checkForQuit():
for event in pygame.event.get(QUIT): # get all the QUIT events
terminate() # terminate if any QUIT events are present
for event in pygame.event.get(KEYUP): # get all the KEYUP events
if event.key == K_ESCAPE:
terminate() # terminate if the KEYUP event was for the Esc key
pygame.event.post(event)
def drawFloor():
#Open the image used for tiles and initialize N
floorTile = pygame.image.load('tile.png')
N = 0
while (N < tilesNeeded):
DISPLAYSURF.blit(floorTile,((20 * N, (floorx + (TILESIZE/4)) - TILESIZE)), )
DISPLAYSURF.blit(floorTile,(20 * N, (floorx + (TILESIZE/4))))
N = N + 1
#Updates the display
pygame.display.flip()
def checkCollide():
FLOOR_SURF = pygame.Rect( 0, (WINDOWHEIGHT - (TILESIZE * 2)), WINDOWWIDTH, WINDOWHEIGHT)
def terminate():
pygame.quit()
sys.exit()
if __name__ == '__main__':
main()
The reason you're getting the "tail" of your sprite is because you're not clearing the screen before you begin drawing a new frame. One way to handle this would be to enter something like the following at the beginning of runGame():
DISPLAYSURF.fill(white)
This will "clear" the surface by covering everything in white. When you begin drawing images for that frame, they will be drawn over a blank white surface. The caveat to this is that you will need to redraw every sprite on the screen, not just the ones that have moved in the last frame.
For the first question, if you're asking how to scale the size of the image, you would use the scale function from pygame.transform
L_monster = pygame.transform.scale(L_monster, (500, 500))
This creates a new surface by transforming the given surface to the new size given by the tuple.
http://www.pygame.org/docs/ref/transform.html#pygame.transform.scale

Pygame Arrow Control

I am wondering why is it that when I execute the file,
the arrow control and movement of the left rectangle will not continuously move up or down, even though I am holding down on the arrow keys for a long time.
import pygame
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
pygame.init()
size = [700,500]
screen = pygame.display.set_mode(size)
fonto = pygame.font.SysFont("algerian", 100)
font = pygame.font.SysFont("algerian", 12)
text = fonto.render("Game Over", True, (0, 128, 10))
pygame.display.set_caption("Vasanths First Legit Game")
done = False
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
score = 1
rect_x = 50
rect_y = 50
rect_xp = 10
rect_yp = 10
rect_change_x = 10
rect_change_y = 10
rect_change_xp = 10
rect_change_yp = 3
while done == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done=True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
rect_yp = rect_change_yp+rect_yp
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
rect_yp = 0+rect_yp
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
rect_yp=-3+rect_yp
if event.key == pygame.K_RIGHT:
rect_yp=3+rect_yp
if event.key == pygame.K_UP:
rect_yp=-3+rect_yp
if event.key == pygame.K_DOWN:
rect_yp=3+rect_yp
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
rect_yp=0+rect_yp
if event.key == pygame.K_RIGHT:
rect_yp=0+rect_yp
if event.key == pygame.K_UP:
rect_yp=0+rect_yp
if event.key == pygame.K_DOWN:
rect_yp=0+rect_yp
pos = pygame.mouse.get_pos()
x = pos[0]
y = pos[1]
screen.fill(black)
pygame.draw.rect(screen,white,[rect_x,rect_y,10,10])
pygame.draw.rect(screen,green,[x,490,50,10])
pygame.draw.rect(screen,green,[10,rect_yp,10,50])
# Move the rectangle starting point
rect_x += rect_change_x
rect_y += rect_change_y
if rect_y == 0:
rect_change_x=rect_change_x*1
rect_change_y=rect_change_y*-1
if rect_y == 490:
if rect_x < x + 50 :
scoref = font.render(score, True, (0, 128, 0))
screen.blit(scoref,
(20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10))
rect_change_x=rect_change_x*1
rect_change_y=rect_change_y*-1
if rect_x < x:
rect_change_y = 0
rect_change_x = 0
#dont do this , it will go bizzonkes
score = str(score)
score = int(score)
if rect_y == 490:
if rect_x < x + 50 :
if rect_change_x !=0:
if rect_change_y !=0:
score=int(score)
score = score + 1
score=str(score)
if rect_change_x == 0:
if rect_change_y == 0:
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
if rect_x == 700:
rect_change_x = rect_change_x*-1
rect_change_y = rect_change_y*1
if rect_x == 0:
rect_change_x = rect_change_x*0
rect_change_y = rect_change_y*0
if rect_y == 500:
rect_change_y = 0
rect_change_x = 0
screen.blit(text,
(320 - text.get_width() // 2, 240 - text.get_height() // 2))
score=str(score)
print(score)
score = str(score)
scoref = font.render(score, True, (0, 128, 0))
screen.blit(scoref,
(20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10))
clock.tick(30)
pygame.display.flip()
pygame.quit ()
In pygame the input is handled in a event loop. There is a event queue, the system sends input from the keyboard, and by calling pygame.event.get() you get the first event in the queue. There are many types of events, the most popular being KEYUP and KEYDOWN.
The mistake that most beginner people make, is that they believe that when a button is pressed, a KEYDOWN event is sent the whole time. That is not needed, since if you press a button, it is pressed until you release it. So you need to have certain flags to see if a button is pressed.
The most popular way of doing this is by using a d = v*t equation. Since the speed is constant, we need to introduce a direction. So our equation would look like this:
distance_changed = direction * speed * time_change
In your event loop, you then change the direction:
1 if KEYDOWN-RIGHT
-1 if KEYDOWN-LEFT
0 if KEYUP-LEFTorRIGHT.
Now the question might pop up, why use time_change? Since, we cannot predict on which machines the program will work, the amount of times the loop will repeat will not be known.
If you take an old machine, the game will work much slower. So we measure the time taken from the last movement, so that it will not changed on different machines.
I have see that you use pygame.tick(30), which waits so that the time it took for the loop to finish was constant. The problem arises, when you run this at an older machine. The loop cannot speed up.
As a suggestion, you should divide you game into functions. It's much more readable, and you can use you code in different places. Also, your event loop, has to many ifs. Use elif since there is no point to check if RIGTH key was pressed if LEFT was already pressed.
This is how I handle it in one of my own Pygame projects:
class Inputs:
def __init__(self):
self.bindings = {"up": pygame.K_UP,
"down": pygame.K_DOWN,
"left": pygame.K_LEFT,
"right": pygame.K_RIGHT,
"lp": pygame.K_a,
"mp": pygame.K_s,
"hp": pygame.K_d,
"lk": pygame.K_z,
"mk": pygame.K_x,
"hk": pygame.K_c,
"pause": pygame.K_RETURN}
self.inputState = {"up": False,
"down": False,
"right": False,
"left": False,
"lp": False,
"mp": False,
"hp": False,
"lk": False,
"mk": False,
"hk": False,
"pause": False}
self.buffer = InputBuffer()
def lookupBinding(self, keyEntered):
for binding, keyBound in self.bindings.items():
if keyEntered == keyBound:
return binding
return "not found"
def getInputState(self, events):
for event in events:
if event.type == pygame.KEYDOWN:
binding = self.lookupBinding(event.key)
if binding != "not found":
newInput = Input()
newInput.inputName = binding
newInput.timeSinceInput = 0
self.buffer.push(newInput)
self.inputState[binding] = True
if event.type == pygame.KEYUP:
binding = self.lookupBinding(event.key)
if binding != "not found":
self.inputState[binding] = False
return self.inputState
I keep two dictionaries, one of in-game "commands", such as directions, to the pygame key, then another of those commands to a boolean representing the command's on/off state. By watching for KEYDOWN and KEYUP events, I can determine which mapped inputs are on and which are off.
EDIT: A benefit of this way method that I should mention is that it makes it very easy to change the key mapping later on, or even allow custom key-mappings. Your game logic only needs to rely on the basic inputs, such as a jump or move input, and won't need to change if the key-mappings change.
I would use pygame.key.get_pressed(), but you are also forgetting pygame.key.set_repeat(). The first argument is the # of milliseconds it takes to start repeating, and the second is the interval at which the key repeats.
This is an example which uses both:
x = 400
y = 300
import pygame, sys
bkg = (255, 211, 0)
clr = (0, 0, 0)
squ = (8, 11, 134)
pygame.init()
size = (800, 600)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Bloxy")
pygame.key.set_repeat(1, 1)
font = pygame.font.SysFont("Stencil", 20)
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_LEFT]:
x -= 5
if keys_pressed[pygame.K_RIGHT]:
x += 5
if keys_pressed[pygame.K_UP]:
y -= 5
if keys_pressed[pygame.K_DOWN]:
y += 5
if x > 800:
x = 0
if x < 0:
x = 800
if y > 600:
y = 0
if y < 0:
y = 600
screen.fill(bkg)
text = font.render('(' + str(x) + ',' + str(y) + ')', True, clr)
screen.blit(text, [10, 10])
pygame.draw.rect(screen, squ, [x - 10, y - 10, 20, 20])
pygame.display.flip()
clock.tick(60)

Categories

Resources