Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have been making a game where 2 people try to score a goal on a net, but to do so, the ball must move and bounce. I would like the ball to move forward and upwards at a realistic angle, then bounce on the ground a few times before becoming stationary again. I'm not sure how to achieve this, my code is below, I really hope someone can edit it to work.
When I run the code, I get the following error
TypeError: unsupported operand type(s) for +=: 'pygame.math.Vector2' and 'int'(for the line "ball_vel += x2")
import pygame as pg
from pygame.math import Vector2
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
screen = pg.display.set_mode((800, 600))
width, height = screen.get_size()
clock = pg.time.Clock()
pg.display.set_caption("Super Acrobatic Rocket Powered Battle Polygons(SARPBP)")
x = 740
y = 0
x2 = 370
y2 = 500
x_change = 0
y_change = 0
bluespeed = 5
on_ground = False
bluecar = pg.Surface((60, 30))
bluecar.fill((0,0,255))
BALL = pg.Surface((30, 30), pg.SRCALPHA)
pg.draw.circle(BALL, [0,0,0], [15, 15], 15)
ball_pos = Vector2(x2, y2)
ballrect = BALL.get_rect(center=ball_pos)
ball_vel = Vector2(0, 0)
ball_mask = pg.mask.from_surface(BALL)
mask_blue = pg.mask.from_surface(bluecar)
mask_ball = pg.mask.from_surface(BALL)
pos_blue = Vector2(x,y)
bluerect = bluecar.get_rect(center = pos_blue)
vel_blue = Vector2(bluespeed,0)
# A constant value that you add to the y_change each frame.
GRAVITY = .5
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
x_change = -5
elif event.key == pg.K_d:
x_change = 5
elif event.key == pg.K_w:
if on_ground: # Only jump if the player is on_ground.
y_change = -12
on_ground = False
elif event.type == pg.KEYUP:
if event.key == pg.K_a and x_change < 0:
x_change = 0
elif event.key == pg.K_d and x_change > 0:
x_change = 0
# Add the GRAVITY value to y_change, so that
# the object moves faster each frame.
y_change += GRAVITY
x += x_change
y += y_change
#x += vel_blue
# Stop the object when it's near the bottom of the screen.
if y >= height - 100:
y = height - 100
y_change = 0
on_ground = True
if x == 0:
x = 5
elif x == 740:
x = 735
offset_blue = bluerect[0] - ballrect[0], bluerect[1] - ballrect[1]
overlap_blue = mask_ball.overlap(mask_blue, offset_blue)
if overlap_blue: # Blue collides with the ball.
ball_vel = Vector2(x_change) * 1.4
ball_vel += x2
# Draw everything.
screen.fill(LIGHTBLUE)
pg.draw.line(screen, (0, 0, 0), (0, height-70), (width, height-70))
screen.blit(bluecar, (x, y))
screen.blit(BALL, (x2,y2))
pg.display.update()
clock.tick(60)
pg.quit()
You can just invert the y component of the velocity vector when the ball touches the ground to make it bounce: ball_vel.y *= -1. Change the value by which you multiply the velocity to adjust the elasticity: ball_vel.y *= -0.94 # Lower elasticity.
import pygame as pg
from pygame.math import Vector2
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
screen = pg.display.set_mode((800, 600))
width, height = screen.get_size()
clock = pg.time.Clock()
BALL = pg.Surface((30, 30), pg.SRCALPHA)
pg.draw.circle(BALL, [0,0,0], [15, 15], 15)
ball_pos = Vector2(370, 0)
ballrect = BALL.get_rect(center=ball_pos)
ball_vel = Vector2(0, 0)
ground_pos = 70
GRAVITY = .9
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
ball_vel.y += GRAVITY # Accelerate downwards.
ball_pos += ball_vel # Move the ball.
ballrect.center = ball_pos
# Bounce when the ball touches the bottom of the screen.
if ballrect.bottom >= height - ground_pos:
# Just invert the y-velocity to bounce.
ball_vel.y *= -0.94 # Change this value to adjust the elasticity.
# Don't go below the ground.
ballrect.bottom = height - ground_pos
ball_pos.y = ballrect.centery
# Draw everything.
screen.fill(LIGHTBLUE)
pg.draw.line(screen, (0, 0, 0), (0, height-70), (width, height-ground_pos))
screen.blit(BALL, ballrect)
pg.display.update()
clock.tick(60)
pg.quit()
The error says that you cannot add an int and Vector2 together directly. The program does not know how to. What you need to do instead is to add to the x value of the vector. Change the line ball_vel += x2 to ball_vel.x += x2.
Related
I'm working on a space shooter game where you have to dodge asteroids and shoot them. Right now, I'm working on collision for the asteroids. I'm just testing one asteroid for now, but the asteroid passes straight through the ship and doesn't end the game like I want it to.
Here's the code:
import pygame
pygame.init()
#initalizing all the clunky variables
size = (900,700)
BLACK = (0, 0, 30)
RED = (255, 0, 0)
YELLOW = (0, 255, 0)
x_pos = 450
y_pos = 600
global x_pos
global y_pos
direct = 0
w, h = 100, 100
screen = pygame.display.set_mode(size)
klok = pygame.time.Clock()
#main ship image and its rotations
ship = pygame.image.load('u-sniper.png')
shipL = pygame.transform.rotate(ship, 270)
shipR = pygame.transform.rotate(ship, 90)
shipD = pygame.transform.rotate(ship, 180)
#init hitbox
hitbox = ship.get_rect()
hitbox.center = w//2,h//2
#funct for drawing ship
def drawShip():
if direct == 0:
screen.blit(ship, [x_pos,y_pos])
if direct == 1:
screen.blit(shipR, [x_pos,y_pos])
if direct == 2:
screen.blit(shipD, [x_pos,y_pos])
if direct == 3:
screen.blit(shipL, [x_pos,y_pos])
#asteroid obstacles (these are meant to collide with the ship)
class asteroid:
def __init__(self,x,y,spawn):
self.x = x
self.y = y
self.spawn = spawn
def drawA(self):
if self.spawn == 1:
pygame.draw.circle(screen, RED, (self.x,self.y), 30)
def moveA(self):
self.y += 8
if self.y > 650:
self.spawn = 0
done = False
roid = asteroid(450,0,1)
#asteroid hitbox init
rect_asteroid = (roid.x, roid.y, 30, 30)
#here is where its going wrong, collision dosent register
def checkForCollisions():
collide = pygame.Rect.colliderect(hitbox,rect_asteroid)
if collide == True:
done = True
#loop
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
drawShip()
roid.drawA()
roid.moveA()
#calling fuction, but it dosent work
checkForCollisions()
#if branch that moves the ship
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_pos -= 5
direct = 0
if event.key == pygame.K_DOWN:
y_pos += 5
direct = 2
if event.key == pygame.K_RIGHT:
x_pos += 5
direct = 3
if event.key == pygame.K_LEFT:
x_pos -= 5
direct = 1
#collision between screen boundaries
if x_pos > 850:
x_pos -= 6
if x_pos < -50:
x_pos += 6
if y_pos > 650:
y_pos -= 6
if y_pos < 0:
y_pos += 6
pygame.display.flip()
klok.tick(60)
pygame.quit()
I tried multiple colliderect functions, but it just results in one thing: the ship and the asteroid pass straight through each other.
The pygame.Rect objects do not magically update their position when you change the coordinates used to draw the object. You need to update the location stored in the pygame.Rect objects before collision detection. Or just create the objects in checkForCollisions:
def checkForCollisions():
hitbox.topleft = (x_pos, y_pos)
rect_asteroid = (roid.x, roid.y, 30, 30)
collide = hitbox.colliderect(rect_asteroid)
return collide
This question already has an answer here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I'm having trouble getting my collision to work in my game, I am using two rects, one acting as a paddle and one as a ball. I am using the normal pygame statement, rect1.colliderect(rect2), but for some reason it is not working.
Here is the line of code for the rects collision
#collision of ball with paddle
if (paddle.colliderect(ball)):
ball_x = 10
ball_y = 10
Not sure what's wrong. Here is the full coding if you wanna run it.
#December 16, 2019
#Final Project - Breakout
#IMPORTING LIBRARIES-----
import pygame
import sys
import time
#INITIALIZING SCREEN SIZE-----
pygame.init()
screen_size = (700, 750)
screen = pygame.display.set_mode((screen_size),0)
pygame.display.set_caption("BREAKOUT")
#retrieve screen measurements
screen_w = screen.get_width()
screen_h = screen.get_height()
#retrieve position of center of screen
center_x = int(screen_w/2)
center_y = int(screen_h/2)
#COLOURS-----
WHITE = (255,255,255)
BLACK = (0, 0, 0)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
PURPLE = (154, 136, 180)
#BACKGROUND-----
screen.fill(BLACK)
pygame.display.update()
#SPEED-----
clock = pygame.time.Clock()
FPS = 60 #set frames per second
speed = [4,4]
paddle_speed = 6
#VARIABLES-----
#paddle
paddle_w = 100
paddle_h = 10
paddle_x = 500
paddle_y = 670
paddle_dx = 0
paddle_dy = 0
#ball
ball_w = 10
ball_h = 10
ball_x = center_x
ball_y = center_y
#RECTS-----
paddle = pygame.Rect(paddle_x, paddle_y, paddle_w, paddle_h)
ball = pygame.Rect(ball_x, ball_y, ball_w, ball_h)
#LOOPS-----
game = False
#loop for game
game = True
while game:
for event in pygame.event.get():
if event.type ==pygame.QUIT:
game = False
pygame.quit()
sys.exit()
#moving paddle with keys
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
paddle_dx = -paddle_speed
elif event.key == pygame.K_RIGHT:
paddle_dx = paddle_speed
if event.type == pygame.KEYUP:
paddle_dx = 0
#constrain this loop to the specified FPS
clock.tick(FPS)
#PADDLE EVENTS-----
#store old paddle positions
old_paddle_x = paddle.x
old_paddle_y = paddle.y
#moving the paddle rect
paddle.move_ip(paddle_dx, paddle_dy)
#check to see if rect has left screen
if paddle.left < 0 or paddle.right > screen_w:
paddle.x = old_paddle_x
#BALL EVENTS-----
#moving ball
ball = ball.move(speed)
#collision left & right
if ball.left < 0 or ball.right > screen_w:
speed[0] = -speed[0]
#collision top
if ball.top < 0 or ball.bottom > screen_h:
speed[1] = -speed[1]
#collision of ball with paddle
if (paddle.colliderect(ball)):
ball_x = 10
ball_y = 10
#removes screen trail
screen.fill(BLACK)
#drawing paddle/ball inside rect
pygame.draw.rect(screen,PURPLE,paddle,0)
pygame.draw.rect(screen,WHITE,ball,0)
#updating the screen
pygame.display.update()
pygame.quit()
sys.exit()
The position of the ball is defined by the pygame.Rect object ball. ball_x and ball_y is just used to initialize ball.
You have to set ball.x = 10 and ball.y = 10 rather than ball_x = 10 and ball_y = 10:
if paddle.colliderect(ball):
ball.x = 10
ball.y = 10
To make the ball bounce of the paddle you have to invert speed[1] rather than changing the position of the ball by ball.x = 10 and ball.y = 10:
if paddle.colliderect(ball):
speed[1] = -speed[1]
I use this for rect collision :
if not (x1 >= x2 + w2 or x1 + w1 <= x2 or y1 >= y2 + h2 or y1 + h1 <= y2):
collision = True
else:
collision = False
I have been making a pygame game where 2 cars hit a ball around a pitch. When the player collides with the ball, the ball goes forwards, however, if the bottom of the player hits the top of the ball, the ball still goes upwards, understandingly as the code tells the ball to go upwards after contact. However, I want the ball to go downwards realistically when the ball is hit downwards. Has anyone got any ideas?
import pygame as pg
from pygame.math import Vector2
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
DARKBLUE = pg.Color(11, 8, 69)
screen = pg.display.set_mode((800, 600))
width, height = screen.get_size()
clock = pg.time.Clock()
# You need surfaces with an alpha channel for the masks.
bluecar = pg.Surface((60, 30), pg.SRCALPHA)
bluecar.fill((0,0,255))
BALL = pg.Surface((30, 30), pg.SRCALPHA)
pg.draw.circle(BALL, [0,0,0], [15, 15], 15)
ball_pos = Vector2(395, 15)
ballrect = BALL.get_rect(center=ball_pos)
ball_vel = Vector2(0, 0)
mask_blue = pg.mask.from_surface(bluecar)
mask_ball = pg.mask.from_surface(BALL)
pos_blue = Vector2(740, 500) # Just use the pos vector instead of x, y.
bluerect = bluecar.get_rect(center = pos_blue)
vel_blue = Vector2(0, 0) # Replace x_change, y_change with vel_blue.
# A constant value that you add to the y-velocity each frame.
GRAVITY = .5
ground_y = height - 100
timer = 3
dt = 1
def bluejumps():
if timer > 0:
vel_blue.y = -12
if pos_blue.y > 469:
timer -= dt
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
vel_blue.x = -5
elif event.key == pg.K_d:
vel_blue.x = 5
elif event.key == pg.K_w:
bluejumps()
elif event.type == pg.KEYUP:
if event.key == pg.K_a and vel_blue.x < 0:
vel_blue.x = 0
elif event.key == pg.K_d and vel_blue.x > 0:
vel_blue.x = 0
if bluerect.bottom >= ground_y:
bluerect.bottom = ground_y
pos_blue.y = bluerect.centery
#vel_blue.y = 0
timer = 3
ball_vel.y += GRAVITY # Accelerate downwards.
ball_pos += ball_vel # Move the ball.
ballrect.center = ball_pos # Update the rect.
# Bounce when the ball touches the bottom of the screen.
if ballrect.bottom >= ground_y:
# Just invert the y-velocity to bounce.
ball_vel.y *= -0.7 # Change this value to adjust the elasticity.
ball_vel.x *= .95 # Friction
# Don't go below the ground.
ballrect.bottom = ground_y
ball_pos.y = ballrect.centery
# Left and right wall collisions.
if ballrect.left < 0:
ball_vel.x *= -1
ballrect.left = 0
ball_pos.x = ballrect.centerx
elif ballrect.right > width:
ball_vel.x *= -1
ballrect.right = width
ball_pos.x = ballrect.centerx
if ballrect.top <= 0:
# Just invert the y-velocity to bounce.
ball_vel.y *= -0.4 # Change this value to adjust the elasticity.
ballrect.top = 1
ball_pos.y = ballrect.centery
# Add the GRAVITY value to vel_blue.y, so that
# the object moves faster each frame.
vel_blue.y += GRAVITY
pos_blue += vel_blue
bluerect.center = pos_blue # You have to update the rect as well.
# Stop the object when it's near the bottom of the screen.
if bluerect.bottom >= ground_y:
bluerect.bottom = ground_y
pos_blue.y = bluerect.centery
vel_blue.y = 0
timer = 3
if bluerect.x < 0:
bluerect.x = 0
pos_blue.x = bluerect.centerx
elif bluerect.right > width:
bluerect.right = width
pos_blue.x = bluerect.centerx
print(timer)
offset_blue = bluerect[0] - ballrect[0], bluerect[1] - ballrect[1]
overlap_blue = mask_ball.overlap(mask_blue, offset_blue)
if overlap_blue: # Blue collides with the ball.
if vel_blue.x != 0: # Player is moving.
ball_vel = Vector2(vel_blue.x, -17)
else: # If the player is standing, I just update the vel.y.
ball_vel.y = -17
# Draw everything.
screen.fill(LIGHTBLUE)
pg.draw.line(screen, (0, 0, 0), (0, ground_y), (width, ground_y))
screen.blit(bluecar, bluerect) # Blit it at the rect.
screen.blit(BALL, ballrect)
pg.display.update()
dt = clock.tick(60)/1000
pg.quit()
The easiest fix is to act like the player is actually two objects. If the ball intersects with the top half, have it bounce upwards, and if it hits the bottom half have it bound downwards. The more accurate approach would be to calculate the collision point and apply some rigid body collision response math based on that, but the approach might be good enough for your case.
The simpler approach will only work if the ball isn't moving too quickly, when the ball passes through a large portion of the player in a single game tick, but it's probably good enough for your case, you'll need to do some testing to figure out whether it's worth the extra complexity
I have been making a game in pygame where 2 squares hit a ball around score when they hit it into a net. I have added a minimalistic version of the code underneath.
When the ball hits the square, I am trying to make the ball go forward and a bit upwards before coming back down due to gravity in a realistic-looking way. Is there any possible way of doing this?
import pygame as pg
from pygame.math import Vector2
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
DARKBLUE = pg.Color(11, 8, 69)
screen = pg.display.set_mode((800, 600))
width, height = screen.get_size()
clock = pg.time.Clock()
pg.display.set_caption("Super Acrobatic Rocket Powered Battle Polygons(SARPBP)")
x = 740
y = 500
x2 = 395
y2 = 15
x_change = 0
y_change = 0
bluespeed = 5
ground_pos = 70
on_ground = False
bluecar = pg.Surface((60, 30))
bluecar.fill((0,0,255))
bluegoal = pg.Surface((60,150))
bluegoal.fill((0,0,255))
BALL = pg.Surface((30, 30), pg.SRCALPHA)
pg.draw.circle(BALL, [0,0,0], [15, 15], 15)
ball_pos = Vector2(x2, y2)
ballrect = BALL.get_rect(center=ball_pos)
ball_vel = Vector2(0, 0)
ball_mask = pg.mask.from_surface(BALL)
mask_blue = pg.mask.from_surface(bluecar)
mask_ball = pg.mask.from_surface(BALL)
pos_blue = Vector2(x,y)
bluerect = bluecar.get_rect(center = pos_blue)
vel_blue = Vector2(bluespeed,0)
# A constant value that you add to the y_change each frame.
GRAVITY = .5
GRAVITY2 = .5
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
x_change = -5
elif event.key == pg.K_d:
x_change = 5
elif event.key == pg.K_w:
if on_ground: # Only jump if the player is on_ground.
y_change = -12
on_ground = False
elif event.type == pg.KEYUP:
if event.key == pg.K_a and x_change < 0:
x_change = 0
elif event.key == pg.K_d and x_change > 0:
x_change = 0
ball_vel.y += GRAVITY # Accelerate downwards.
ball_pos += ball_vel # Move the ball.
ballrect.center = ball_pos
# Bounce when the ball touches the bottom of the screen.
if ballrect.bottom >= height - ground_pos:
# Just invert the y-velocity to bounce.
ball_vel.y *= -0.7 # Change this value to adjust the elasticity.
# Don't go below the ground.
ballrect.bottom = height - ground_pos
ball_pos.y = ballrect.centery
# Add the GRAVITY value to y_change, so that
# the object moves faster each frame.
y_change += GRAVITY
x += x_change
y += y_change
# Stop the object when it's near the bottom of the screen.
if y >= height - 100:
y = height - 100
y_change = 0
on_ground = True
if x == 0:
x = 5
elif x == 740:
x = 735
offset_blue = bluerect[0] - ballrect[0], bluerect[1] - ballrect[1]
overlap_blue = mask_ball.overlap(mask_blue, offset_blue)
if overlap_blue: # Blue collides with the ball.
ball_vel = Vector2(vel_blue) * 1.4
# Draw everything.
screen.fill(LIGHTBLUE)
pg.draw.line(screen, (0, 0, 0), (0, height-70), (width, height-70))
screen.blit(bluecar, (x, y))
screen.blit(BALL, ballrect)
pg.display.update()
clock.tick(60)
pg.quit()
You have to update the position of the blue rect as well each frame or it will stay at it's original position and the collision detection won't work.
Then I suggest getting rid of the x, y, x2, y2, x_change, y_change variables, since you can just use the vectors pos_blue and vel_blue.
When the player collides with the ball you can set the y-component of the ball's velocity to some negative value, so that it moves up (I just set the x-component to the player's velocity.x here if the player is moving).
ball_vel = Vector2(vel_blue.x, -17)
Note that you have to use surfaces with an alpha channel or the pygame.mask.from_surface won't work, therefore I pass pygame.SRCALPHA as the second argument to pygame.Surface (you could also call convert_alpha() or set_colorkey()).
import pygame as pg
from pygame.math import Vector2
pg.init()
LIGHTBLUE = pg.Color('lightskyblue2')
DARKBLUE = pg.Color(11, 8, 69)
screen = pg.display.set_mode((800, 600))
width, height = screen.get_size()
clock = pg.time.Clock()
# You need surfaces with an alpha channel for the masks.
bluecar = pg.Surface((60, 30), pg.SRCALPHA)
bluecar.fill((0,0,255))
BALL = pg.Surface((30, 30), pg.SRCALPHA)
pg.draw.circle(BALL, [0,0,0], [15, 15], 15)
ball_pos = Vector2(395, 15)
ballrect = BALL.get_rect(center=ball_pos)
ball_vel = Vector2(0, 0)
mask_blue = pg.mask.from_surface(bluecar)
mask_ball = pg.mask.from_surface(BALL)
pos_blue = Vector2(740, 500) # Just use the pos vector instead of x, y.
bluerect = bluecar.get_rect(center = pos_blue)
vel_blue = Vector2(0, 0) # Replace x_change, y_change with vel_blue.
# A constant value that you add to the y-velocity each frame.
GRAVITY = .5
on_ground = False
ground_y = height - 100
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_a:
vel_blue.x = -5
elif event.key == pg.K_d:
vel_blue.x = 5
elif event.key == pg.K_w:
if on_ground: # Only jump if the player is on_ground.
vel_blue.y = -12
on_ground = False
elif event.type == pg.KEYUP:
if event.key == pg.K_a and vel_blue.x < 0:
vel_blue.x = 0
elif event.key == pg.K_d and vel_blue.x > 0:
vel_blue.x = 0
ball_vel.y += GRAVITY # Accelerate downwards.
ball_pos += ball_vel # Move the ball.
ballrect.center = ball_pos # Update the rect.
# Bounce when the ball touches the bottom of the screen.
if ballrect.bottom >= ground_y:
# Just invert the y-velocity to bounce.
ball_vel.y *= -0.7 # Change this value to adjust the elasticity.
ball_vel.x *= .95 # Friction
# Don't go below the ground.
ballrect.bottom = ground_y
ball_pos.y = ballrect.centery
# Left and right wall collisions.
if ballrect.left < 0:
ball_vel.x *= -1
ballrect.left = 0
ball_pos.x = ballrect.centerx
elif ballrect.right > width:
ball_vel.x *= -1
ballrect.right = width
ball_pos.x = ballrect.centerx
# Add the GRAVITY value to vel_blue.y, so that
# the object moves faster each frame.
vel_blue.y += GRAVITY
pos_blue += vel_blue
bluerect.center = pos_blue # You have to update the rect as well.
# Stop the object when it's near the bottom of the screen.
if bluerect.bottom >= ground_y:
bluerect.bottom = ground_y
pos_blue.y = bluerect.centery
vel_blue.y = 0
on_ground = True
if bluerect.x < 0:
bluerect.x = 0
pos_blue.x = bluerect.centerx
elif bluerect.right > width:
bluerect.right = width
pos_blue.x = bluerect.centerx
offset_blue = bluerect[0] - ballrect[0], bluerect[1] - ballrect[1]
overlap_blue = mask_ball.overlap(mask_blue, offset_blue)
if overlap_blue: # Blue collides with the ball.
if vel_blue.x != 0: # Player is moving.
ball_vel = Vector2(vel_blue.x, -17)
else: # If the player is standing, I just update the vel.y.
ball_vel.y = -17
# Draw everything.
screen.fill(LIGHTBLUE)
pg.draw.line(screen, (0, 0, 0), (0, ground_y), (width, ground_y))
screen.blit(bluecar, bluerect) # Blit it at the rect.
screen.blit(BALL, ballrect)
pg.display.update()
clock.tick(60)
pg.quit()
import pygame
#Colors, Allways you need colors!!!!
BLACK = ( 0, 0, 0)
GREEN = ( 0, 255, 0)
WHITE = ( 255, 255, 255)
RED = ( 255, 0, 0)
ORANGE = ( 255, 115, 0)
YELLOW = ( 242, 255, 0)
BROWN = ( 115, 87, 39)
PURPLE = ( 298, 0, 247)
GRAY = ( 168, 168, 168)
PINK = ( 255, 0, 234)
BLUE = ( 0, 0 , 255)
pygame.init()
# Screen
screen = pygame.display.set_mode([700,500])
#Name of thewindow
pygame.display.set_caption("Trial to make PONG")
# Any variables!
x_speed = 0
y_speed = 0
x_coord = 10
y_coord = 250
x = 670
y = 250
other_speed = 0
other_speed2 = 0
rect_x = 50
rect_y = 50
rect_change_x = 5
rect_change_y = 5
clock = pygame.time.Clock()
#Sounds,maybe needed?
#Main Loop__________
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# User pressed down on a key
elif event.type == pygame.KEYDOWN:
# Figure out if it was an arrow key. If so
# adjust speed.
if event.key == pygame.K_UP:
y_speed = -5
elif event.key == pygame.K_DOWN:
y_speed = 5
elif event.key == pygame.K_w:
other_speed2 = -5
elif event.key == pygame.K_s:
other_speed2 = 5
# User let up on a key
elif event.type == pygame.KEYUP:
# If it is an arrow key, reset vector back to zero
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_speed = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_speed = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
other_speed2 = 0
# Move the object according to the speed vector.
x_coord += x_speed
y_coord += y_speed
x += x_speed
y += other_speed2
screen.fill(BLACK)
pygame.draw.rect(screen,BLUE,[x_coord,y_coord,20,60])
pygame.draw.rect(screen,YELLOW,[x,y,20,60])
if x > 650 or x < 0:
# Draw the rectangle
pygame.draw.ellipse(screen, BLUE, [rect_x, rect_y, 50, 50])
# Move the rectangle starting point
rect_x += rect_change_x
rect_y += rect_change_y
if rect_x > 650 or rect_x < 0:
rect_change_x = rect_change_x * -1
if rect_y > 450 or rect_y < 0:
rect_change_y = rect_change_y * -1
pygame.display.flip()
clock.tick(60)
pygame.quit()
Ok so I have 2 paddles in this pong game called Blue and yellow rectangle. I can move them but they move off the screen. How do I prevent that. Iv looked online but nothing seems to be working. I thought about putting rectangles around the screen to make a collision point argument where when the Blue/Yellow paddle hit it they won't move any further, but im not sure how to do that with ought ruining the code? Thank you for your help..
You should check to see if it's off the edge of the screen before you change the y coordinate. See
if y_coord + y_speed >= 0 and y_coord + y_speed + 60 <= 500:
y_coord += y_speed
Though as you can see it can get a little confusing to use numbers, which is why you should avoid hard-coding. It's better to have a display_height, display_width, and y_speed variable. Basically, outside of initializing variables, you should only have 0s as numbers. Also, note what happens when you leave out + y_speed in the if statement.
I suggest you start using the Rect class, since it makes handling such cases easy. Also, your code will become cleaner and shorter.
Here's an example of using Rect. Note that I simply use clamp_ip to ensure the player paddles can't leave the screen:
import pygame
BLACK = pygame.color.Color('Black')
YELLOW = pygame.color.Color('Yellow')
BLUE = pygame.color.Color('Blue')
pygame.init()
screen = pygame.display.set_mode([700,500])
screen_rect = screen.get_rect()
pygame.display.set_caption("Trial to make PONG")
blue_rect = pygame.Rect(10, 250, 20, 60)
yellow_rect = pygame.Rect(670, 250, 20, 60)
ball_rect = pygame.Rect(50, 50, 50, 50)
ball_x_speed = 5
ball_y_speed = 5
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# check all pressed keys and move the paddles
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP]: blue_rect.move_ip(0, -5)
if pressed[pygame.K_DOWN]: blue_rect.move_ip(0, 5)
if pressed[pygame.K_w]: yellow_rect.move_ip(0, -5)
if pressed[pygame.K_s]: yellow_rect.move_ip(0, 5)
# ensure paddles stay on screen
blue_rect.clamp_ip(screen_rect)
yellow_rect.clamp_ip(screen_rect)
# move the ball
ball_rect.move_ip(ball_x_speed, ball_y_speed)
# check if the ball needs to change direction
if ball_rect.x + ball_rect.width > screen_rect.width or ball_rect.x < 0:
ball_x_speed = ball_x_speed * -1
if ball_rect.y + ball_rect.height> screen_rect.height or ball_rect.y < 0:
ball_y_speed = ball_y_speed * -1
# draw everything
screen.fill(BLACK)
pygame.draw.ellipse(screen, BLUE, ball_rect)
pygame.draw.rect(screen,BLUE, blue_rect)
pygame.draw.rect(screen,YELLOW, yellow_rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
It seems like you're setting the height of the screen to be 500 pixels. Maybe you could check if your paddles are at the limit of the screen before moving them.
newY = y_coord + y_speed
if newY >= 0 and newY + PADDLE_HEIGHT < SCREEN_HEIGHT:
y_coord = newy