I have to move the rectangular object straight through the pygame window. I have tried some code with pygame. The code is
import pygame
from itertools import cycle
pygame.init()
screen = pygame.display.set_mode((300, 300))
s_r = screen.get_rect()
player = pygame.Rect((100, 100, 50, 50))
timer = pygame.time.Clock()
movement = "straight"
x = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
if movement == 'straight':
x += 50
screen.fill(pygame.color.Color('Black'))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
pygame.display.flip()
timer.tick(25)
Here the image didnt moves. What I need is that the image must be moved in a straight way.
x is adding, but that does not affect player, which actually affects the drawing of the rectangle.
import pygame
from itertools import cycle
pygame.init()
screen = pygame.display.set_mode((300, 300))
s_r = screen.get_rect()
timer = pygame.time.Clock()
movement = "straight"
x = 0
player = pygame.Rect((x, 100, 50, 50))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
if movement == 'straight':
x += 10
player = pygame.Rect((x, 100, 50, 50))
if x >= 300:
x = 0
screen.fill(pygame.color.Color('Black'))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
pygame.display.flip()
timer.tick(25)
You need to adjust the player rectangle each time you change x. From http://www.pygame.org/docs/ref/rect.html, you can see that the first two arguments are "left" and "top". So, if you want to the rectangle to move from left to right, you'll want something like this:
player = pygame.Rect((100 + x, 100, 50, 50))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
import pygame
BLACK = pygame.color.Color('Black')
GREY = pygame.color.Color('Grey')
pygame.init()
screen = pygame.display.set_mode((300, 300))
screen_rect = screen.get_rect()
timer = pygame.time.Clock()
movement = "straight"
player = pygame.Rect(0, 100, 50, 50) # four aguments in place of tuple (,,,)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if movement == 'straight':
player.x += 10
if player.x >= 300: # check only when `player.x` was changed
player.x = 0
screen.fill(BLACK)
pygame.draw.rect(screen, GREY, player)
pygame.display.flip()
timer.tick(25)
BTW:
don't use raise to exit program.
use readable variable - not s_r but screen_rect
you don't need x - you have player.x
you can create rectangle only once
remove repeated empty lines when you add code to question
Related
I'm making a game for a school assignment and every time the character moves, it moves back to its original position. I'm not particularly well versed in pygame but I've looked over time and time again and I can't really figure out what the problem is.
Any tips?
import math
import sys
import pygame
def game():
pygame.init()
clock = pygame.time.Clock()
white = (255,255,255)
black = (0,0,0)
purple = (127, 84, 253)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
running = False
player_x = 12
player_y = 12
velocity = 10
surface = pygame.display.set_mode((400,400))
player = pygame.Rect(player_x,player_y,20,20)
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:player.y-=50
if keys[pygame.K_a]:player.x-=50
if keys[pygame.K_s]:player.y+=50
if keys[pygame.K_d]:player.x+=50
if keys[pygame.K_ESCAPE]:pygame.quit()
pygame.display.flip()
pygame.display.update()
surface.fill((255, 255, 255))
clock.tick(40)
pygame.quit()
game()```
player_x = 12
player_y = 12
velocity = 10
Should be out of the while loop you are resetting them each frame which cause the problem
I am making a pong game and the ball object leaves a trail when it moves and I was wondering how to stop it from doing this any help would be greatly appreciated. Thank you in advance.
Here is my code:
import sys
import pygame
pygame.init()
clock = pygame.time.Clock()
# screen setup
screen_width = 1200
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))
background = pygame.image.load("spacebackground.png").convert_alpha()
pygame.mouse.set_visible(False)
pygame.display.set_caption('pong')
# set up player and opponent and ball rect
player = pygame.Rect(screen_width - 20,screen_height/2 - 70,10,140)
opponent = pygame.Rect(10,screen_height/2 - 70,10,140 )
ball = pygame.Rect(screen_width/2-15, screen_height/2 - 15,30, 30)
ball_speed_x = 7
ball_speed_y = 7
# defining clock and colour
red = (0,0,0)
clock = pygame.time.Clock()
while True:
pygame.display.update(ball)
pygame.display.flip()
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
ball.x += ball_speed_x
ball.y += ball_speed_y
# Drawing the rects
pygame.draw.rect(background, red, player)
pygame.draw.rect(background, red, opponent)
pygame.draw.ellipse(background, red, ball)
pygame.display.update(ball)
clock.tick(60)
Draw the objects on the screen instead of on the background:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
ball.x += ball_speed_x
ball.y += ball_speed_y
# draw background on the screen
screen.blit(background, (0, 0))
# draw objects on the screen
pygame.draw.rect(screen, red, player)
pygame.draw.rect(screen, red, opponent)
pygame.draw.ellipse(screen, red, ball)
# update the display
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Basically, when I click on an image I want the image to move to a new different location. When I click again, it should move again.
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((1420, 750))
pygame.display.set_caption("Soccer Game")
icon = pygame.image.load('soccer-ball-variant.png')
pygame.display.set_icon(icon)
ball = pygame.image.load('soccer2.png')
ballrect = ball.get_rect()
X = random.randrange(0, 1100)
Y = random.randrange(0, 600)
def player():
screen.blit(ball, (X, Y))
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = event.pos
if ball.get_rect().collidepoint(x, y):
X = random.randrange(0, 1100)
Y = random.randrange(0, 600)
player()
screen.fill((255, 255, 255))
player()
pygame.display.update()
The problem is that this program only works when i click on the left-up corner of the screen, and not on the ball. I am a biginner in the pygame module, but i think the problem is this if statement:
if ball.get_rect().collidepoint(x, y):
X = random.randrange(0, 1100)
Y = random.randrange(0, 600)
player()
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, that always starts at (0, 0) since a Surface object has no position. A Surface is blit at a position on the screen. The position of the rectangle can be specified by a keyword argument. For example, the top leftof the rectangle can be specified with the keyword argument topleft. These keyword argument are applied to the attributes of the pygame.Rect before it is returned (see pygame.Rect for a full list of the keyword arguments).
if ball.get_rect().collidepoint(x, y):
if ball.get_rect(topleft = (X, Y)).collidepoint(x, y):
However, I recommend removing the X and Y variables, but using ballrect instead:
ballrect = ball.get_rect()
ballrect.x = random.randrange(0, 1100)
ballrect.y = random.randrange(0, 600)
def player():
screen.blit(ball, ballrect)
if ballrect.collidepoint(event.pos):
ballrect.x = random.randrange(0, 1100)
ballrect.y = random.randrange(0, 600)
Complete example:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((1420, 750))
pygame.display.set_caption("Soccer Game")
icon = pygame.image.load('soccer-ball-variant.png')
pygame.display.set_icon(icon)
ball = pygame.image.load('soccer2.png')
ballrect = ball.get_rect()
ballrect.x = random.randrange(0, 1100)
ballrect.y = random.randrange(0, 600)
def player():
screen.blit(ball, ballrect)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if ballrect.collidepoint(event.pos):
ballrect.x = random.randrange(0, 1100)
ballrect.y = random.randrange(0, 600)
screen.fill((255, 255, 255))
player()
pygame.display.update()
I am trying to get this square to go across my screen and back along the path it came by but it just stays where it is. It's a clash between two if statements and I have tried using a break statement but that just stopped everything.
if squareX < 100:
squareX += 1
elif squareX > 900:
squareX -= 1
You have a state in your game, which describes in which directions your rect moves. So when you go out of screen, this state changes.
When you update your game (which is one of the three things you do in your main loop: handle events, update the game state, draw the game), you look at your state and decide in which direction you move your rect. Then you check if it's out of the screen.
Here's a minimal example:
import pygame
def main():
screen = pygame.display.set_mode((400, 200))
clock = pygame.time.Clock()
rect = pygame.Rect(100, 100, 32, 32)
direction = 1
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
return
rect.move_ip(direction * 3, 0)
if not screen.get_rect().contains(rect):
direction *= -1
screen.fill((30, 30, 30))
pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
clock.tick(120)
pygame.display.flip()
if __name__ == '__main__':
main()
easy, you first need to understand what a sprite class is.
follow the following code:
import pygame
class MovingSquare(pygame.sprite.Sprite):
def __init__(self, location, speed):
pygame.sprite.Sprite.__init__(self)
image_surface = pygame.surface.Surface([30, 30])
image_surface.fill([0,0,0])
self.image = image_surface.convert()
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
self.speed=speed
def move(self):
self.rect=self.rect.move(self.speed)
if self.rect.right>screen.get_width() or self.rect.left<0:
self.speed[0]=-self.speed[0]
pygame.init()
screen=pygame.display.set_mode([640, 480])
screen.fill([255, 255, 255])
x=5
y=0
squareX=MovingSquare([50, 50], [x, y])
clock=pygame.time.Clock()
running=True
while running:
clock.tick(30)
square.move()
screen.blit(squareX.image, squareX.rect)
pygame.display.flip()
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
the only problem is that it doesn't erase it's tracks so i suggest using an image file instead.
I've have this dodging aliens game and it's not working. I can get the front begin screen to open but then when I hit enter to start it crashes and freezes. I've tried running it from python.exe instead of just IDLE but in that case it just pops up then closes right down. A few errors popped up the first few times I tried to run it but now there are no errors indicating what might be wrong. It just stops responding. What am I doing wrong here?
import pygame, random, sys
from pygame.locals import *
def startGame():
if event.type == K_ENTER:
if event.key == K_ESCAPE:
sys.exit()
return
def playerCollision():
for a in aliens:
if playerRect.colliderect(b['rect']):
return True
return False
pygame.init()
screen = pygame.display.set_mode((750,750))
clock = pygame.time.Clock()
pygame.display.set_caption('Dodge the Aliens')
font = pygame.font.SysFont(None, 55)
playerImage = pygame.image.load('')
playerRect = playerImage.get_rect()
alienImage = pygame.image.load('')
drawText('Dodge the Aliens!', font, screen, (750 / 3), (750 / 3))
drawText('Press ENTER to start.', font, screen, (750 / 3) - 45, (750 / 3) + 65)
pygame.display.update()
topScore = 0
while True:
aliens = []
score = 0
playerRect.topleft = (750 /2, 750 - 50)
alienAdd = 0
while True:
score += 1
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]: x -=3
if pressed[pygame.K_RIGHT]: x += 3
if pressed[pygame.K_ESCAPE]: sys.exit()
alienAdd += 1
if alienAdd == addedaliens:
aliendAdd = 0
alienSize = random.randint(10, 40)
newAlien = {'rect': pygame.Rect(random.randint(0, 750 - alienSize), 0 -alienSize, alienSize, alienSize), 'speed': random.randint(1, 8), 'surface':pygame.transform.scale(alienImage, (alienSize, alienSize)), }
aliens.append(newAlien)
for a in aliens[:]:
if a['rect'].top > 750:
aliens.remove(a)
screen.fill(0,0,0)
drawText('Score %s' % (score), font, screen, 10, 0)
screen.blit(playerImage, playerRect)
for a in aliens:
screen.blit(b['surface'], b['rect'])
pygame.display.update()
if playerCollision(playerRect, aliens):
if score > topScore:
topScore = score
break
clock.tick(60)
drawText('Game Over!', font, screen, (750 / 3), ( 750 / 3))
drawText('Press ENTER To Play Again.', font, screen, ( 750 / 3) - 80, (750 / 3) + 50)
pygame.display.update()
startGame()
Here's my new code after modifying it some
import pygame, random, sys
from pygame.locals import*
alienimg = pygame.image.load('C:\Python27\alien.png')
playerimg = pygame.image.load('C:\Python27\spaceship.png')
def playerCollision(): # a function for when the player hits an alien
for a in aliens:
if playerRect.colliderect(b['rect']):
return True
return False
def screenText(text, font, screen, x, y): #text display function
textobj = font.render(text, 1, (255, 255, 255))
textrect = textobj.get_rect()
textrect.topleft = (x,y)
screen.blit(textobj, textrect)
def main(): #this is the main function that starts the game
pygame.init()
screen = pygame.display.set_mode((750,750))
clock = pygame.time.Clock()
pygame.display.set_caption('Dodge the Aliens')
font = pygame.font.SysFont("monospace", 55)
pressed = pygame.key.get_pressed()
aliens = []
score = 0
alienAdd = 0
addedaliens = 0
while True: #our while loop that actually runs the game
for event in pygame.event.get(): #key controls
if event.type == KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit()
elif event.type == KEYDOWN and event.key == pygame.K_LEFT:
playerRect.x -= 3
elif event.type == KEYDOWN and event.key == pygame.K_RIGHT:
playerRect.x += 3
playerImage = pygame.image.load('C:\\Python27\\spaceship.png').convert() # the player images
playerRect = playerImage.get_rect()
playerRect.topleft = (750 /2, 750 - 50)
alienImage = pygame.image.load('C:\\Python27\\alien.png').convert() #alien images
alienAdd += 1
pygame.display.update()
if alienAdd == addedaliens: # randomly adding aliens of different sizes and speeds
aliendAdd = 0
alienSize = random.randint(10, 40)
newAlien = {'rect': pygame.Rect(random.randint(0, 750 - alienSize), 0 -alienSize, alienSize, alienSize), 'speed': random.randint(1, 8), 'surface':pygame.transform.scale(alienImage, (alienSize, alienSize)), }
aliens.append(newAlien)
for a in aliens[:]:
if a['rect'].top > 750:
aliens.remove(a) #removes the aliens when they get to the bottom of the screen
screen.blit(screen, (0,0))
screenText('Score %s' % (score), font, screen, 10, 0)
screen.blit(playerImage, playerRect)
for a in aliens:
screen.blit(b['surface'], b['rect'])
pygame.display.flip()
if playerCollision(playerRect, aliens):
if score > topScore:
topScore = score
break
clock.tick(60)
screenText('Game Over!', font, screen, (750 / 6), ( 750 / 6))
screenText('Press ENTER To Play Again.', font, screen, ( 750 / 6) - 80, (750 / 6) + 50)
pygame.display.update()
main()
I still see several issues with your code and I think you're trying to do too much at once for the very beginning. Try to keep it as simple as possible. Try creating a display and draw some image:
import pygame
pygame.init()
display = pygame.display.set_mode((750, 750))
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
display.blit(img, (0, 0))
pygame.display.flip()
You'll have to adjust the img path of course. Running this you should either get an explicit Error (which you should then post in another thread) or see your img on the screen. BUT the program will not respond as there's no event handling and no main loop at all.
To avoid this, you could introduce a main loop like:
import sys
import pygame
pygame.init()
RESOLUTION = (750, 750)
FPS = 60
display = pygame.display.set_mode(RESOLUTION)
clock = pygame.time.Clock()
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
while True: # <--- game loop
# check quit program
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# clear the screen
display.fill((0, 0, 0))
# draw the image
display.blit(img, (0, 0))
# update the screen
pygame.display.flip()
# tick the clock
clock.tick(FPS)
This should result in a program that displays the same img over and over, and it can be quit properly using the mouse. But still it's like a script, and if someone imported this, it would execute immediately, which is not what we want. So let's fix that as well and wrap it all up in a main function like this:
import sys
import pygame
#defining some constants
RESOLUTION = (750, 750)
FPS = 60
def main(): # <--- program starts here
# setting things up
pygame.init()
display = pygame.display.set_mode(RESOLUTION)
clock = pygame.time.Clock()
img = pygame.image.load("""C:\\Game Dev\\alien.png""")
while True: # <--- game loop
# check quit program
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# clear the screen
display.fill((0, 0, 0))
# draw the image
display.blit(img, (0, 0))
# update the screen
pygame.display.flip()
# tick the clock
clock.tick(FPS)
if __name__ == "__main__":
main()
The 'if name == "main":' ensures that the program does not execute when it's imported.
I hope this helps. And remember: Don't try too much all at once. Take small steps, one after another, and try to keep the control over your program. If needed, you can even put a print statement after every single line of code to exactly let you know what your program does and in what order.