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()
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'm making the Super Mario Bros. game on python using the pygame library. I wanted to fit only a portion of the map of mario bros level and I have no idea how am I supposed to do that. One of my seniors told me that I could use the sliding window algorithm. However, the problem is I don't know how to implement this algorithm on the image. If I can get any help that would be really appreciated.mario level world 1-1
I have also been able to print out the map to a suitable scaling:
map on code
edit: I am sorry I did not post my code. here it is:
import pygame
import pygame.transform
i = pygame.init()
X = 640
Y = 480
Window = pygame.display.set_mode ((X, Y))
pygame.display.set_caption ("Game")
Mario_Standing_Left = pygame.image.load("F:\\Mario in Python\\Mario_Standing_Left.png")
Mario_Standing_Right = pygame.image.load("F:\\Mario in Python\\Mario_Standing_Right.png")
x = 50
y = 430
width = 40
height = 60
speed = 5
isjump = False
jumpcount = 10
left = False
right = False
WalkCount = 0
ScreenWidth = X - width - speed
ScreenHeight = Y - height - speed
isjump = False
jumpcount = 10
run = True
while run:
pygame.time.delay (50) #time in pygame measured in milliseconds
for event in pygame.event.get ():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > speed:
x -= speed
if keys[pygame.K_RIGHT] and x <= ScreenWidth:
x += speed
if not (isjump):
if keys[pygame.K_SPACE]:
isjump = True
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) * 0.5 * neg
jumpcount -= 1
else:
isjump = False
jumpcount = 10
Window.fill ((0,0,0))
#(surface, (the window defined above, (colour), (the object being drawn)))
pygame.display.update()
world = pygame.image.load('World 1-1.png').convert()
world = pygame.transform.smoothscale(world,(8750,1400))
while True:
Window.blit(world,(0,0))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.display.quit()
pygame.quit()
You should use area in blit(..., area=...) to display only some part of world
I use area = pygame.Rect(0, 300, SCREEN_WIDTH, SCREEN_HEIGHT) to keep information what area to display. And I change area.x to scroll it right and left.
import pygame
# --- constants --- # PEP8: all constants directly after imports
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
FPS = 60
# --- main --- # PEP8: `lower_case_names` for variables
pygame.init()
window = pygame.display.set_mode ((SCREEN_WIDTH, SCREEN_HEIGHT))
world_image = pygame.image.load('World 1-1.png').convert()
world_image = pygame.transform.smoothscale(world_image, (8750,1400))
world_rect = world_image.get_rect()
area = pygame.Rect(0, 300, SCREEN_WIDTH, SCREEN_HEIGHT)
direction = 'right'
# - mainloop -
clock = pygame.time.Clock()
run = True
while run:
for event in pygame.event.get ():
if event.type == pygame.QUIT:
run = False
if direction == 'right':
# move right
area.x += 2
# change direction
if area.right > world_rect.right:
area.right = world_rect.right
direction = 'left'
else:
# move left
area.x -= 2
# change direction
if area.left < world_rect.left:
area.left = world_rect.left
direction = 'right'
#window.fill((0, 0, 0))
window.blit(world_image, (0,0), area=area)
pygame.display.flip()
clock.tick(FPS) # keep speed 60 FPS (Frames Per Second)
# - end -
pygame.quit()
PEP 8 -- Style Guide for Python Code
EDIT:
If you will have other elements then you may need to create Surface with size of world to blit world and other elements before on this surface and later display it in window using area.
import pygame
# --- constants ---
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
FPS = 60
# --- main --- # PEP8: `lower_case_names` for variables
pygame.init()
window = pygame.display.set_mode ((SCREEN_WIDTH, SCREEN_HEIGHT))
window_rect = window.get_rect()
world_image = pygame.image.load('World 1-1.png').convert()
world_image = pygame.transform.smoothscale(world_image, (8750,1400))
world_rect = world_image.get_rect()
player_image = pygame.Surface((40, 40))
player_image.fill((255, 0, 0)) # red
player_rect = player_image.get_rect(centerx=window_rect.centerx, centery=window_rect.centery+300 )
area = pygame.Rect(0, 300, SCREEN_WIDTH, SCREEN_HEIGHT)
direction = 'right'
buffer = pygame.Surface(world_rect.size)
# - mainloop -
clock = pygame.time.Clock()
run = True
while run:
for event in pygame.event.get ():
if event.type == pygame.QUIT:
run = False
if direction == 'right':
# move right
area.x += 5
player_rect.x += 5
# change direction
if area.right > world_rect.right:
area.x -= 5
player_rect.x -= 5
#area.right = world_rect.right
direction = 'left'
else:
# move left
area.x -= 5
player_rect.x -= 5
# change direction
if area.left < world_rect.left:
area.x += 5
player_rect.x += 5
#area.left = world_rect.left
direction = 'right'
#player_rect.center = area.center
buffer.blit(world_image, (0,0))
buffer.blit(player_image, player_rect)
# ---
#window.fill((0, 0, 0))
window.blit(buffer, (0,0), area=area)
pygame.display.flip()
clock.tick(FPS) # keep speed 60 FPS (Frames Per Second)
# - end -
pygame.quit()
So I keep trying to detect two different moving rects in pygame colliding but its just constantly registering a collision. As in the console constantly print lose, but the enemy isn't even touching the ball. The effect I want is just a simple game where the ball has to avoid the tack so that the ball doesn't pop.
import pygame
import sys
import math
import random
pygame.init()
size = width, height = 800, 600
white = 255, 255, 255
red = 255, 0, 0
clock = pygame.time.Clock()
screen = pygame.display.set_mode(size)
character = pygame.image.load("intro_ball.gif")
charrect = character.get_rect()
x = 340
y = 480
enemy = pygame.image.load("ho.png")
enrect = enemy.get_rect()
ex = random.randint(0, 690)
ey = 0
lose = False
while 1:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if ey >= 600 and lose != True:
ey = 0
ex = random.randint(0, 690)
collide = pygame.Rect.colliderect(charrect, enrect)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT and x < 690:
x += 4
if event.key == pygame.K_LEFT and x > 0:
x -= 4
if collide:
lose = True
else: lose = False
if lose == True: print("lose")
ey += 2
screen.fill(white)
screen.blit(enemy, (ex, ey))
screen.blit(character, (x, y))
pygame.display.update()
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 lelft of 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):
while 1:
# [...]
charrect = character.get_rect(topleft = (x, y))
enrect = enemy.get_rect(topleft = (ex, ey))
collide = pygame.Rect.colliderect(charrect, enrect)
# [...]
On the other hand you do not need the variables x, y, ex, ey at all. Use the features of the pygame.Rect objects.
Additionally read How can I make a sprite move when key is held down
Minimal example:
import pygame, sys, math, random
pygame.init()
size = width, height = 800, 600
white = 255, 255, 255
red = 255, 0, 0
clock = pygame.time.Clock()
screen = pygame.display.set_mode(size)
#character = pygame.image.load("intro_ball.gif")
character = pygame.Surface((20, 20))
character.fill((0, 255, 0))
charrect = character.get_rect(topleft = (340, 480))
#enemy = pygame.image.load("ho.png")
enemy = pygame.Surface((20, 20))
enemy.fill((255, 0, 0))
enrect = enemy.get_rect(topleft = (random.randint(0, 690), 0))
lose = False
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
charrect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 4
charrect.clamp_ip(screen.get_rect())
enrect.y += 2
if enrect.y >= 600 and lose != True:
enrect.y = 0
enrect.x = random.randint(0, 690)
collide = pygame.Rect.colliderect(charrect, enrect)
if collide:
lose = True
else:
lose = False
if lose == True:
print("lose")
screen.fill(white)
screen.blit(enemy, enrect)
screen.blit(character, charrect)
pygame.display.update()
pygame.quit()
exit()
import pygame as pg
from pygame.constants import MOUSEBUTTONDOWN, MOUSEBUTTONUP
import random
pg.init()
WIDTH = 700
HEIGHT = 700
screen = pg.display.set_mode((WIDTH, HEIGHT))
screen.fill("white")
boxIMG = pg.image.load('asteroid.png')
rndCorner = [(0, 0), (0, 700), (700, 0), (700, 700)]
def draw_screen():
obstacle = pg.draw.line(screen, (0, 0, 0), (random.choice(rndCorner)), (200, 200), 2)
def box(x, y):
screen.blit(boxIMG, (x, y))
def game_loop():
running = True
left_clicking = False
boxX = 0
boxY = 0
clock = pg.time.Clock()
while running:
screen.fill("white")
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
pg.quit()
if event.type == MOUSEBUTTONDOWN:
if event.button == 1:
left_clicking = True
if event.type == MOUSEBUTTONUP:
if event.button == 1:
left_clicking = False
if left_clicking:
boxX, boxY = pg.mouse.get_pos()
boxX -= 32.5
boxY -= 32.5
if boxX < 0:
boxX = 0
elif boxX > 635:
boxX = 635
elif boxY < 0:
boxY = 0
elif boxY > 635:
boxY = 635
# Update Screen
draw_screen()
box(boxX, boxY)
pg.display.update()
clock.tick(60)
game_loop()
So I am running into an issue where the lines I drew when calling 'draw_Screen()` are flickering. I tried using doublebuf but that didn't fix the issue for me. If you are wondering what I am trying to achieve, I am trying to move the box (main player) while holding the left click button, hence the 'if left_clicking'
You choose a new random corner coordinate in every frame. This causes the flickering. Pick a random corner once and use the same coordinate in every frame:
random_corner = random.choice(rndCorner)
def draw_screen():
obstacle = pg.draw.line(screen, (0, 0, 0), random_corner, (200, 200), 2)
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()