Pygame collideRect precion issue [duplicate] - python

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 am trying to write a pygame program where the user dodges objects falling from the top of the screen. However, when I run, collideRect activates too early. Any suggestions?
import pygame
import sys
import time
import random
pygame.init()
size = width, height = 500, 500
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Avalanche!")
character = pygame.image.load("C:/Python27/Lib/site-packages/StickBasic.png")
boulder = pygame.image.load("C:/Python27/Lib/site-packages/Boulder1.png")
charRect = character.get_rect()
charRect.left = 246
charRect.bottom = 450
running = True
skyBlue = 0, 255, 255
groundBrown = 100, 0, 0
direction = 0
timer = 0
boulderFrequency = 20
boulders = []
def endgame():
global running
running = False
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
def bg():
screen.fill(skyBlue)
pygame.draw.rect(screen, groundBrown, (0, 450, 500, 500))
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
if charRect.left > 0:
direction = -1
elif event.key == pygame.K_RIGHT:
if charRect.right < 500:
direction = 1
elif event.type == pygame.KEYUP:
direction = 0
if (direction < 0) and (charRect.left > 0):
charRect.left -= 1
if (direction > 0) and (charRect.right < 500):
charRect.left += 1
if timer >= boulderFrequency:
timer = 0
newBoulder = {
'rect': pygame.Rect(random.randint(0, 460), -40, 40, 40),
'surface': boulder}
boulders.append(newBoulder)
bg()
for b in boulders:
b['rect'].move_ip(0, 5)
if b['rect'].top > 500:
boulders.remove(b)
for b in boulders:
screen.blit(b['surface'], b['rect'])
screen.blit(character, charRect)
pygame.display.flip()
timer += 1
for b in boulders:
if charRect.colliderect(b['rect']):
endgame()
time.sleep(0.02)
PS: I know that the coding is not very clean, but I am relatively knew to coding.

Related

How to make "player health" decrease when it collides with an enemy sprite in pygame [duplicate]

This question already has answers here:
Updating text in pygame
(1 answer)
Creating a self-updating score
(1 answer)
Closed 23 days ago.
I made a surface for the player health and drew it on the screen. Then I made an if statement checking to see if the player X position was == to the enemy X position and if it was the player health would continuously decrease. I know it was decreasing because I was having it print out the player health afterwards in the console and everything was good but the health on the screen would not change. What am I doing wrong?
I am a newbie at pygame and a beginner in python therefore my code is not written in the best way...
Sorry the code is very long but the # should show everything...
import pygame
from sys import exit
from time import sleep
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1200, 535))
background = pygame.image.load("background1.jpg")
background = pygame.transform.rotozoom(background, 0, 2)
# Player
player_surf = pygame.image.load("player_sprites/player_right.png").convert_alpha()
player_rect = player_surf.get_rect(bottomright = (575, 470))
player_surf = pygame.transform.rotozoom(player_surf, 0, 2.5).convert_alpha()
# Health...
health = 50
health_font = pygame.font.Font('Pixeltype.ttf', 50)
health_display = health_font.render(f"Health {health}", True, (0, 0, 0))
# Enemy #1
enemy1_surf = pygame.image.load("enemy1sprites/enemy1_right.png").convert_alpha()
enemy1_rect = enemy1_surf.get_rect(bottomleft = (1100, 462))
enemy1_surf = pygame.transform.rotozoom(enemy1_surf, 0, 2.5).convert_alpha()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(background, (0, 0))
screen.blit(player_surf, player_rect)
screen.blit(enemy1_surf, enemy1_rect)
screen.blit(health_display, (550, 75))
# Player Movement
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_surf = pygame.image.load("player_sprites/player_left.png")
player_surf = pygame.transform.rotozoom(player_surf, 0, 2.5)
player_rect.x -= 4
if event.key == pygame.K_RIGHT:
player_surf = pygame.image.load("player_sprites/player_right.png")
player_surf = pygame.transform.rotozoom(player_surf, 0, 2.5)
player_rect.x += 4
if player_rect.x >= 1075:
player_rect.x = 1075
elif player_rect.x <= 0:
player_rect.x = 0
wave_one = True
# Enemy 1 AI
if player_rect.x != enemy1_rect.x:
if player_rect.x > enemy1_rect.x:
enemy1_surf = pygame.image.load("enemy1sprites/enemy1_right.png")
enemy1_surf = pygame.transform.rotozoom(enemy1_surf, 0, 2.5)
enemy1_rect.x += 1
elif player_rect.x < enemy1_rect.x:
enemy1_surf = pygame.image.load("enemy1sprites/enemy1_left.png")
enemy1_surf = pygame.transform.rotozoom(enemy1_surf, 0, 2.5)
enemy1_rect.x -= 1
# Collision with enemy
if player_rect.x == enemy1_rect.x:
health -= 0.005
print(health)
pygame.display.update()
clock.tick(60)
I expected it to continuously update the health_display but It did not.
Have you tried updating / re-rendering the text on screen? From your code, it appears that the health is only printed when updated, not shown in the game.

I need to spam the "C" Button until the Game Restarts [duplicate]

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 4 months ago.
Hello i need to programm a Game with pygame for school. I nearly finish the Game but when i want to Press the "C" button in the Gameover loop then nothing happends and the game will not restart.
unti i spam the "C" Button. I dont think that there is a problem with the detection of pressing the button because i made a print command thatalways prints something when i press the "C" Button and it always print something out.
I hope you can help me with the Problem :)
from turtle import pos
import pygame
import time
from pygame.locals import *
import random
pygame.init()
dis_width = 600
dis_height = 400
pos_x = 303
pos_y = 370
x_change = 0
y_change = 0
enemie_pos_x = random.randint(180, 420)
enemie_pos_y = 30
clock = pygame.time.Clock()
screen=pygame.display.set_mode((dis_width, dis_height))
font_style = pygame.font.SysFont("bahnschrift", 25)
time_font = pygame.font.SysFont("bahnschrift", 25)
running=True
obj = False
obj2 = False
enemie = False
game_over = False
crash = True
start = time.time() + 0.1
tolleranz = 40
speed = 5
timer = 5
score = 0
displayscore = 0
highscore = 0
ROT = (255, 0, 0)
BLACK = (0, 0, 0)
pygame.display.update()
def stopwatch(time):
value = time_font.render("Time: " + str(time), True, ROT)
screen.blit(value, [0, 0])
value2 = time_font.render("Score: " + str(score), True, ROT)
screen.blit(value2, [0, 30])
value6 = time_font.render("HighScore: " + str(highscore), True, ROT)
screen.blit(value6, [0, 60])
def enemies():
counter = 1
global enemie_pos_x, enemie_pos_y, speed, aTimeRound, timer, displayscore, highscore
enemie_pos_y += speed
if aTimeRound > timer:
speed += 5
timer += 5
if enemie_pos_y > 430:
enemie_pos_y = 0
enemie_pos_x = random.randint(180, 420)
global score
score += 1
if highscore <= score:
if highscore != score:
highscore += 1
displayscore = score
def gameoverF():
global score, start, speed, timer, game_over, displayscore, highscore
screen.fill(BLACK)
value3 = time_font.render("GAMEOVER", True, ROT)
screen.blit(value3, [230, 100])
value6 = time_font.render("Score:" + str(displayscore), True, ROT)
screen.blit(value6,[230, 150])
value4 = time_font.render("Highscore: " + str(highscore), True, ROT)
screen.blit(value4,[225, 200])
value5 = time_font.render("Press 'C' to play again OR Press 'Q' to Quit", True, ROT)
screen.blit(value5,[70,250])
score = 0
start = time.time()
speed = 5
timer = 5
pygame.display.update()
while running:
while game_over == True:
for event in pygame.event.get(): # Bei jeden GameLoop die Liste an Events abfragen
if event.type == pygame.QUIT:
running = False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # Prüfen, ob der Eventtyp ein Tastendruck ist
if event.key == ord("c"): # Prüfen, ob die Cursor-Links-Taste gedrückt wurde...
game_over = False
speed = 5
timer = 5
score = 0
print("GEDRÜCKT!!!!!!!")
if event.key == ord("q"):
pygame.quit()
gameoverF()
#Messung der Zeit
aTime = time.time()-start
aTimeRound = round(time.time()-start,1)
#print(aTime)
#Malen der Steuer Kugel und der Linien
pos_x += x_change
screen.fill(BLACK)
pygame.draw.line(screen, ROT, (150,0),(150,400), 10)
pygame.draw.line(screen, ROT, (450,0),(450,400), 10)
pygame.draw.circle(screen, [255,255,255],(pos_x,pos_y), 25)
stopwatch(aTimeRound)
enemies()
pygame.draw.circle(screen, [255,255,255],(enemie_pos_x,enemie_pos_y), 25)
#print( enemie_pos_x - pos_x)
check_x = pos_x - enemie_pos_x
if check_x < 0:
check_x = check_x * -1
print(check_x)
if check_x < tolleranz and pos_y - enemie_pos_y < tolleranz:
game_over = True
clock.tick(30)
if pos_x <= 192:
pos_x = 192
if pos_x >= 410:
pos_x = 410
for event in pygame.event.get(): # Bei jeden GameLoop die Liste an Events abfragen
if event.type == pygame.QUIT:
running = False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN: # Prüfen, ob der Eventtyp ein Tastendruck ist
if event.key == pygame.K_LEFT or event.key == ord("a"): # Prüfen, ob die Cursor-Links-Taste gedrückt wurde...
x_change = -10
y_change = 0 # Aktion bei Cursor-Links
if event.key == pygame.K_RIGHT or event.key == ord("d"):
x_change = 10
y_change = 0
pygame.display.update()
gameoverF()
Played your game got highscore of 22 oh I mean I read the code and and I debugged it
Well actually playing was the debugging haha. The problem is that after you press C game restarts as it should but the enemy which hit you is not removed and it instantly kills you again and moves tiny bit lower. By spamming C you move it out of screen and game continues
Simple fix to reset enemy pose when C is pressed
if event.key == ord("c"):
enemie_pos_y = 30 # Reset enemy pose
Keep up the good work!

Slowly decrement variable with timer?

I've got a variable that increases when the user presses a button.
When the user presses another button, I'd like to set that variable to 0,
but not instantly-- I'd like it to tick down over the course of a few seconds.
During this time I'd like the user to be able to perform other actions-- hence why I'm not using sleep.
I've looked at using pygame's events, time.clock, etc., but I can't seem to get this to work. Here is what I've tried so far:
import pygame, sys, math
from pygame.locals import *
pygame.init()
pygame.font.init()
scrw = 640
scrh = 480
screen = pygame.display.set_mode((scrw, scrh))
ttwist = 0
recentering = False
fps = 15
clock = pygame.time.Clock()
my_font = pygame.font.SysFont("arial", 12)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed = pygame.key.get_pressed()
if not recentering:
if pressed[pygame.K_d]:
ttwist +=1
if pressed[pygame.K_a]:
ttwist -=1
RECENTERTORSOEVENT = USEREVENT
if event.type == pygame.KEYDOWN and event.key == pygame.K_BACKSLASH:
recentering = True
pygame.time.set_timer(RECENTERTORSOEVENT, 1000*abs(ttwist))
if ttwist == 0:
recentering = False
if event.type == USEREVENT:
if ttwist < 0:
ttwist += 1
elif ttwist > 0:
ttwist -= 1
drawtext = my_font.render("TTWIST:"+str(ttwist), True, (255,255,255),(0,0,0))
screen.blit(drawtext,(10,130))
pygame.display.update()
clock.tick(fps)
What am i doing wrong?
You are on the right track, but some parts of the code need to be changed:
All the if event.type == ... blocks should be inside of the event loop.
RECENTERTORSOEVENT = USEREVENT should be defined above the while loop (but that doesn't cause problems).
You're setting the time interval for the RECENTERTORSOEVENT way too high: 1000*abs(ttwist). That means, if the ttwist is 10, you're setting it to 10.000 ms (10 seconds). Just set it to a constant value like 100 ms.
When the ttwist is recentered, call pygame.time.set_timer(RECENTERTORSOEVENT, 0) to stop the timer.
Fill the screen each frame screen.fill((30, 30, 30)), otherwise you see artifacts because the font surface keeps changing its size.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
my_font = pygame.font.SysFont('arial', 22)
clock = pygame.time.Clock()
ttwist = 0
RECENTERTORSOEVENT = pygame.USEREVENT
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
print('recentering')
# Start to add the USEREVENT every 100 ms.
pygame.time.set_timer(RECENTERTORSOEVENT, 100)
elif event.type == RECENTERTORSOEVENT:
ttwist += 1 if ttwist < 0 else -1
if ttwist == 0:
print('done')
# Stop to add the USEREVENT to the queue.
pygame.time.set_timer(RECENTERTORSOEVENT, 0)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_d]:
ttwist += 1
if pressed[pygame.K_a]:
ttwist -= 1
screen.fill((30, 30, 30))
drawtext = my_font.render(
'TTWIST: {}'.format(ttwist), True, (255, 255, 255))
screen.blit(drawtext, (10, 130))
pygame.display.update()
clock.tick(30)
ttwist += 1 if ttwist < 0 else -1 is a conditional expression and does basically the same as:
if ttwist < 0:
ttwist += 1
elif ttwist > 0:
ttwist -= 1

2D pinball mask collisions? [duplicate]

This question already has answers here:
Pygame collision with masks
(1 answer)
How can I rotate my hitbox with my rotating and moving car in pygame?
(1 answer)
python pygame mask collision [closed]
(1 answer)
Pygame mask collision
(1 answer)
Closed 2 years ago.
I am currently developing a 2d pinball game in python using the pygame library, I opted for the mask collision detection, here is a link to a post where it's well explained:
2D Collision detection for Pinball Game
I think I did everything but it's not working as wanted .
Here is my code for the physiscs of the ball:
from math import *
from Constants import *
def Getcolor(ballx,bally,screen,resources):
screen.blit(resources["CollisionMain"], (220, 0))
color=screen.get_at((ballx,bally))
colore=color[1]
return colore
def UpdateBall(ball,color):
ballx=ball[1][0]
bally=ball[1][1]
lastpos = ball[1][0], ball[1][1]
velocity=ball[2]
if -FRICTION_BALL <= velocity <= FRICTION_BALL :
velocity = 0
else:
velocity += FRICTION_BALL if velocity < 0 else -FRICTION_BALL
ball[2] = velocity
ball[1][0] += velocity
vectorx = sin(color / 255 * 2 * pi)
vectory = cos(color / 255 * 2 * pi)
if ballx+Ball_width<screen_width:
ballx=screen_width-Ball_width
if (bally+Ball_len)>screen_lenght:
bally=screen_lenght-Ball_len
#ball[1][1] -= 10
else:
if color == 255:
ball[1][1] += Gravity
else:
ball[1][0],ball[1][1]=lastpos
ball[1][0] += vectorx
ball[1][1] += vectory
def DrawBall(screen,ball,resources):
screen.blit(ball[0],(ball[1][0],ball[1][1]))
and here is my game engine code:
import pygame
import sys
from pygame.locals import *
from Constants import *
from ball import *
def Init():
pygame.init()
screen = pygame.display.set_mode((screen_width,screen_lenght))
pygame.display.set_caption('Supinball')
pygame.key.set_repeat(150,150)
pygame.mixer.init(44100, -16, 2, 1024)
return screen
def LoadResources():
resources= dict()
resources["MainLayer"] = pygame.image.load("resources/images/main_layer.png")
resources["Ball"] = pygame.image.load("resources/images/Ball.png")
resources["CollisionMain"] = pygame.image.load("resources/images/collision_main.png")
resources["CollisionSpec"] = pygame.image.load("resources/images/collision_special.png")
resources["Rflipper"] = pygame.image.load("resources/images/right_flipper.png")
resources["Lflipper"] = pygame.image.load("resources/images/left_flipper.png")
resources["Spring"] = pygame.image.load("resources/images/spring.png")
resources["Music"] = pygame.mixer.Sound("resources/sounds/music.ogg")
resources["Coin"] = pygame.mixer.Sound("resources/sounds/Coin.wav")
resources["Hit"] = pygame.mixer.Sound("resources/sounds/hit.wav")
resources["Tilted"] = pygame.mixer.Sound("resources/sounds/tilted.wav")
resources["GameOver"] = pygame.mixer.Sound("resources/sounds/GameOver.ogg")
resources["Font"] = pygame.font.Font('resources/Vdj.ttf', 30)
return resources
def GameLoop(screen,resources):
gameRunning = True
ball = [resources["Ball"],[300,20],0]
fpsClock = pygame.time.Clock()
while gameRunning:
ev = GetEvent(ball)
gameRunning = ev[GAME_RUNNING]
#resources["Music"].play(-1)
color=Getcolor(int(ball[1][0]), int(ball[1][1]), screen, resources)
print(color)
UpdateBall(ball,color)
#screen.blit(resources["MainLayer"], (0,0))
DrawBall(screen,ball,resources)
pygame.display.update()
fpsClock.tick(FPS)
def GetEvent(ball):
ev = [True,False,False,False,False,False,False,False,False,False]
for event in pygame.event.get():
if event.type == QUIT:
ev[GAME_RUNNING] = False
if event.type == MOUSEBUTTONUP:
mousepos = pygame.mouse.get_pos()
ball[1][0],ball[1][1]=mousepos
if event.type == KEYDOWN:
if event.key == K_DOWN:#compress spring
ev[KEY_DOWN] = True
if event.key == K_UP: #relax spring
ev[KEY_UP] = True
if event.key == K_LSHIFT: #left flipper
ev[KEY_LSHIFT] = True
if event.key == K_RSHIFT: #right flipper
ev[KEY_RSHIFT] = True
if event.type == KEYUP:
if event.key == K_q: #insert coin
ev[KEY_Q] = True
if event.key == K_SPACE: #launch ball
ev[KEY_SPACE] = True
if event.key == K_LEFT:#tilt left
ev[KEY_LEFT] = True
if event.key == K_RIGHT:#tilt right
ev[KEY_RIGHT] = True
if event.key == K_p:#pause
ev[KEY_P] = True
return ev
def DestroyGame():
pygame.quit()
and the constants code:
#screen
screen_lenght = 256
screen_width= 600
#fps
FPS=100
#events
GAME_RUNNING = 0
KEY_Q = 1
KEY_DOWN = 2
KEY_UP = 3
KEY_SPACE = 4
KEY_LSHIFT = 5
KEY_RSHIFT = 6
KEY_RIGHT = 7
KEY_LEFT = 8
KEY_P = 9
#ball physics
FRICTION_BALL=0.5
Gravity=1.9
Ball_width=11
Ball_len=9
But when I run it the ball is not colliding perfectly it's only colliding with the darkest spots and going through the light grey colors
If you look at this picture
the ball shouldn't be able to go through the bumpers but it does—I am sorry if my code is garbage, I am a beginner. :)
Here is a youtube link to a kinda working version of what I want to achieve: https://www.youtube.com/watch?v=SXegewcVx8A

PyGame Collision detection for pong and keeping the paddles on screen [duplicate]

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)
Sometimes the ball doesn't bounce off the paddle in pong game
(1 answer)
Closed 2 years ago.
So my problem here is that I don't want to use classes because I don't fully understand them yet nor do I want to use sprites. I have uploaded two images to the program I am able to move the paddles and get the ball to move and bounce off the top and bottom. However I cannot get the ball to bounce off the paddles. Also I cannot keep the paddles from going down off the screen or above off the screen. Any help would be appreciated thank you.
import sys
import pygame
pygame.init()
size = width, height = 1000, 800
screenColor = 0, 0, 0
outline = 0, 0, 255
paddleOne = pygame.image.load("PONGPADDLE.png")
paddleTwo = pygame.image.load("PONGPADDLE.png")
ball = pygame.image.load("Bullet.png")
paddleOnerect = paddleOne.get_rect()
paddleTworect = paddleTwo.get_rect()
ballrect = ball.get_rect()
speed = [1, 1]
paddleOne_x = 980
paddleOne_y = 400
paddleTwo_x = 5
paddleTwo_y = 400
paddleOnePos_x = 0
paddleOnePos_y = 0
paddleTwoPos_x = 0
paddleTwoPos_y = 0
screen = pygame.display.set_mode(size)
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
paddleOnePos_y = -1
if event.key == pygame.K_DOWN:
paddleOnePos_y = +1
if event.key == pygame.K_w:
paddleTwoPos_y = -1
if event.key == pygame.K_s:
paddleTwoPos_y = +1
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
paddleOnePos_y = 0
if event.key == pygame.K_DOWN:
paddleOnePos_y = 0
if event.key == pygame.K_w:
paddleTwoPos_y = 0
if event.key == pygame.K_s:
paddleTwoPos_y = 0
ballrect = ballrect.move(speed)
if ballrect.left < 0 or ballrect.right > width:
ballrect = ball.get_rect()
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[1]
paddleOne_y += paddleOnePos_y
paddleTwo_y += paddleTwoPos_y
screen.fill(screenColor)
screen.blit(paddleOne, (paddleOne_x, paddleOne_y))
screen.blit(paddleTwo, (paddleTwo_x, paddleTwo_y))
screen.blit(ball, ballrect)
pygame.draw.rect(screen, outline, ((0, 0), (width, height)), 5)
pygame.display.flip()

Categories