Trying to make mask overlap but not working properly [duplicate] - pygame

This question already has answers here:
Pygame mask collision
(1 answer)
Pygame collision with masks
(1 answer)
Check collision between a image and a line
(1 answer)
How to rotate mask of image pygame
(1 answer)
Closed 10 months ago.
Hi im tryin to make simulator for parking with use of genetic alghorythm, and from the begining im having trouble with colliding with mask i dont what im doing wrong but my track mask and car mask are colliding very wierdly.
Below is how im drawing and rotating my car
def draw(self, screen): # 3
self.car_rect.topleft = (int(self.x), int(self.y))
rotated_image = pygame.transform.rotate(self.car_img, self.angle)
new_rect = rotated_image.get_rect(center=self.car_img.get_rect(topleft=self.car_rect.topleft).center)
self.car_mask = pygame.mask.from_surface(rotated_image)
screen.blit(rotated_image, new_rect.topleft)
Theres how im using collision
def collide(self ,mask):
self.car_mask = pygame.mask.from_surface(self.car_img)
offset = (int(self.x),int(self.y))
poi = mask.overlap(self.car_mask,offset)
return poi
Below is my game loop where im moving with car and drawing it
screen.screen.fill((175, 174, 174)) # 9
screen.screen.blit(track.track_img, (0, 0))
car1.draw(screen.screen)
pygame.display.flip()
pygame.display.update()
clock.tick(60)
events = pygame.event.get()
pressed = pygame.key.get_pressed()
car1.speed *= 0.9
if pressed[pygame.K_UP]: car1.speed += 0.5 # 6
if pressed[pygame.K_DOWN]: car1.speed -= 0.5 # 6
if pressed[pygame.K_LEFT]: car1.angle += car1.speed / 4 # 7
if pressed[pygame.K_RIGHT]: car1.angle -= car1.speed / 4 # 7
car1.x += car1.speed * math.cos(math.radians(+car1.angle)) # 8
car1.y -= car1.speed * math.sin(math.radians(car1.angle)) # 8
offset = (int(car1.x), int(car1.y))
if car1.collide(track.track_mask) != None:
print("collide")
i dont know where problem is because mask i moving with car but on corners it stuck even if its now on the border. For offset im using just position of car bcs map is drawing at 0,0.

Related

Pygame square not showing up because of sprites [duplicate]

This question already has answers here:
Pygame Drawing a Rectangle
(6 answers)
Closed 5 months ago.
I try to print a square for use as a hitbox because the collision detection doesn't work on images. But when I try to draw a test square in setup it doesn't appear. I have tried moving the command, and changing it but nothing worked. And that is only for the square. The images appear and move perfectly. I am pretty sure it has something to do with the sprites because without them everything works perfectly.
import pygame
import sys
pygame.init()
fps = 30
fpsclock=pygame.time.Clock()
window = pygame.display.set_mode((600, 600))
x = 275
y = 375
BulletX = x + 10
BulletY = y - 15
color = (250,210,240)
ship_img = pygame.image.load('spaceship.png')
ship = pygame.transform.scale(ship_img,(32,32))
bullet_img = pygame.image.load('bullet (2).png')
bullet = pygame.transform.scale(bullet_img,(12,12))
# main application loop
run = True
while run:
# limit frames per second
fpsclock.tick(fps)
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
key_input = pygame.key.get_pressed() #key inputs
if key_input[pygame.K_LEFT]:
x -= 5
if key_input[pygame.K_RIGHT]:
x += 5
# clear the display
window.fill(0)
window.blit(ship,(x,y))
pygame.draw.rect(window,color,pygame.rect(200,200,30,30))
window.blit(bullet,(BulletX,BulletY))
BulletY = BulletY - 20
if(BulletY <= -10):
BulletY = y - 10
BulletX = x + 10
# update the display
pygame.display.flip()
pygame.quit()
exit()
The only problem with your code is a lowercase 'r' instead of of uppercase one. Change the appropriate line to:
pygame.draw.rect(window, color, pygame.Rect(200,200,30,30) )
and have fun implementing the collision.

Pyton - Pygame - stuck refreshing blitting image on screen [duplicate]

This question already has answers here:
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Why is my PyGame application not running at all?
(2 answers)
Closed 1 year ago.
Hi there and thank you for your time reading this.
This is related to the project I'm making. It's a reaction test game. Basically, Arcade buttons with LEDs light up, and players need to press them to score points. Whack-a-Mole style.
The game is timed, 30 seconds. But instead of using a numerical timer, I'm using a progress bar moving across the screen to indicate the remaining time instead.
image below:
game screenshot
I added this as an image blit in the code, but it doesn't refresh correctly. You can see it only at the start of the game, and when players press a button.
It needs to be constantly blitting across the screen.
Maybe I'm just missing something or my indentation is wrong?
Would really appreciate any inputs on this.
Main game loop code is below:
# MAIN GAME SEQUENCE CODE ---------------------------------------------------------------------------------------------
# Setup Pygame refresh rate to 120 fps
clock.tick(60)
while game_running:
# Idle Screen
idle_scrn()
# Instructions
inst_seq()
# GAME PLAY SECTION --------
score = 0
time_Out = 0
leds.off()
start_Time = pygame.time.Clock()
start = int(time.time())
time_move = -500
random_num = random.randint(0, 11)
leds.on(random_num)
print(random_num)
while time_Out != 30:
screen.blit(Timebar, (time_move,1000))
time_move += 50
pygame.display.update()
for event in pygame.event.get():
print("For Event started, Game screen started")
screen.fill((255,255,255))
screen.blit(Game_screen[6], (0,0))
score_textback = score_fontback.render("00", 3, (199,199,199))
score_text = score_font.render(str(score), 3, (255,37,24))
ctr = 1110
if score >= 10:
ctr -= 155
center_pos = (ctr, 580)
score_rect = score_text.get_rect(center = center_pos)
screen.blit(score_textback, (645, 390))
screen.blit(score_text, score_rect)
if event.type == pygame.JOYBUTTONDOWN:
print("If for event JOYBUTTONDOWN")
if event.button == random_num:
B = event.button
print(B, " button pressed, CORRECT")
leds.off()
butt_Sound.play()
random_num = random.randint(0, 11)
leds.on(random_num)
score += 1
pygame.display.update()
current_Time = int(time.time())
time_Out = current_Time - start
#pygame.display.update()
#print("TIMER: ", time_Out)
#print(type(start_Time))
#print(current_Time)
#print(type(current_Time))
#pygame.display.update()
# FINAL SCORE ------------------------
final_Score()
exit()
The image is Timebar. in the code, we move it 50 pixels across the screen in every refresh.
Thank you in advance.
Here's a minimal example, perhaps you'll find it useful:
import pygame
pygame.init()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
fps = 60
clock = pygame.time.Clock()
progress_width = 0 # initialse progress tracker
total_time = 0
target_time = 10_000 # ten seconds in milliseconds
finished = False
while not finished:
# Handle Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
finished = True
elif event.type == pygame.KEYDOWN:
progress_width = 0 # reset progress
total_time = 0
# Update Game State
dt = clock.tick(fps) # limit FPS and return time since last call
total_time += dt
progress_width += width * dt / target_time # scale bar width
progress_rect = pygame.Rect(0, height-20, int(progress_width), 20)
# Draw Background
screen.fill(pygame.Color("black"))
# Draw Sprites
pygame.draw.rect(screen, pygame.Color("red"), progress_rect)
# Update Display
pygame.display.flip()
# Display the elapsed time in the title bar
pygame.display.set_caption(f"Simple Progress {total_time:,d} ms")
pygame.quit()
It calculates the time elapsed and updates the progress bar width. It takes ten seconds to fill the screen width and pressing a key resets the progress.
Your main loop should look something like:
Handle Events
Update Game State
Draw sprites
Update Screen
If you're trying to update the screen or handle events in multiple places, things get confusing pretty quickly.

Moving a Sprite in the direction of an angle in Pygame [duplicate]

This question already has answers here:
How to turn the sprite in pygame while moving with the keys
(1 answer)
Image rotation while moving
(2 answers)
Closed 2 years ago.
Im trying to move a sprite in the direction of an angle in pygame, using the left & right arrow keys to change the direction of the sprite but when I press the up key, the sprite just moves right. I have 2 variables that take speed and a velocity calculation and adds them together (vel_x & vel_y), I then add this to the position (orientation) of the sprite but it isnt following the sprite orientation when it moves forward (if keybd_tupl[K_UP]).
import pygame
import random
import math
from pygame.locals import *
window_wid = 800
window_hgt = 600
frame_rate = 50
delta_time = 1 / frame_rate
STATE_READY = 2
def game_loop_inputs():
# look in the event queue for the quit event
quit_ocrd = False
for evnt in pygame.event.get():
if evnt.type == QUIT:
quit_ocrd = True
return quit_ocrd
def game_loop_update(circle_hitbox):
# start by assuming that no collisions have occurred
circle_hitbox["col"] = False
# return the new state of the rotating line and the circle hitbox
return circle_hitbox
def game_loop_render(circle_hitbox, window_sfc):
# clear the window surface (by filling it with black)
window_sfc.fill( (0,0,0) )
# draw the circle hitbox, in red if there has been a collision or in white otherwise
if circle_hitbox["col"]:
#pygame.draw.circle(window_sfc, (255, 0, 0), circle_hitbox["pos"], circle_hitbox["rad"])
rotated_damage = pygame.transform.rotate(circle_hitbox["damage"], circle_hitbox["angle"])
window_sfc.blit(rotated_damage, circle_hitbox["pos"])
else:
#pygame.draw.circle(window_sfc, (255, 255, 255), circle_hitbox["pos"], circle_hitbox["rad"])
rotated_image = pygame.transform.rotate(circle_hitbox["sprite"], circle_hitbox["angle"])
window_sfc.blit(rotated_image, circle_hitbox["pos"])
# update the display
pygame.display.update()
def main():
# initialize pygame
pygame.init()
# create the window and set the caption of the window
window_sfc = pygame.display.set_mode( (window_wid, window_hgt) )
pygame.display.set_caption('"Toy" for the MDA Exercise')
# create a clock
clock = pygame.time.Clock()
# this is the initial game state
game_state = STATE_READY
#####################################################################################################
# these are the initial game objects that are required (in some form) for the core mechanic provided
#####################################################################################################
# this game object is a circulr
circle_hitbox = {}
circle_hitbox["pos"] = (window_wid // 2, window_hgt // 2)
circle_hitbox["rad"] = 30
circle_hitbox["col"] = False
circle_hitbox["sprite"] = pygame.image.load("cars_racer_{}.png".format(random.randint(1, 3)))
circle_hitbox["damage"] = pygame.image.load("cars_racer_red.png")
circle_hitbox["crash"] = pygame.image.load("explosion.png")
circle_hitbox["damaged"] = False
circle_hitbox["angle"] = 0
speed = 10.0
vel_x = speed * math.cos(circle_hitbox["angle"] * (math.pi / 180))
vel_y = speed * math.sin(circle_hitbox["angle"] * (math.pi / 180))
# the game loop is a postcondition loop controlled using a Boolean flag
closed_flag = False
while not closed_flag:
#####################################################################################################
# this is the "inputs" phase of the game loop, where player input is retrieved and stored
#####################################################################################################
closed_flag = game_loop_inputs()
keybd_tupl = pygame.key.get_pressed()
if keybd_tupl[K_UP]:
circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)
print(vel_y)
if keybd_tupl[K_LEFT]:
circle_hitbox["angle"] = (circle_hitbox["angle"] + 10.0)
if keybd_tupl[K_RIGHT]:
circle_hitbox["angle"] = (circle_hitbox["angle"] - 10.0)
#####################################################################################################
# this is the "update" phase of the game loop, where the changes to the game world are handled
#####################################################################################################
circle_hitbox = game_loop_update(circle_hitbox)
#####################################################################################################
# this is the "render" phase of the game loop, where a representation of the game world is displayed
#####################################################################################################
game_loop_render(circle_hitbox, window_sfc)
# enforce the minimum frame rate
clock.tick(frame_rate)
if __name__ == "__main__":
main()
It just isnt working & I dont know why.
You have to calculate the vel_x and vel_y in the while loop.
while not closed_flag:
closed_flag = game_loop_inputs()
keybd_tupl = pygame.key.get_pressed()
if keybd_tupl[K_UP]:
circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)
print(vel_y)
if keybd_tupl[K_LEFT]:
circle_hitbox["angle"] -= 1.0
if keybd_tupl[K_RIGHT]:
circle_hitbox["angle"] += 1.0
# `math.radians` can be used instead of `* (math.pi / 180)`
vel_x = speed * math.cos(math.radians(circle_hitbox["angle"]))
vel_y = speed * math.sin(math.radians(circle_hitbox["angle"]))
Also, pass the negative angle to pygame.transform.rotate in the game_loop_render function:
rotated_damage = pygame.transform.rotate(circle_hitbox["damage"], -circle_hitbox["angle"])
The rotation probably still doesn't look right (I'm using some replacement images and they don't rotate correctly). Take a look at this answer if you want to know how to rotate pygame sprites and images around their center in pygame.

Pygame breaking code, creating a wall of bricks [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)
Closed 2 years ago.
This is my first time using pygame and I apologize for possible misunderstandings and 'silly' questions. I am developing a breaking game, consisting of a ball ,a paddle and a wall of bricks. So far I ve the ball, and that s fine. I am trying to implement my code in order to get the wall, but I am missing something and it doesn t show up on the screen when I run it. Could anyone help me? The bricks are 50x60, 3 rows. Thank you in advance. (If anyone would also recommend something about creating the paddle and making the ball stick to it, that would be highly appreciated.)
Here is my code so far:
""""BREAKING GAME"""
#Import and initialize pygame
import pygame as pg
pg.init()
#Set the colour of the background and store the ball data
backgroundcolour = (50,50,50)
randomcolour=(205,55,0)
ballimg = pg.image.load("ball.gif")
ballimage = ballimg.get_rect()
#Set the frame
xmax = 800
ymax = 800
screen = pg.display.set_mode((xmax,ymax))
#Starting values
horizontalposition = 400. #pixels (unit f length of computer)
verticalposition = 400. #pixels
v_x = 400. #pixels
v_y = 300. #pixels
#Set the clock of the computer
t0 = float(pg.time.get_ticks())/1000.
# Create wall of bricks
position_Bricks_x=[0,50,100,150,200,250,300,350,400,450,500,550,600,650,700,750]
position_Bricks_y = [16,32,48]
i = 0
j = 0
#Infinite loop
running = True
while running:
t = float(pg.time.get_ticks())/1000.
dt = min(t-t0, 0.1)
t0 = t
# Motion of the ball
horizontalposition = horizontalposition+v_x*dt
verticalposition = verticalposition+v_y*dt
#Bounce the ball on the edges of the screen
if horizontalposition > xmax:
v_x=-abs(v_x)
elif horizontalposition < 0:
v_x= abs(v_x)
if verticalposition > ymax:
v_y = -abs(v_y)
elif verticalposition<0:
v_y = abs(v_y)
# Draw the frame
screen.fill(backgroundcolour)
ballimage.centerx = int(horizontalposition)
ballimage.centery = int(verticalposition)
screen.blit(ballimg,ballimage)
while i < len(position_Bricks_x):
if j < len(position_Bricks_y):
pg.draw.rect(screen,randomcolour,[position_Bricks_x[i],position_Bricks_y[j],50,16])
j = j + 1
else:
j=0
i=i+1
pg.display.update()
pg.display.flip()
# Event handling
pg.event.pump()
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
Quit pygame
pg.quit()
print "Ready"

pygame collision detection between draw.circle and draw.rect [duplicate]

This question already has answers here:
How can I know if a circle and a rect is touched in Pygame?
(1 answer)
Issue finding side of collision for Circle-Rectangle collision
(1 answer)
Detect collision between textbox and circle in pygame
(1 answer)
How do I detect collision in pygame?
(5 answers)
Sometimes the ball doesn't bounce off the paddle in pong game
(1 answer)
Closed 2 years ago.
Is there a way to handle collision detection between draw.circle and draw.rect ?
If I try to use sprite collision detection than it says circle has not got rect atrributes.
I create two players: rectangles. I create one ball: circle. I would like to handle the collision between two players and a ball in the best way possible. Could you help ?
I present my code below:
# DATE: 090215
TWO PLAYERS
CONTROL VIA KEYBOARD OR MOUSE
#
import pygame, sys
from pygame.constants import MOUSEMOTION, K_LEFT, K_RIGHT, K_DOWN, K_UP
pygame.init()
clock = pygame.time.Clock()
SCREENW = 800
SCREENH = 600
SCREEN = pygame.display.set_mode((SCREENW,SCREENH),0,32)
WHITE = (255,255,255)
BLACK = (0,0,0)
BLUE = (0,70,160)
RED = (255,0,0)
RECTH = 100
RECTW = 30
#players
PLAYER1P = (0,((SCREENH - RECTH)/2),RECTW,RECTH)
PLAYER2P = ((SCREENW-RECTW),((SCREENH - RECTH)/2),RECTW,RECTH)
# BALLS append with a ball for collision detection purposes
BALLS = []
# PLAYERS append with players for collision detection purposes
PLAYERS = []
# CLASS TO DEFINE PLAYER
class PlayerSprite(pygame.sprite.Sprite):
# define object atributes
def __init__(self,x,y,rwidth,rheight):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = rwidth
self.height = rheight
# define object behavior
def update(self,control,Surface,color):
key = pygame.key.get_pressed()
self.control = control
if self.control == 1:
self.y = pygame.mouse.get_pos()[1]
if self.y >= SCREENH - RECTH:
self.y = SCREENH - RECTH
if self.control == 0:
dist = 20
if key[pygame.K_DOWN]:
self.y += dist
if key[pygame.K_UP]:
self.y -= dist
if key[pygame.K_LEFT]:
None
if key[pygame.K_RIGHT]:
None
if self.y >= SCREENH - RECTH:
self.y = SCREENH - RECTH
if self.y <= 0:
self.y = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# draw player as a rectangle
# the important bit is that here you can change player shape
self.player = pygame.Rect(self.x,self.y,self.width,self.height)
pygame.draw.rect(Surface,color,self.player)
class CircleSprite(pygame.sprite.Sprite):
# define object atributes
def __init__(self,x,y,rwidth,rheight,speedx,speedy):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.speedx = speedx
self.speedy = speedy
self.width = rwidth
self.height = rheight
# define object behavior
def update(self,Surface,color):
#self.control = control
#if self.control == 1:
# self.y = pygame.mouse.get_pos()[1]
self.x += self.speedx
self.y += self.speedy
# draw player as a rectangle
# the important bit is that here you can change player shape
pygame.draw.circle(Surface, color, (self.x, self.y), self.width, 0)
# main function
def main():
# CREATE PLAYER OBJECT before WHILE loop
prec1 = PlayerSprite(0,SCREENH/2 - RECTH/2,RECTW,RECTH)
prec2 = PlayerSprite(SCREENW - RECTW,SCREENH/2 - RECTH/2,RECTW,RECTH)
prec3 = CircleSprite(SCREENW/2,SCREENH/2,RECTW/3,RECTH/3,10,5)
PLAYERS.append(prec1)
PLAYERS.append(prec2)
BALLS.append(prec3)
while True:
# update OBJECT position
SCREEN.fill(WHITE)
# 0 = KEYBOARD
# 1 = MOUSE
prec1.update(0,SCREEN,BLUE)
prec2.update(1,SCREEN,BLACK)
prec3.update(SCREEN,RED)
# check collision
is_a_collision = pygame.sprite.collide_mask(prec1,prec3)
if is_a_collision:
print "Boom1"
# change direction
if prec3.x >= SCREENW or prec3.x <= 0:
prec3.speedx = - prec3.speedx
if prec3.y >= SCREENH or prec3.y <= 0:
prec3.speedy = - prec3.speedy
pygame.display.update()
clock.tick(50)
pygame.quit()
main()