I fixed the last problem but now i've got this.File "main.py", line 103, in main bullet = pygame.Rect ( TypeError: Argument must be rect style object [duplicate] - pygame

This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
Closed 3 months ago.
This is the error I'm getting but I don't see a problem on line 103 with anything
If there really is a problem PLs let me know.For some reason It's not letting me submit this complaint without having more text so thats what Im trying to do.
File "main.py", line 103, in main
bullet = pygame.Rect(
TypeError: Argument must be rect style object

import pygame
import os
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Cosmic Shooters")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
BORDER = pygame.Rect(WIDTH//2-5, 0, 10, HEIGHT)
BULLET_VEL = 8
MAX_BULLETS = 3
FPS = 60
VEL = 5
SPACESHIP_WIDTH, SPACESHIP_HEIGHT = 55, 40
BULLET_VEL = 8
MAX_BULLETS = 3
YELLOW_HIT = pygame.USEREVENT + 1
RED_HIT = pygame.USEREVENT + 2
YELLOW_SPACESHIP_IMAGE = pygame.image.load(os.path.join('Assets', 'spaceship_yellow.png'))
YELLOW_SPACESHIP = pygame.transform.rotate(pygame.transform.scale(YELLOW_SPACESHIP_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT)), 90)
RED_SPACESHIP_IMAGE = pygame.image.load(os.path.join('Assets', 'spaceship_red.png'))
RED_SPACESHIP = pygame.transform.rotate(pygame.transform.scale(RED_SPACESHIP_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT)), 270)
def draw_window(red, yellow, red_bullets, yellow_bullets):
WIN.fill(WHITE)
pygame.draw.rect(WIN, BLACK, BORDER)
WIN.blit(YELLOW_SPACESHIP, (yellow.x, yellow.y))
WIN.blit(RED_SPACESHIP, (red.x, red.y))
for bullet in red_bullets:
pygame.draw.rect(WIN, RED, bullet)
for bullet in yellow_bullets:
pygame.draw.rect(WIN, YELLOW, bullet)
pygame.display.update()
def yellow_handle_movement(keys_pressed, yellow):
if keys_pressed[pygame.K_a] and yellow.x - VEL > 0: # left
yellow.x -= VEL
if keys_pressed[pygame.K_d] and yellow.x + VEL + yellow.width < BORDER.x : # right
yellow.x += VEL
if keys_pressed[pygame.K_w] and yellow.y - VEL > 0: # up
yellow.y -= VEL
if keys_pressed[pygame.K_s] and yellow.y + VEL + yellow.height < HEIGHT - 15 : # down
yellow.y += VEL
def red_handle_movement(keys_pressed, red):
if keys_pressed[pygame.K_LEFT] and red.x - VEL > BORDER.x + BORDER.width: # left
red.x -= VEL
if keys_pressed[pygame.K_RIGHT] and red.x + VEL + red.width < BORDER.x: # right
red.x += VEL
if keys_pressed[pygame.K_UP] and red.y - VEL > 0 : # up
red.y -= VEL
if keys_pressed[pygame.K_DOWN] and red.y + VEL + red.height < HEIGHT - 15 : # down
red.y += VEL
def handle_bullets(yellow_bullets, red_bullets, yellow, red):
for bullet in yellow_bullets:
bullet.x += BULLET_VEL
if red.colliderect(bullet):
pygame.event.post(pygame.event.Event(RED_HIT))
yellow_bullets.remove(bullet)
for bullet in red_bullets:
bullet.x -= BULLET_VEL
if yellow.colliderect(bullet):
pygame.event.post(pygame.event.Event(YELLOW_HIT))
yellow_bullets.remove(bullet)
def main():
red = pygame.Rect(700, 300, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
yellow = pygame.Rect(100, 300, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
red_bullets = []
yellow_bullets = []
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LCTRL and len(yellow_bullets) < MAX_BULLETS:
bullet = pygame.Rect(
yellow.x + yellow.width, yellow.y, yellow.height//2 - 2, 10, 5)
yellow_bullets.append(bullet)
if event.key == pygame.K_RCTRL and len(red_bullets) < MAX_BULLETS:
bullet = pygame.Rect(
red.x, red.y + red.height//2 - 2, 10, 5)
red_bullets.append(bullet)
print(red_bullets, yellow_bullets)
keys_pressed = pygame.key.get_pressed()
yellow_handle_movement(keys_pressed, yellow)
red_handle_movement(keys_pressed, red)
handle_bullets(yellow_bullets, red_bullets, yellow, red)
draw_window(red, yellow, red_bullets, yellow_bullets)
pygame.quit()
if __name__ == "__main__":
main()
Again it's not letting me go without more details but I really don't know could possibly be the issue.

Not all pygame.events are key presses, you should check what type of event it is before accessing the key attribute.

Related

Cannot move player on pygame

i am learning pygame.I get a little problem with moving and i dont know
how to make so that player move.i cannot understand where my mistake.Can you help me on this problem.And i will so appriciate if you give me some advice on pygame.I'm such a newbie
import pygame
widthSurface = 640
heightSurface = 480
keys = [False, False, False, False]
playerpos = [100, 100]
vel = 5
# images
player = pygame.image.load('resources/images/dude.png')
grass = pygame.image.load('resources/images/grass.png')
castle = pygame.image.load('resources/images/castle.png')
def blitGrassAndCastle():
for x in range(widthSurface // grass.get_width() + 1):
for y in range(heightSurface // grass.get_height() + 1):
surface.blit(grass, (x * grass.get_width(), y * grass.get_height()))
surface.blit(castle, (0, 30))
surface.blit(castle, (0, 135))
surface.blit(castle, (0, 240))
surface.blit(castle, (0, 345))
if __name__ == '__main__':
pygame.init()
pressed = pygame.key.get_pressed()
surface = pygame.display.set_mode((widthSurface, heightSurface))
while True:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
if pressed[pygame.K_LEFT]:
playerpos[0] -= vel
if pressed[pygame.K_RIGHT]:
playerpos[0] += vel
if pressed[pygame.K_UP]:
playerpos[1] -= vel
if pressed[pygame.K_DOWN]:
playerpos[1] += vel
blitGrassAndCastle()
surface.blit(player, playerpos)
pygame.display.update()
Thank you in advanced!
pygame.key.get_pressed() returns a list with the current state of all keyboard buttons. You need to get the state of the keys ** in ** the application loop every frame, rather than once before the loop. The states you get before the loop will never change.
if __name__ == '__main__':
pygame.init()
# pressed = pygame.key.get_pressed() # <-- DELETE
surface = pygame.display.set_mode((widthSurface, heightSurface))
while True:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
pressed = pygame.key.get_pressed() # <--- INSERT
if pressed[pygame.K_LEFT]:
playerpos[0] -= vel
if pressed[pygame.K_RIGHT]:
playerpos[0] += vel
if pressed[pygame.K_UP]:
playerpos[1] -= vel
if pressed[pygame.K_DOWN]:
playerpos[1] += vel
blitGrassAndCastle()
surface.blit(player, playerpos)
pygame.display.update()

Pygame unable to create a function which will make the snake eat the food and also close the game and also increase snake size

Pygame unable to create a function which will make the snake eat the food and also close the game.I want to write a funtion which can make the snake eat the food and increase its length.I have made a funtion which has drawn the circle and the rectangle.
from random import randrange
import pygame
from pygame import Color, Surface, event, image, key
import random
import math
pygame.init()
icon = pygame.image.load(r"D:\\icon.png")
blue=(0,0,255)
red =(255,0,0)
yellow = (255,255,0)
screen_size = (720,600)
title = 'Snake Game'
vel = 0
vel_1 = 0
x = random.randrange(100,690)
y = randrange(50,550)
x_enemy = random.randrange(100,690)
y_enemy = randrange(50,550)
screen = pygame.display.set_mode(screen_size)
caption = pygame.display.set_caption(title)
def snake(surface,color,dim):
pygame.draw.rect(surface,color,dim)
def food(surface,color,center,radius):
pygame.draw.circle(surface,color,center,radius)
score = 0
running = True
while running:
dim = (x,y,30,30)
centre = (80,80)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
vel = -0.5
vel_1 = 0
if keys[pygame.K_RIGHT]:
vel = 0.5
vel_1 = 0
if keys[pygame.K_UP]:
vel_1 = -0.5
vel = 0
if keys[pygame.K_DOWN]:
vel_1 = 0.5
vel = 0
if keys[pygame.K_ESCAPE]:
running = False
if x >= 690 :
running = False
if x <= 0 :
running = False
if y >= 570:
running = False
if y <= 0 :
running = False
x += vel
y += vel_1
screen.fill((255, 255, 255))
snake(screen,blue,dim)
food(screen,red,[x_enemy,y_enemy],7)
pygame.display.update()
Firstly, you should read about pygame.Rect.colliderect. It's about collision so you can use it for snake eating the food.
Arrays(x-axis array and y-axis array), can be used for snake length. (In Python can be used Lists instead of Arrays) In this arrays, every array's element contains one position of square and this position represents square's topleft(x,y). I already drew a sketch about it that might be more expressive.
(the meaning of "durum" is status)

Pygame bounce off ceiling acting strangely

I have been working on a pygame project where a player controls a rectangle that hits a ball. When the ball hit the side walls, it bounces off perfectly, same with the floor, but when it hits the top, it works very weirdly in a way I can't describe. If anyone wants to test this, my code is below, just hit the ball onto the roof and it will show what I am trying to explain. I would like it so you can't ram the ball into the ceiling so it goes off the screen and for it to be a clean bounce instead of what it dose right now and sort of rolls down if it touches the ceiling.
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
if ballrect.top <= 0:
# Just invert the y-velocity to bounce.
ball_vel.y *= 0.4 # Change this value to adjust the elasticity.
# 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()
Just set the ballrect.top coordinate to 1, so that it stays in the game area and also update the ball_pos.y afterwards.
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

Pygame sin,cos,tan caculating circular movement path

I have been struggling for few days know trying to figure out how to make for example a image move in circular path. I have looked other posts here but i just can't get it.
So how do i move image in circular path. My code only moves my image 45 degrees and stops then. I would need it to go full circle and continue doing it.
Current Code:
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
CENTER = (200, 200)
RADIUS = 100
x = 0
y = 0
satelliteCenter = (CENTER[0]+RADIUS, CENTER[1])
run = 1
while run == 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = 0
pygame.quit()
mouse = pygame.mouse.get_pos()
vector = x-CENTER[0], y-CENTER[1]
x +=1
distance = (vector[0]**2 + vector[1]**2)**0.5
if distance > 0:
scalar = RADIUS / distance
satelliteCenter = (
int(round( CENTER[0] + vector[0]*scalar )),
int(round( CENTER[1] + vector[1]*scalar )) )
screen.fill((255,255,255))
pygame.draw.circle(screen, (71,153,192), CENTER, RADIUS)
pygame.draw.circle(screen, (243,79,79), satelliteCenter, 16)
pygame.display.update()
You can just use a pygame.math.Vector2 and rotate it each frame, scale it by the radius and add it to the CENTER position to get the current center of the small circle.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
CENTER = (200, 200)
RADIUS = 100
# A unit vector pointing to the right.
direction = pygame.math.Vector2(1, 0)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
direction.rotate_ip(4) # By 4 degrees.
# Normalize it, so that the length doesn't change because
# of floating point inaccuracies.
direction.normalize_ip()
# Scale direction vector, add it to CENTER and convert to ints.
ball_pos = [int(i) for i in CENTER+direction*RADIUS]
screen.fill((255,255,255))
pygame.draw.circle(screen, (71,153,192), CENTER, RADIUS)
pygame.draw.circle(screen, (243,79,79), ball_pos, 16)
pygame.display.update()
clock.tick(30)
Edit: If you want the red ball to follow the mouse, then your example actually works if you set x and y to the mouse pos x, y = pygame.mouse.get_pos().
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
CENTER = (200, 200)
RADIUS = 100
x = 0
y = 0
satelliteCenter = (CENTER[0]+RADIUS, CENTER[1])
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
x, y = pygame.mouse.get_pos()
vector = x-CENTER[0], y-CENTER[1]
distance = (vector[0]**2 + vector[1]**2)**0.5
if distance > 0:
scalar = RADIUS / distance
satelliteCenter = (
int(round( CENTER[0] + vector[0]*scalar )),
int(round( CENTER[1] + vector[1]*scalar ))
)
screen.fill((255,255,255))
pygame.draw.circle(screen, (71,153,192), CENTER, RADIUS)
pygame.draw.circle(screen, (243,79,79), satelliteCenter, 16)
pygame.display.update()

Difficulty with movement in game close to Pong (pygame)

Note: I am really new in programming.
At first, I am just going to post the code I have written:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode([640, 480])
paddle = pygame.image.load("pulgake.png")
pygame.display.set_caption("PONG!")
WHITE = [0, 0, 0]
back = pygame.image.load("taust.png")
screen.blit(back, (0, 0))
screen.blit(paddle, (600, 240))
pygame.display.flip()
xpaddle = 600
ypaddle = 240
delay = 10
interval = 10
pygame.key.set_repeat(delay, interval)
class Ball:
def __init__(self):
self.pos = [0,0]
self.velocity = [1,0]
def move():
self.pos[0] += self.velocity[0]
self.pos[1] += self.velocity[1]
if self.pos[0] > 10:
self.pos[0] *= -1
elif self.pos[1] > 470: # My background has a frame
self.pos[1] *= -1
elif self.pos[1] < 10:
self.pos[1] *= -1
elif self.pos[0] > 605:
False
def draw(screen):
pygame.draw.circle(screen,WHITE,self.pos,15)
pall = Ball()
while True:
pall.move()
screen.blit(back, (0,0))
screen.blit(paddle, (xpaddle, ypaddle))
pygame.display.flip()
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
if i.key == pygame.K_UP:
ypaddle = ypaddle - 10
if ypaddle < 10:
ypaddle = 10
elif i.key == pygame.K_DOWN:
ypaddle = ypaddle + 10
if ypaddle > 410:
ypaddle = 410
I am getting this error-
line 44, in <module>
pall.move()
TypeError: move() takes no arguments (1 given)
So, I want to get a ball that bounces off the walls (and paddle as well, but I don't know yet how)
Also, I would be really grateful if somebody helps me to get a stopwatch in this game, showing time "survived".
EDIT: added def move(self)
Now, a bigger problem occured:
draw() and move() - global name"self" not defined.
I really can't figure out this one.
You are calling ball.move which doesn't exist, because move needs to be indented once more.
If you want "do stuff while key is held down" You can use getkeystate and use KEYDOWN events when you want 'do stuff once, when key is pressed'
see both here: https://stackoverflow.com/a/13207525/341744