VIDEO When my player distance is a little farther than the knife they stop shooting at the player I am not sure why? How could I fix it and make sure it shoots where ever the player distance is. Like I don't want it to stop shooting when the player is a little farther away from the projectile I am not sure if I have a range for it to shoot the player or maybe when my player scrolls
when it stops shooting at the player the shooting sound still plays but my projectiles aren't shooting and that causes my sound to keep playing rapidly.
This is how my enemies shoot:
for shootss in shootsright:
shootss.x += shootss.xspeed
shootss.y += shootss.yspeed
if shootss.x > 700 or shootss.x < 0 or shootss.y > 500 or shootss.y < 0:
shootsright.pop(shootsright.index(shootss))
shootss.lookAt((playerman.x,playerman.y))
if box1.health > 25:
if len(shootsright) < 1:
for enemyshoot in enemyshooting:
BULLET_SPEED = 10
start_x = round(enemyshoot.x+enemyshoot.width+-35)
start_y = round(enemyshoot.y + enemyshoot.height+-25)
target_x = playerman.x+playerman.width//2
target_y = playerman.y+playerman.width//2
delta_x, delta_y = target_x - start_x, target_y - start_y
distance = math.sqrt(delta_x ** 2 + delta_y ** 2)
dir_x = BULLET_SPEED * delta_x / distance
dir_y = BULLET_SPEED * delta_y / distance
distance = math.sqrt(dir_x**2 + dir_y**2)
knifesound.play()
if distance > 0:
shootsright.append(enemyboolss(start_x,start_y,(0,0,0),dir_x, dir_y))
This is the class for the projectile:
class projectile(object):
def __init__(self, x, y, dirx, diry, color):
self.x = x
self.y = y
self.dirx = dirx
self.diry = diry
self.isJump = False
self.slash = pygame.image.load("round.png")
self.slash = pygame.transform.scale(self.slash,(self.slash.get_width()//6,self.slash.get_height()//6))
self.rect = self.slash.get_rect()
self.rect.topleft = ( self.x, self.y )
self.speed = 18
self.color = color
self.hitbox = (self.x + -18, self.y, 46,60)
def move(self):
self.x += self.dirx * self.speed
self.y += self.diry * self.speed
def draw(self, window):
self.rect.topleft = (round(self.x), round(self.y))
window.blit(self.slash, self.rect)
self.hitbox = (self.x + -18, self.y, 30,30)
my full code: script
Your screen is 800x800, but the knife code is checking 700x500. The knife projectile is created but immediately removed from the knife list at the next loop:
if shootss.x > 700 or shootss.x < 0 or shootss.y > 500 or shootss.y < 0:
shootsright.pop(shootsright.index(shootss))
shootss.lookAt((playerman.x,playerman.y))
This causes the knife flash but no movement for knives past 700.
After setting the check to 800, the knives worked correctly including sound.
Related
So I'm creating a little pong game in python (pygame) and I'm trying to create a bot for it...
if you have the balls velocity:
velocity = [10, 5]
the balls x:
x = 300
and the y:
y = 300
is it possible the calculate where the ball is going to go (also knowing where the edges are where the ball bounces)
my code for the game till now:
https://pastebin.com/eQRZedqs
import pygame
import sys
SIZE = (1000, 600)
FRAMES = 60
win = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
class Player:
def __init__(self, x, y):
self.size = (15, 120)
self.x = x
self.y = y
def draw(self, surface):
pygame.draw.rect(surface, (255, 255, 255),
pygame.Rect((self.x, self.y), self.size))
class Ball:
def __init__(self):
self.x = SIZE[0] // 2
self.y = SIZE[1] // 2
self.vel = [-5, 0]
def move(self):
self.x += self.vel[0]
self.y += self.vel[1]
if self.y <= 20 or self.y >= SIZE[1] - 20:
self.vel[1] *= -1
if (self.x <= 45 and bot.y < self.y < bot.y + bot.size[1]) or (self.x >= SIZE[0] - 45 and p.y < self.y < p.y + p.size[1]):
self.vel[0] *= -1
def draw(self, surface):
pygame.draw.circle(surface, (255, 255, 255), (self.x, self.y), 10)
class Bot(Player):
def __init__(self, x, y):
super().__init__(x, y)
self.ball_vel = b.vel
self.ball_x = b.x
self.ball_y = b.y
def draw_screen(surface):
surface.fill((0, 0, 0))
p.draw(surface)
b.draw(surface)
bot.draw(surface)
b.move()
pygame.display.update()
def key_handler():
keys = pygame.key.get_pressed()
if (keys[pygame.K_UP] or keys[pygame.K_w]) and p.y >= 20:
p.y -= 5
elif (keys[pygame.K_DOWN] or keys[pygame.K_s]) and p.y + p.size[1] <= SIZE[1] - 20:
p.y += 5
def main_loop():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
key_handler()
draw_screen(win)
clock.tick(FRAMES)
if __name__ == "__main__":
pygame.init()
p = Player(SIZE[0] - 45, SIZE[1] // 2 - 60)
b = Ball()
bot = Bot(20, SIZE[1] // 2 - 60)
main_loop()
I'd say add the following function to the Ball class:
class Ball:
def __init__(self):
self.x = SIZE[0] // 2
self.y = SIZE[1] // 2
self.vel = [-5, 0]
def move(self):
self.x += self.vel[0]
self.y += self.vel[1]
if self.y <= 20 or self.y >= SIZE[1] - 20:
self.vel[1] *= -1
if (self.x <= 45 and bot.y < self.y < bot.y + bot.size[1]) or (self.x >= SIZE[0] - 45 and p.y < self.y < p.y + p.size[1]):
self.vel[0] *= -1
def draw(self, surface):
pygame.draw.circle(surface, (255, 255, 255), (self.x, self.y), 10)
# projecting to see in which y the ball will end up (returns the y coordinate)
def project(self):
# setting up local variables as to not change the actual position of the ball
x = self.x
y = self.y
vel = self.vel
# doing practically the same thing as move but with the local x and y
while x > 45 and x < SIZE[0] - 45:
x += vel[0]
y += vel[1]
if y <= 20 or y >= SIZE[1] - 20:
vel[1] *= -1
return y
Since you have the return value of y, then you can get your bot to move directly there, either in a slow manner or an instant one.
If you want to get into quicker solutions, you need to use some physics equations, but in my opinion, this is quick enough (it'll get there pretty quickly). Also, you could alternatively use trigonometry to get the answer, by imagining the velocities as one vector (then you could get the angle of motion relative to the y axis and then use trig to get the final length until the y reaches the border. Repeat that, until you get to the y-axis borders, and you can calculate your x more efficiently (though, once again, there is most probably no need for that, since it should run fast enough).
I have an Enemys That Move Left And Right With A HealthBar But How Could I add Particles When The Enemy Dies Like Blood Particles When The enemy Is Killed it appears and falls down and dispears?
Example: >>> VIDEO I killed the enemy and its deleted how could I make load blood particles same position as the enemy that just died
heres my enemy class
class enemys:
def __init__(self,x,y,height,width,end):
self.x = x
self.y =y
self.esright = [pygame.image.load("esright1.png"),
pygame.image.load("esright1.png"),
pygame.image.load("esright2.png"),
pygame.image.load("esright3.png"),
pygame.image.load("esright4.png"),
pygame.image.load("esright5.png"),
pygame.image.load("esright6.png"),
pygame.image.load("esright7.png"),
pygame.image.load("esright8.png"),
pygame.image.load("esright9.png"),
pygame.image.load("esright10.png"),
pygame.image.load("esright11.png"),
pygame.image.load("esright12.png"),
pygame.image.load("esright13.png"),
pygame.image.load("esright14.png"),
pygame.image.load("esright15.png"),
pygame.image.load("esright16.png"),
pygame.image.load("esright17.png"),
]
self.esleft = [pygame.image.load("esleft1.png"),
pygame.image.load("esleft1.png"),
pygame.image.load("esleft2.png"),
pygame.image.load("esleft3.png"),
pygame.image.load("esleft4.png"),
pygame.image.load("esleft5.png"),
pygame.image.load("esleft6.png"),
pygame.image.load("esleft7.png"),
pygame.image.load("esleft8.png"),
pygame.image.load("esleft9.png"),
pygame.image.load("esleft10.png"),
pygame.image.load("esleft11.png"),
pygame.image.load("esleft12.png"),
pygame.image.load("esleft13.png"),
pygame.image.load("esleft14.png"),
pygame.image.load("esleft15.png"),
pygame.image.load("esleft16.png"),
pygame.image.load("esleft17.png"),
]
self.esright = [pygame.transform.scale(image,(image.get_width()//3,image.get_height()//3)) for image in self.esright]
self.esleft = [pygame.transform.scale(image,(image.get_width()//3,image.get_height()//3)) for image in self.esleft]
self.height = height
self.width = width
self.anim_index = 0
self.distance = 80
self.speed = 8
self.vel = 3
self.path = [x,end]
self.Walking_index = 0
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
self.rect = pygame.Rect(x,y,height,width)
COOLDOWN = 30
# enemys health
self.health = 10
self.visible = True
# this makes the enemy move right and left
def draw(self,window):
self.move()
if self.Walking_index + 1 >= 33:
self.Walking_index = 0
if self.vel > 0:
window.blit(self.esright[self.Walking_index//3], (self.x,self.y))
self.Walking_index += 1
else:
window.blit(self.esleft[self.Walking_index//3], (self.x,self.y))
self.Walking_index += 1
# this moves the enemy left and right
def move(self):
if self.visible:
if self.vel > 0:
if self.x + self.vel < self.path[1]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.Walking_index = 0
else:
if self.x - self.vel > self.path[0]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.Walking_index = 0
# the hit box for the enemy the health
pygame.draw.rect(window, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 70, 10)) # NEW
pygame.draw.rect(window, (0,255,0), (self.hitbox[0], self.hitbox[1] - 20, 70 - (5 * (10 - self.health)), 10))
self.hitbox = (self.x + 47, self.y + 31, 50, 72)
# THIS PART MAKES the enemy not scroll with the player
def scroll(self,sx, sy):
self.x += sx
self.y += sy
self.path[0] += sx
self.path[1] += sx
heres when the enemys health bar reaches 0 the enemy gets deleted how can I add particles when its deleted? blood particles that drop from the enemys position
# enemys 1
for bullet in bullets:
if bullet.rect.colliderect(enemys2.hitbox):
if enemys2.health > -5:
enemys2.health -= 1
bullets.pop(bullets.index(bullet))
hitesound.play()
# this function calss the -5 text appearing and dispearing on my screen
minusenemyhealthtext()
else:
for oe in range(len(enemyings)-1,-1,-1):
deathsound.play()
del enemyings[oe]
Here are your options:
Get a GIF, split it to multiple images, and just display each of those images one after another. Make all of that in a class.
Make a class (blood class) that would draw make instances of another class (particle class) that just moves outwards and disappears after a while.
I am not going to write the code out for you, you must write it yourself, but that is how you do it.
I have an enemy that shoots projectiles but only shoots to the right I want it to shoot at the player with any position I don't know how to do that heres a vid what I have done so fare if you could walk me throw the steps on how to do it that would be great Thank You
this is what I have done so fare it only shoots to the right I want it to shoot at the player within any position the player is at
for shootss in shootsright:
if shootss.x < 500 and shootss.x > 0:
shootss.x += 7
else:
shootsright.pop(shootsright.index(shootss))
if len(shootsright) < 1:
shootsright.append(Bools(round(enemyshoots1.x+enemyshoots1.width-107),round(enemyshoots1.y + enemyshoots1.height-50),(0,0,0)))
and here is my bullet class
# enemys bullets
ksud = pygame.image.load("heart.png")
class Bools(object):
def __init__(self, x, y,color):
self.x = x
self.y = y
self.ksud = pygame.image.load("heart.png")
self.hitbox = self.ksud.get_rect()
self.rect = self.ksud.get_rect()
self.rect.topleft = (self.x,self.y)
self.speed = 10
self.color = color
self.hitbox = (self.x + 57, self.y + 33, 29, 52) # NEW
def draw(self, window):
self.rect.topleft = (self.x,self.y)
player_rect = self.ksud.get_rect(center = self.rect.center)
player_rect.centerx += 0 # 10 is just an example
player_rect.centery += 0 # 15 is just an example
window.blit(self.ksud, player_rect)
self.hitbox = (self.x + 97, self.y + 33, 10, 10) # NEW
window.blit(self.ksud,self.rect)
my enemys class
shotsright = pygame.image.load("shooting2.png")
shotsleft = pygame.image.load("shooting1.png")
class enemyshoot:
def __init__(self,x,y,height,width,color):
self.x = x
self.y =y
self.height = height
self.width = width
self.color = color
self.shootsright = pygame.image.load("shooting2.png")
self.shotsleft = pygame.image.load("shooting1.png")
self.shootsright = pygame.transform.scale(self.shootsright,(self.shootsright.get_width()//3,self.shootsright.get_height()//3))
self.shotsleft = pygame.transform.scale(self.shotsleft,(self.shotsleft.get_width()//3,self.shotsleft.get_height()//3))
self.rect = pygame.Rect(x,y,height,width)
self.health = 10
self.hitbox = (self.x + -20, self.y + 30, 31, 57)
def draw(self):
self.rect.topleft = (self.x,self.y)
window.blit(self.shootsright,self.rect)
self.hits = (self.x + 20, self.y, 28,60)
pygame.draw.rect(window, (255,0,0), (self.hitbox[0], self.hitbox[1] - 60, 50, 10)) # NEW
pygame.draw.rect(window, (0,255,0), (self.hitbox[0], self.hitbox[1] - 60, 50 - (5 * (10 - self.health)), 10))
self.hitbox = (self.x + 60, self.y + 80, 81, 87)
black = (0,0,0)
enemyshoots1 = enemyshoot(1100,240,100,100,black)
enemyshooting = [enemyshoots1]
here is my full code
script
Looking at your script didn't help me a lot as you are maintaining many different classes.
for shootss in shootsright:
if shootss.x < 500 and shootss.x > 0:
shootss.x += 7
Here it appears that when you are updating your bullets x coordinate you are incrementing it with a positive constant value.
And then you update it like this in your bullet class.
window.blit(self.ksud,self.rect)
What you can do instead is have a bullet speed that changes its direction.You can use a code like this
if object_you_want_to_follow.x > object_shooting_the_bullet.x:
bulletSpeed = +7
elif object_you_want_to_follow.x < object_shooting_the_bullet.x:
bulletSpeed = -7
Same applies if you want to follow it vertically along the y direction.
OPTIMIZATION TIP
From what i understand having this in your bullet class makes no difference as you are updating it soon after.
window.blit(self.ksud, player_rect)
EDIT
To make things easier you can simply do this
for shootss in shootsright:
if shootss.x < 500 and shootss.x > 0:
if enemy.x < playerman.x:
shootss.x += 7
else:
shootss.x -= 7
else:
shootsright.pop(shootsright.index(shootss))
if len(shootsright) < 1:
shootsright.append(Bools(round(enemyshoots1.x+enemyshoots1.width-107),round(enemyshoots1.y + enemyshoots1.height-50),(0,0,0)))
Let's consider following code (balls with random centers and velocities collide, with screen surface bounds, and with each other):
import pygame,sys,math
from pygame.locals import *
from random import randrange
WIDTH = 500
HEIGHT = 500
WHITE = (255,255,255)
BLUE = (0, 0, 255)
RADIUS = 10
FPS = 30
DISPLAYSURF = pygame.display.set_mode((WIDTH,HEIGHT),0,32)
TAB = []
fpsClock = pygame.time.Clock()
pygame.display.set_caption('Animation')
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, A):
return math.sqrt((A.x-self.x)**2 + (A.y-self.y)**2)
def getTouple(self):
return (self.x,self.y)
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def norm(self):
return math.sqrt(self.x**2 + self.y**2)
class Ball:
def __init__(self, center, radius, velocity):
self.center = center
self.radius = radius
self.velocity = velocity
def __init__(self):
self.radius = RADIUS
self.center = Point(randrange(RADIUS,WIDTH-RADIUS), randrange(RADIUS,HEIGHT-RADIUS))
vx = randrange(-5,5)
vy = randrange(-5,5)
while vx == 0 or vy == 0:
vx = randrange(-5,5)
vy = randrange(-5,5)
self.velocity = Vector(vx,vy)
def draw(self):
self.center.x += self.velocity.x
self.center.y += self.velocity.y
for ball in TAB:
if ball != self:
if ball.center.distance(self.center) <= 2*RADIUS:
tmp = self.velocity
self.velocity = ball.velocity
ball.velocity = tmp
if self.center.x - self.radius <= 0:
self.velocity.x = -self.velocity.x
if self.center.x + self.radius >= WIDTH:
self.velocity.x = -self.velocity.x
if self.center.y - self.radius <= 0:
self.velocity.y = -self.velocity.y
if self.center.y + self.radius >= HEIGHT:
self.velocity.y = -self.velocity.y
pygame.draw.circle(DISPLAYSURF, BLUE, self.center.getTouple(), self.radius, 0)
BallNum = 30
for i in range(BallNum):
k = Ball()
TAB.append(k)
while True:
DISPLAYSURF.fill(WHITE)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
for ball in TAB:
ball.draw()
pygame.display.update()
fpsClock.tick(FPS)
This code works but not corectly: some balls are 'catched' by the bounds and others 'stick together'. I think the problem is in Ball class method draw. I will be grateful for any ideas on how to improve that code.
The main problem with the code you have posted which causes some of the balls to stick together, is that after they bounce off of each other, they still are in contact, so they bounce off of each other indefinitely which causes them to 'stick together'.
To fix this problem:
Add in an attribute/variable which holds a reference to the ball that it last hit. I called this attribute ball_last_hit and I initialized it to None.
Then, in the collision detection code, simply check to make sure the ball is not in contact with the ball it last hit, with an if statement like this: if ball != self.ball_last_hit:.
Then, if the balls should bounce off of each other, after swapping their velocities, set self.ball_last_hit to ball.
This will solve the 'sticking together' problem between the balls, but the ball could still get 'stuck' to the wall, although it is less common. To solve this you could add in an attribute called something like self.ignore_walls and after each collision with a wall, set it to true, then after a certain amount of time, set it back to false, so it can collide with walls again.
Here is the fixed code:
import pygame,sys,math
from pygame.locals import *
from random import randrange
WIDTH = 500
HEIGHT = 500
WHITE = (255,255,255)
BLUE = (0, 0, 255)
RADIUS = 10
FPS = 30
DISPLAYSURF = pygame.display.set_mode((WIDTH,HEIGHT),0,32)
TAB = []
fpsClock = pygame.time.Clock()
pygame.display.set_caption('Animation')
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, A):
return math.sqrt((A.x-self.x)**2 + (A.y-self.y)**2)
def getTouple(self):
return (self.x,self.y)
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def norm(self):
return math.sqrt(self.x**2 + self.y**2)
class Ball:
def __init__(self):
self.radius = RADIUS
self.center = Point(randrange(RADIUS,WIDTH-RADIUS), randrange(RADIUS,HEIGHT-RADIUS))
vx = randrange(-5,5)
vy = randrange(-5,5)
while vx == 0 or vy == 0:
vx = randrange(-5,5)
vy = randrange(-5,5)
self.velocity = Vector(vx,vy)
self.ball_last_hit = None
def draw(self):
self.center.x += self.velocity.x
self.center.y += self.velocity.y
for ball in TAB:
if ball != self:
if ball.center.distance(self.center) <= 2*RADIUS:
if ball != self.ball_last_hit:
tmp = self.velocity
self.velocity = ball.velocity
ball.velocity = tmp
self.ball_last_hit = ball
if self.center.x - self.radius <= 0:
self.velocity.x = -self.velocity.x
if self.center.x + self.radius >= WIDTH:
self.velocity.x = -self.velocity.x
if self.center.y - self.radius <= 0:
self.velocity.y = -self.velocity.y
if self.center.y + self.radius >= HEIGHT:
self.velocity.y = -self.velocity.y
pygame.draw.circle(DISPLAYSURF, BLUE, self.center.getTouple(), self.radius, 0)
BallNum = 30
for i in range(BallNum):
k = Ball()
TAB.append(k)
while True:
DISPLAYSURF.fill(WHITE)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
for ball in TAB:
ball.draw()
pygame.display.update()
fpsClock.tick(FPS)
Note: instead of using a temp variable, and executing three lines of code, you can swap the balls' velocities with just one this line of code: self.velocity, ball.velocity = ball.velocity, self.velocity.
I hope this answer helped you, and if you have any further questions, please feel free to leave a comment below!
Edit: to get rid of the sticking to the walls, all we need to do is make sure that after a collision with the wall, the ball is not still in contact with the wall, because if it is, it will bounce against the wall indefinitely, and get 'stuck'
After changing the ball's velocity, when it collides with the wall, I just set the center of the ball to one pixel away from the wall, so it is definitely not touching the wall, and this fixed the problem for me.
Here is the new collision detection code, which goes at the end of the draw() method. There are just 4 new lines needed.
if self.center.x - self.radius <= 0:
self.velocity.x = -self.velocity.x
self.center.x = self.radius + 1
if self.center.x + self.radius >= WIDTH:
self.velocity.x = -self.velocity.x
self.center.x = WIDTH - self.radius - 1
if self.center.y - self.radius <= 0:
self.velocity.y = -self.velocity.y
self.center.y = self.radius + 1
if self.center.y + self.radius >= HEIGHT:
self.velocity.y = -self.velocity.y
self.center.y = HEIGHT - self.radius - 1
Note: this simulation gets very tricky if you increase the ball number even higher, because groups of 3 balls start to collide with each other at a time, and your current code is only capable of handling collision between two balls.
I have a huge assignment due in class and Im lost like , asking god to spare me lost. Im making a brick game and the most basic function of getting the ball to bounce of the walls I cant figure out , my teacher is too busy and classmates are competitive , I dont want you to write the code for me, I just dont know how to code it. I keep getting errors and its just been hell the last couple of classes.
import math
import pygame
import random
pygame.init()
screen = pygame.display.set_mode([800,600])
done = False
clock = pygame.time.Clock()
#DEFINE COLORS
WHITE = (255,255,255)
BLUE=(0,102,204)
LIGHT_BLUE=(0,0,204)
pink=(238,130,238)
#import images
#lives = pygame.image.load("heart.png")
# initialize font; must be called after 'pygame.init()' to avoid 'Font not Initialized' error
myfont = pygame.font.SysFont("monospace", 15)
#var carying the space of the game
top = -100
left= -50
right= -750
bottom= -600
angle = math.radians(random.randint(-140,-30))
class game_screen():
def draw_screen():
pygame.draw.rect(screen,BLUE,(50,100,700,600))
def save_button():
pygame.draw.rect(screen,pink,(500,20,50,30),0)
save = "Save"
label = myfont.render(save, 40, (0,0,0))
screen.blit(label, (505, 20))
def quit_button():
pygame.draw.rect(screen,pink,(600,20,50,30),0)
quit1 = "Quit"
label = myfont.render(quit1, 40, (0,0,0))
screen.blit(label, (605, 20))
mX, mY = pygame.mouse.get_pos()
mouseButtons = pygame.mouse.get_pressed()
if mouseButtons[0] == True:
if (mX in range (600-20,600+20) and mY in range (20-20,20+20)):
pygame.quit()
#def display_lives():
#lives_counter = screen.blit(lives,(50,30))
#lives_counter2 = screen.blit(lives,(120,30))
#lives_counter3 = screen.blit(lives,(190,30))
class PADDLE:
def __init__(self,xpos,ypos):
self.x = xpos
self.y = ypos
def draw(self): # draws paddle
pygame.draw.rect(screen,pink,(self.x,self.y,70,20))
def move(self):
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_LEFT]:
if self.x<=50:
self.x=50
else:
self.x -= 10
elif keys[pygame.K_RIGHT]:
if self.x >=680:
self.x = 680
else:
self.x += 10
class BALL:
def __init__(self,paddle1):
self.x = (paddle1.x+35)
self.y = (paddle1.y-5)
self.speed = 0
self.speedX = 0
self.speedY = 0
self.direction = 200
def draw(self):
pygame.draw.circle(screen,WHITE,(self.x,self.y),10)
def bounce(self):
self.direction = (180 - self.direction) % 360
def move_ball(self):
keys = pygame.key.get_pressed() #checking pressed keys
ball_on_paddle = True
if ball_on_paddle == True :
self.x = (paddle1.x+35)
self.y = (paddle1.y-5)
self.speed = 0
if keys[pygame.K_UP] == True:
ball_on_paddle = False
print("a")
self.speed = 10
self.speedX += int(math.cos(angle)* self.speed)
self.speedY += int(math.sin(angle)* self.speed)
print(bottom)
print(self.speedY)
if self.y <= 0:
self.bounce(0)
self.y = 1
if self.x <= 0:
self.direction = (360 - self.direction) % 360
self.x = 1
if self.x > self.screenwidth - self.width:
self.direction = (360 - self.direction) % 360
self.x = self.screenwidth - self.width - 1
paddle1 = PADDLE(350,550)
ball1 = BALL(paddle1)
# MAIN LOOP
while not done:
screen.fill((LIGHT_BLUE))
game_screen.draw_screen()
game_screen.save_button()
game_screen.quit_button()
paddle1.draw()
paddle1.move()
ball1.draw()
ball1.move_ball()
ball1.bounce()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.display.flip()
clock.tick(60)
pygame.quit()
The collission between ball and wall can be detected by comparing the ball's coordinates with the coordinates of the walls. Reflecting the ball means a multiplication of either speedX or speedY - depending on the wall - with -1.
The easiest way to do this is to make a function bounce(self) in your class BALL.
First, you decide which border you touch.
Then, you change the angle of the ball according to which border you bounce on. If you work in a 360-degree system, the angle is mirrored:
around a vertical axis when the ball bounces of the bottom and the top border. So angle = 180 - angle.
around a horizontal axis when the ball bounces of the side borders. So angle = - angle .
And lastly, you have to move the ball back what it has travelled too much.
Like you can see, the ball travels in 1 iteration from C1 to C3', while we want it to go to C3. We can achieve this by reflecting it around the axis BOUNDARY_X - ball_size.
The new x-coordinate of the ball becomes then x = BOUNDARY_X - ball_size - (x - BOUNDARY_X + ball_size) = 2*(BOUNDARY_X - ball_size) - x .
When we cast that into code, we get:
class BALL:
def bounce(self):
if self.x < ball_size:
self.angle = math.pi - self.angle
self.x = 2*ball_size - self.x
elif self.x > DISPLAY_WIDTH - ball_size:
self.angle = math.pi - self.angle
self.x = 2*(DISPLAY_WIDTH - ball_size) - self.x
if self.y < ball_size:
self.angle = - self.angle
self.y = 2*ball_size - self.y
elif self.y > DISPLAY_HEIGHT - ball_size:
self.angle = - self.angle
self.y = 2*(DISPLAY_HEIGHT - ball_size) - self.y