Hey guys I have been trying to move the ball image in a square manner on the screen with pygame. I have tried many times but it does not work. Please see my code below.
import time
import pygame, sys
from pygame.locals import *
pygame.init()
clocks = pygame.time.Clock()
surfaceObject = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Bounce')
mousey,mousex = 0,0
imgx = 10
imgy = 10
pixmove = 60
tiger = [2,2]
movement = 'down'
background = pygame.image.load('bg.jpg').convert()
ball = pygame.image.load('ball.jpg').convert_alpha()
pygame.mixer.music.load('yeah.mp3')
while True:
time.sleep(1)
if movement == 'down':
imgx += pixmove
if imgx < 640:
tiger[0] - tiger[1]
elif movement == 'right':
imgx += pixmove
if imgx < 0:
movement = 'up'
elif movement == 'up':
imgy -= pixmove
if imgy < 0:
movement = 'left'
elif movement == 'left':
imgx -= pixmove
if imgx < 0:
movement = 'down'
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
surfaceObject.blit(background,(mousex,mousey))
surfaceObject.blit(ball,(imgx,imgy))
pygame.mixer.music.play()
pygame.display.update()
clocks.tick(50)
When I run this code the ball moves in a straight way and the ball does not bounce back when it touches the end.
My goal is to rotate the ball in a square manner across the screen. I have tried changing the pixmove variable but it did not solve my problem.
Hope you guys can help me out ..Thanx in advance
Your indentation is totally broken, so I can't say what's going.
However, moving the image in a square fashion is easy. Just create a Rect in which the object should move, and once the object leaves the Rect, change the direction.
Take a look at the following example:
import pygame
from itertools import cycle
pygame.init()
screen = pygame.display.set_mode((300, 300))
# move inside the screen (or any other Rect)
s_r = screen.get_rect()
player = pygame.Rect((100, 100, 50, 50))
timer = pygame.time.Clock()
speed = 5
up, down, left, right = (0, -speed), (0, speed), (-speed, 0), (speed, 0)
dirs = cycle([up, right, down, left])
dir = next(dirs)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
# move player
player.move_ip(dir)
# if it's outside the screen
if not s_r.contains(player):
# put it back inside
player.clamp_ip(s_r)
# and switch to next direction
dir = next(dirs)
screen.fill(pygame.color.Color('Black'))
pygame.draw.rect(screen, pygame.color.Color('Grey'), player)
pygame.display.flip()
timer.tick(25)
Since we determined that what you actually want to do is for the ball to bounce off the edges, look here :
Why isn't the ball bouncing back?
In summary, what needs to happen is that you need to keep track of the direction the ball is going (in terms of it's vertical and horizontal movement) and change them as you hit a wall.
You seriously want to fix your indenting, as that leads your code to be highly ununderstandable.
If you want to move something, such as a circle, in a square formation, that is pretty easy:
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((1200, 600))
x, y = (100, 100)
dir = 'right'
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
DISPLAYSURF.fill((0, 0, 0))
pygame.draw.circle(DISPLAYSURF, (255, 255, 255), (x, y), 10)
if dir == 'right':
x+=14
if x >= 1100:
dir = 'down'
elif dir == 'down':
y+=14
if y >= 500:
dir = 'left'
elif dir == 'left':
x-=14
if x <= 100:
dir = 'up'
elif dir == 'up':
y-=14
if y <= 100:
dir = 'right'
pygame.display.flip()
Related
I learned how to print image in pygame, but I don't know how to make a dynamic position(It can change the image position by itself). What did I miss? Here's my attempt.
import pygame
screen_size = [360,600]
screen = pygame.display.set_mode(screen_size)
background = pygame.image.load("rocketship.png")
keep_alive = True
while keep_alive:
planet_x = 140
o = planet_x
move_direction = 'right'
if move_direction == 'right':
while planet_x == 140 and planet_x < 300:
planet_x = planet_x + 5
if planet_x == 300:
planet_x = planet_x - 5
while planet_x == 0:
if planet_x == 0:
planet_x+=5
screen.blit(background, [planet_x, 950])
pygame.display.update()
You don't need nested loops to animate objects. You have one loop, the application loop. Use it! You need to redraw the entire scene in each frame. Change the position of the object slightly in each frame. Since the object is drawn at a different position in each frame, the object appears to move smoothly.
Define the path the object should move along by a list of points and move the object from one point to another.
Minimal example
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
corner_points = [(100, 100), (300, 300), (300, 100), (100, 300)]
pos = corner_points[0]
speed = 2
def move(pos, speed, points):
direction = pygame.math.Vector2(points[0]) - pos
if direction.length() <= speed:
pos = points[0]
points.append(points[0])
points.pop(0)
else:
direction.scale_to_length(speed)
new_pos = pygame.math.Vector2(pos) + direction
pos = (new_pos.x, new_pos.y)
return pos
image = pygame.image.load('bird.png').convert_alpha()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = move(pos, speed, corner_points)
image_rect = image.get_rect(center = pos)
window.fill(0)
pygame.draw.lines(window, "gray", True, corner_points)
window.blit(image, image_rect)
pygame.display.update()
pygame.quit()
exit()
I learned how to print image in pygame, but I don't know how to make a dynamic position(It can change the image position by itself). What did I miss? Here's my attempt.
import pygame
screen_size = [360,600]
screen = pygame.display.set_mode(screen_size)
background = pygame.image.load("rocketship.png")
keep_alive = True
while keep_alive:
planet_x = 140
o = planet_x
move_direction = 'right'
if move_direction == 'right':
while planet_x == 140 and planet_x < 300:
planet_x = planet_x + 5
if planet_x == 300:
planet_x = planet_x - 5
while planet_x == 0:
if planet_x == 0:
planet_x+=5
screen.blit(background, [planet_x, 950])
pygame.display.update()
You don't need nested loops to animate objects. You have one loop, the application loop. Use it! You need to redraw the entire scene in each frame. Change the position of the object slightly in each frame. Since the object is drawn at a different position in each frame, the object appears to move smoothly.
Define the path the object should move along by a list of points and move the object from one point to another.
Minimal example
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
corner_points = [(100, 100), (300, 300), (300, 100), (100, 300)]
pos = corner_points[0]
speed = 2
def move(pos, speed, points):
direction = pygame.math.Vector2(points[0]) - pos
if direction.length() <= speed:
pos = points[0]
points.append(points[0])
points.pop(0)
else:
direction.scale_to_length(speed)
new_pos = pygame.math.Vector2(pos) + direction
pos = (new_pos.x, new_pos.y)
return pos
image = pygame.image.load('bird.png').convert_alpha()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pos = move(pos, speed, corner_points)
image_rect = image.get_rect(center = pos)
window.fill(0)
pygame.draw.lines(window, "gray", True, corner_points)
window.blit(image, image_rect)
pygame.display.update()
pygame.quit()
exit()
I am building a game in pygame where there is a red target that moves up and down on the right side of the screen and a ship on the left side of the screen the moves up and down that fires bullets (which is just a blue rectangle) at the target.
My ship, and my target start in the center of each side of the screen and are properly moving. The problem that I have is when I 'fire' a bullet the bullet is getting drawn at the ship's original position, not where the ship has moved to on the screen.
I have the bullet's rect set to the ship image's rect outside of my while loop, but I would think that it would get updated as my ship moves up and down on the screen.
import pygame
import pygame.sprite
import sys
screen_width = 1200
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
screen_rect = screen.get_rect()
image = pygame.image.load('ship.bmp')
image_rect = image.get_rect()
image_rect.midleft = screen_rect.midleft
target_rect = pygame.Rect(400, 0, 100, 100)
target_color = (255, 0, 0)
target_rect.midright = screen_rect.midright
target_direction = 1
bullet_rect = pygame.Rect(0, 0, 15, 3)
bullet_rect.midright = image_rect.midright
bullet_color = (0, 0, 255)
fire_bullet = False
while True:
screen.fill((0, 255, 0))
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
sys.exit()
# Move the ship up and down
elif event.key == pygame.K_UP:
image_rect.y -= 45
elif event.key == pygame.K_DOWN:
image_rect.y += 45
# Active bullet fired
elif event.key == pygame.K_SPACE:
fire_bullet = True
elif event.type == pygame.QUIT:
sys.exit()
# Move the bullet across the screen if fired
if fire_bullet:
screen.fill(bullet_color, bullet_rect)
bullet_rect.x += 1
# Move the Target up and down
target_rect.y += target_direction
if target_rect.bottom >= screen_height:
target_direction *= -1
elif target_rect.top <= 0:
target_direction *= -1
screen.fill(target_color, target_rect)
screen.blit(image, image_rect)
pygame.display.flip()
I have the bullet's rect set to the ship image's rect outside of my while loop, but I would think that it would get updated as my ship moves up and down on the screen.
That's not it. You just set the position of the rect, there is not automatic update. You have to write the code to keep them in sync.
But even simpler, in your case you could create the bullet rect when you shot. Move the bullet creation in the loop like this:
elif event.key == pygame.K_SPACE:
bullet_rect = pygame.Rect(0, 0, 15, 3)
bullet_rect.midright = image_rect.midright
bullet_color = (0, 0, 255)
fire_bullet = True
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
I'm making a game using the default Python IDLE and Pygame. I am creating a simple cat animation but there is a problem when I try to run the module. A black screen just appears and the heading just says 'Animation NOT RESPONDING', below I have listed the code used for this animation. Thanks for the help!
Thanks, just edited it, does this look better?
import pygame, sys
from pygame.locals import *
pygame.init()
FPS = 30
fpsClock = pygame.time.Clock()
# set up the window
DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32)
pygame.display.set_caption('Animation')
WHITE = (255, 255, 255)
catImg = pygame.image.load('cat.png')
catx = 10
caty = 10
direction = 'right'
while True: # the main game loop
DISPLAYSURF.fill(WHITE)
if direction == 'right':
catx += 5
if catx == 280:
direction = 'down'
elif direction == 'down':
caty += 5
if caty == 220:
direction = 'left'
elif direction == 'left':
catx -= 5
if caty == 10:
direction = 'up'
elif direction == 'up':
caty -= 5
if caty == 10:
direction = 'right'
DISPLAYSURF.blit(catImg, (catx, caty))
for event in pygame.eventget():
if event.type == QUIT:
pygame.exit()
sys.exit()
pygame.display.update()
fpsClock.tick(FPS)
You can re-edit your posts for typos, there's a link at the end.
The problem is event handling never is ran, unless both direction == 'up' and caty == 10. The window then stops responding, since it can't get messages.
while True: # the main game loop
# events
for event in pygame.event.get():
if event.type == QUIT:
pygame.exit()
sys.exit()
# movement
# ... snip ...
# drawing
DISPLAYSURF.fill(Color("white"))
DISPLAYSURF.blit(catImg, (catx, caty))
pygame.display.update()
fpsClock.tick(FPS)