Why is my sprite not moving - python

My sprite should be moving from right to left across the screen, and there should be multiple of the same sprites moving from random Y co-ordinates, where as the X should stay the same. Instead, at the moment, there is no movement and there is only on of the sprites.
class Mob(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((90, 90)).convert_alpha()
self.image = pygame.image.load(badguy_file).convert_alpha()
self.image = pygame.transform.scale(self.image, (100, 100))
self.rect = pygame.Rect(x, y, 100, 100)
self.x = x
self.y = y
self.rect.x = random.randrange(800 - 100)
self.rect.y = random.randrange(-100, -40)
self.speedx = 5
self.mask = pygame.mask.from_surface(self.image)
def update(self):
self.rect.y += self.speedy
if self.rect.top > height + 10 or self.rect.left < -25 or self.rect.right > width + 20:
self.rect.x = random.randrange(width - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedx = random.randrange(2,0)
def render(self, screen):
screen.blit(self.image, (self.x, self.y))
mobYRange = random.randrange(200, 450)
mobs = pygame.sprite.Group()
for i in range(8):
mob = Mob(850,mobYRange)
mobs.add(mob)
mob.render(screen)

You don't have actual random y-axis, since once generated random list is passed to all instances of the Mob, use code below:
mobs = pygame.sprite.Group()
for i in range(8):
mob = Mob(850, random.randrange(200, 450))
mobs.add(mob)
mob.render(screen)

When you choose the y coord you do it like this mobYRange = random.randrange(200, 450) and then you use the SAME coord for all your mobs. You need to move the call of randrange into the for loop where you create your Mobs.
Also I'm not sure how pygame works. But are you supposed to call screen.blit() just once? I would have guessed this is something you call every frame to keep drawing it to the screen.

Related

How do I change rect size in pygame with sprites to improve accuracy of turrets? [duplicate]

This question already has answers here:
Can't figure out how to check mask collision between two sprites
(1 answer)
How to get the correct dimensions for a pygame rectangle created from an image
(2 answers)
Closed 3 days ago.
I am trying to make a game in pygame. I want to make a turret that will fire at the player. I have the formula to make this happen, but for some reason, it isn't completely accurate. I am running into the same problem with the player shooting as well. I am trying to use the mouse to aim, and it is off by a little bit.
Here is an image to help with understanding.
The cross is the turret and the ghost is the player. The rest is the bullets that should be hitting the player but it is hitting the rect top left it seems.
It is a bit of a mess but here is the code I am trying to test this with.
import pygame, math, random
pygame.init()
height,width = 1050,1000
clock = pygame.time.Clock()
screen = pygame.display.set_mode((height, width,))
pygame.display.set_caption("Vampires Suck")
pygame.display.flip()
running = True
class Crucifix2(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.sprite = pygame.image.load("image")
self.image = self.sprite
self.rect = self.image.get_rect()
self.rect.x =(450)
self.rect.y = (150)
self.mask = pygame.mask.from_surface(self.image)
def update(self):
pass
class MagicBullet2(pygame.sprite.Sprite):
def __init__(self, speed,x,y, targetx, targety):
super().__init__()
self.sprite = pygame.image.load("Image")
self.image = self.sprite
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
angle = math.atan2(targety - y, targetx - x)
self.dx = math.cos(angle) * speed
self.dy = math.sin(angle) * speed
self.x = x
self.y = y
def update(self):
self.x = self.x + self.dx
self.y = self.y + self.dy
self.rect.x = int(self.x)
self.rect.y = int(self.y)
if self.rect.x < -50 or self.rect.x > width + 50 or self.rect.y < -50 or self.rect.y > height + 50:
self.kill()
def collide(self, spriteGroup):
if pygame.sprite.spritecollide(self, spriteGroup, True, pygame.sprite.collide_mask):
pass
class OurHero(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.sprite = pygame.image.load('image')
self.size = (400,400)
self.current_sprite = 0
self.image =pygame.transform.scale(self.sprite, self.size)
self.rect = self.image.get_rect(topleft = (580, 630))
self.rect.x = (430)
self.rect.y = (380)
self.mask = pygame.mask.from_surface(self.image)
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 3
if keys[pygame.K_RIGHT]:
self.rect.x += 3
if keys[pygame.K_UP]:
self.rect.y -= 3
if keys[pygame.K_DOWN]:
self.rect.y += 3
if self.rect.x > 793:
self.rect.x -= 3
if self.rect.x < 75:
self.rect.x += 3
if self.rect.y < 87:
self.rect.y += 3
if self.rect.y > 789:
self.rect.y -=3
self.current_sprite += 0.027
class aim(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.sprite = pygame.image.load("image")
self.image = self.sprite
self.rect = self.image.get_rect(center = (300,300))
self.rect.inflate(-500,-500)
def update(self):
self.rect.center = pygame.mouse.get_pos()
class MagicBullet(pygame.sprite.Sprite):
def __init__(self, speed,x,y, targetx, targety):
super().__init__()
self.sprite = pygame.image.load("image")
self.image = self.sprite
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
angle = math.atan2(targety - y, targetx - x)
self.dx = math.cos(angle) * speed
self.dy = math.sin(angle) * speed
self.x = x
self.y = y
def update(self):
self.x = self.x + self.dx
self.y = self.y + self.dy
self.rect.x = int(self.x)
self.rect.y = int(self.y)
if self.rect.x < -50 or self.rect.x > width + 50 or self.rect.y < -50 or self.rect.y > height + 50:
self.kill()
mouse_x, mouse_y = pygame.mouse.get_pos()
pygame.mouse.set_visible(False)
mouse = aim()
player = OurHero()
dude_sprite = pygame.sprite.Group()
dude_sprite.add(player)
dude_sprite.add(mouse)
bad = pygame.sprite.Group()
bad3 = pygame.sprite.Group()
bad2 = Crucifix2()
bad.add(bad2)
player_bullets = MagicBullet2(8, bad2.rect.x , bad2.rect.y+90 , player.rect.x, player.rect.y)
bullet_group = pygame.sprite.Group()
bad3.add(player_bullets)
distance_x = player.rect.x - bad2.rect.x
distance_y = player.rect.y - bad2.rect.y
angle = math.atan2(distance_y, distance_x)
dude2 = MagicBullet(5, player.rect.x, player.rect.y, mouse_x, mouse_y)
while running:
mouse_x, mouse_y = pygame.mouse.get_pos()
pygame.display.update()
player_bullets = MagicBullet2(8, bad2.rect.x , bad2.rect.y+90 , player.rect.x + 30, player.rect.y + 30)
bad3.add(player_bullets)
screen.fill('white')
bad3.update()
bad3.draw(screen)
dude_sprite.update()
dude_sprite.draw(screen)
bullet_group.draw(screen)
bad.update()
bad.draw(screen)
bullet_group.update()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
#bullet_group.add(player.creat_bullet())
dude2 = MagicBullet(8, player.rect.x , player.rect.y , mouse_x, mouse_y)
bullet_group.add(dude2)
if event.type == pygame.QUIT:
running = False
clock.tick(120)
I have been searching everywhere for an answer. I am not exactly sure what I am looking for. I am very new to game dev and I am still pretty new with python and pygame. I tried transform.scale() but that seemed to push the character off the screen when I put it into update().

when the rectangle descends the ramp, the rectangle shakes

I don't know if there is a better way to implement ramps.
First i calculate the points that belong to the hipotenuse and use collidepoint to see if there is a collision between the rectangle and any point that belongs to the hipotenuse, then i update the rectangle based on the point where there was a collision.
Being careful when the rectangle is at the top of the ramp.
The rectangle ascends the ramp perfectly, but when the rectangle descends the ramp, the rectangle shakes.
import sys
import pygame
from pygame.locals import *
pygame.init()
fps = 60
fpsClock = pygame.time.Clock()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
def draw_grid():
for y in range(0,height,32):
pygame.draw.line(screen,'red',(0,y),(width,y))
for x in range(0,width,32):
pygame.draw.line(screen,'red',(x,0),(x,height))
class Ramp(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color):
super().__init__()
self.image = pygame.Surface((width, height), pygame.SRCALPHA)
#self.image.fill('green')
pygame.draw.polygon(self.image, color,
points=[(0, 0), (0, height), (width, height)])
self.rect = self.image.get_rect(topleft=(x, y))
class Player(pygame.sprite.Sprite):
def __init__(self,x,y):
super().__init__()
self.image = pygame.Surface((32, 32))
self.image.fill('blue')
self.rect = self.image.get_rect(topleft=(x,y))
self.speed = 5
self.direction = pygame.math.Vector2(0,0)
self.gravity = 0.9
self.initial_jump = -20
self.on_ground = True
def apply_gravity(self):
self.direction.y += self.gravity
self.rect.y += self.direction.y
def move(self):
keys=pygame.key.get_pressed()
if keys[K_LEFT]:
self.direction.x = -self.speed
elif keys[K_RIGHT]:
self.direction.x = self.speed
else:
self.direction.x = 0
if keys[K_UP] and self.on_ground:
self.direction.y = self.initial_jump
self.on_ground = False
self.rect.x += self.direction.x
def check_borders(self):
if self.rect.x <= 0:
self.rect.x = 0
if self.rect.right >= width:
self.rect.right = width
if self.rect.bottom >= height:
self.rect.bottom = height
self.direction.y = 0
self.on_ground = True
if self.rect.colliderect(ramp_rect):
if self.direction.x > 0 and abs(self.rect.right-ramp_rect.left) <= 5:
self.rect.right = ramp_rect.left
# ramp stuff
for p in hypotenuse_points:
if self.rect.collidepoint(p):
if self.rect.left >= ramp_rect.left:
self.rect.bottomleft = p
else:
self.rect.bottom = ramp_rect.top
self.on_ground = True
self.direction.y = 0
def update(self):
self.move()
self.apply_gravity()
self.check_borders()
player = pygame.sprite.GroupSingle(Player(12*32,10*32))
ramp = pygame.sprite.GroupSingle(Ramp(5*32,10*32,7*32,5*32,'red'))
ramp_rect = ramp.sprite.rect
m = (ramp_rect.height)/( ramp_rect.width)
x1,y1 = ramp_rect.topleft
hypotenuse_points = []
for x in range(ramp_rect.left,ramp_rect.right):
hypotenuse_points.append((x,m*(x-x1)+y1)) # Point-slope equation
while True:
screen.fill('white')
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
ramp.draw(screen)
player.update()
player.draw(screen)
#draw_grid()
pygame.draw.lines(screen,'black',False,hypotenuse_points,3)
pygame.display.update()
fpsClock.tick(fps)
There is no problem with your code. Only gravity is too weak. The movement is so fast that gravity is acting too late. Note that instead of moving down the slope, you move to the right and then fall.
Of course there is one problem with your code. Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.
The coordinates for Rect objects are all integers. [...]
The fraction part of the coordinates gets lost when the new position of the object is assigned to the Rect object. If this is done every frame, the position error will accumulate over time.
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables respectively attributes and to synchronize the pygame.Rect object. round the coordinates and assign it to the location of the rectangle.
Instead of the list of points I suggest to compute the height of the ramp under the palyer:
if self.rect.colliderect(ramp_rect):
ratio = ramp_rect.height / ramp_rect.width
self.rect.bottom = ramp_rect.bottom - (ramp_rect.right - max(self.rect.left, ramp_rect.left)) * ratio
self.y = self.rect.y
Complete example:
import sys
import pygame
from pygame.locals import *
pygame.init()
fps = 60
fpsClock = pygame.time.Clock()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
def draw_grid():
for y in range(0,height,32):
pygame.draw.line(screen,'red',(0,y),(width,y))
for x in range(0,width,32):
pygame.draw.line(screen,'red',(x,0),(x,height))
class Ramp(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color):
super().__init__()
self.image = pygame.Surface((width, height), pygame.SRCALPHA)
#self.image.fill('green')
pygame.draw.polygon(self.image, color,
points=[(0, 0), (0, height), (width, height)])
self.rect = self.image.get_rect(topleft=(x, y))
class Player(pygame.sprite.Sprite):
def __init__(self,x,y):
super().__init__()
self.image = pygame.Surface((32, 32))
self.image.fill('blue')
self.rect = self.image.get_rect(topleft=(x,y))
self.x, self.y = self.rect.topleft
self.speed = 5
self.direction = pygame.math.Vector2(0,0)
self.gravity = 0.9
self.initial_jump = -20
self.on_ground = True
def apply_gravity(self):
self.direction.y += self.gravity
self.y += self.direction.y
self.rect.y = round(self.y)
def move(self):
keys = pygame.key.get_pressed()
self.direction.x = (keys[K_RIGHT] - keys[K_LEFT]) * self.speed
if keys[K_UP] and self.on_ground:
self.direction.y = self.initial_jump
self.on_ground = False
self.x += self.direction.x
self.rect.x = round(self.x)
def check_borders(self):
if self.rect.x <= 0:
self.rect.x = 0
self.x = self.rect.x
if self.rect.right >= width:
self.rect.right = width
self.x = self.rect.x
if self.rect.bottom >= height:
self.rect.bottom = height
self.direction.y = 0
self.on_ground = True
self.y = self.rect.y
if self.rect.colliderect(ramp_rect):
if self.old_rect.right-1 <= ramp_rect.left:
self.rect.right = ramp_rect.left
self.x = self.rect.x
else:
ratio = ramp_rect.height / ramp_rect.width
bottom = ramp_rect.bottom - (ramp_rect.right - max(self.rect.left, ramp_rect.left)) * ratio
if self.on_ground or self.rect.bottom > bottom:
self.rect.bottom = bottom
self.y = self.rect.y
self.direction.y = 0
self.on_ground = True
def update(self):
self.old_rect = self.rect.copy()
self.move()
self.apply_gravity()
self.check_borders()
player = pygame.sprite.GroupSingle(Player(12*32,10*32))
ramp = pygame.sprite.GroupSingle(Ramp(5*32,10*32,7*32,5*32,'red'))
ramp_rect = ramp.sprite.rect
m = (ramp_rect.height)/( ramp_rect.width)
x1,y1 = ramp_rect.topleft
while True:
screen.fill('white')
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
ramp.draw(screen)
player.update()
player.draw(screen)
pygame.display.update()
fpsClock.tick(fps)

How to shoot bullets from a character facing in direction of cursor in pygame?

In my game the problem is that bullets are coming only from one place i.e, from the center. As my player rotates in direction of cursor, I want the bullets to be shot from top of the player even if the player is rotated and travel in a straight line in the direction player is facing towards, As the player rotates in the direction of cursor.
As you can view here the the bullets are always in same direction and always come out of same place.
I tried to use getpos() method to get cursor position and tried to subtract from the player coordinates but failed to get the result.
I think the problem is within the def shoot(self) method of Rotator class, I need to get the coordinates spaceship's tip even when it is rotating all time.
import math
import random
import os
import pygame as pg
import sys
pg.init()
height=650
width=1200
os_x = 100
os_y = 45
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (os_x,os_y)
screen = pg.display.set_mode((width,height),pg.NOFRAME)
screen_rect = screen.get_rect()
background=pg.image.load('background.png').convert()
background = pg.transform.smoothscale(pg.image.load('background.png'), (width,height))
clock = pg.time.Clock()
running = True
class Mob(pg.sprite.Sprite):
def __init__(self):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load('enemy.png').convert_alpha()
self.image = pg.transform.smoothscale(pg.image.load('enemy.png'), (33,33))
self.rect = self.image.get_rect()
self.rect.x = random.randrange(width - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
self.speedx = random.randrange(-3, 3)
def update(self):
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.top > height + 10 or self.rect.left < -25 or self.rect.right > width + 20:
self.rect.x = random.randrange(width - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
class Rotator(pg.sprite.Sprite):
def __init__(self, screen_rect):
pg.sprite.Sprite.__init__(self)
self.screen_rect = screen_rect
self.master_image = pg.image.load('spaceship.png').convert_alpha()
self.master_image = pg.transform.smoothscale(pg.image.load('spaceship.png'), (33,33))
self.image = self.master_image.copy()
self.rect = self.image.get_rect(center=[width/2,height/2])
self.delay = 10
self.timer = 0.0
self.angle = 0
self.distance = 0
self.angle_offset = 0
def get_angle(self):
mouse = pg.mouse.get_pos()
offset = (self.rect.centerx - mouse[0], self.rect.centery - mouse[1])
self.angle = math.degrees(math.atan2(*offset)) - self.angle_offset
old_center = self.rect.center
self.image = pg.transform.rotozoom(self.master_image, self.angle,1)
self.rect = self.image.get_rect(center=old_center)
self.distance = math.sqrt((offset[0] * offset[0]) + (offset[1] * offset[1]))
def update(self):
self.get_angle()
self.display = 'angle:{:.2f} distance:{:.2f}'.format(self.angle, self.distance)
self.dx = 1
self.dy = 1
self.rect.clamp_ip(self.screen_rect)
def draw(self, surf):
surf.blit(self.image, self.rect)
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.centery)
all_sprites.add(bullet)
bullets.add(bullet)
class Bullet(pg.sprite.Sprite):
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load('bullet.png').convert_alpha()
self.image = pg.transform.smoothscale(pg.image.load('bullet.png'), (10,10))
self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x
self.speedy = -8
def update(self):
self.rect.y += self.speedy
# kill if it moves off the top of the screen
if self.rect.bottom < 0:
self.kill()
all_sprites = pg.sprite.Group()
bullets = pg.sprite.Group()
mobs = pg.sprite.Group()
rotator = Rotator(screen_rect)
all_sprites.add(rotator)
for i in range(5):
m = Mob()
all_sprites.add(m)
mobs.add(m)
while running:
keys = pg.key.get_pressed()
for event in pg.event.get():
if event.type == pg.QUIT:
sys.exit()
pygame.quit()
if event.type == pg.MOUSEBUTTONDOWN:
rotator.shoot()
screen.blit(background, [0, 0])
all_sprites.update()
hits = pg.sprite.groupcollide(mobs, bullets, True, True)
for hit in hits:
m = Mob()
all_sprites.add(m)
mobs.add(m)
hits = pg.sprite.spritecollide(rotator, mobs, False)
if hits:
running = False
all_sprites.draw(screen)
clock.tick(60)
pg.display.update()
See Shooting a bullet in pygame in the direction of mouse and calculating direction of the player to shoot pygame.
Pass the mouse position to rotator.shoot(), when the mouse button is pressed:
if event.type == pg.MOUSEBUTTONDOWN:
rotator.shoot(event.pos)
Calculate the direction of from the rotator to the mouse position and pass it the constructor of the new bullet object:
def shoot(self, mousepos):
dx = mousepos[0] - self.rect.centerx
dy = mousepos[1] - self.rect.centery
if abs(dx) > 0 or abs(dy) > 0:
bullet = Bullet(self.rect.centerx, self.rect.centery, dx, dy)
all_sprites.add(bullet)
bullets.add(bullet)
Use pygame.math.Vector2 to store the current positon of the bullet and the normalized direction of the bullet (Unit vector):
class Bullet(pg.sprite.Sprite):
def __init__(self, x, y, dx, dy):
pg.sprite.Sprite.__init__(self)
self.image = pg.transform.smoothscale(pg.image.load('bullet.png').convert_alpha(), (10,10))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.speed = 8
self.pos = pg.math.Vector2(x, y)
self.dir = pg.math.Vector2(dx, dy).normalize()
Calcualate the new position of the bullet in update() (self.pos += self.dir * self.speed) and update the .rect attribute by the new position.
.kill() the bullet when it leaves the screen. This can be checked by self.rect.colliderect():
class Bullet(pg.sprite.Sprite):
# [...]
def update(self):
self.pos += self.dir * self.speed
self.rect.center = (round(self.pos.x), round(self.pos.y))
if not self.rect.colliderect(0, 0, width, height):
self.kill()

Trouble creating multiple instances in python/pygame

I've been creating a smup game. The problem is that I have multiple instances of enemies within the game which are supposed to fall from the top of the screen.All of my instances except for one hang at the top of the screen. For some bizarre reason it appears that only one instance of my enemy objects seem to move. I've spent hours trying to fix it to absolutely no avail. I've also browsed a plethora of tutorials on how to create classes, and I can't find anything really wrong with my code. Please help.
import pygame,random,os
from pygame.locals import *
'initialize pygame'
pygame.init()
'set variables'
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
black = (0,0,0)
white = (255,255,255)
width = 1280
height = 720
'create window'
screen = pygame.display.set_mode((1280,720))
clock = pygame.time.Clock()
'sprite groups'
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
'classes'
class Player(pygame.sprite.Sprite):
def __init__(self):
self.x, self.y = pygame.mouse.get_pos()
pygame.sprite.Sprite.__init__(self)
#self.image = pygame.Surface((32,32))++--3
#$self.image.fill((green))
self.image = pygame.image.load("vehicle.png")
self.image.set_colorkey(white)
self.rect = self.image.get_rect()
self.rect.center = (width/2,700)
self.speed = 0
def move(self):
self.keypress = pygame.key.get_pressed()
if self.keypress[pygame.K_a]:
self.speed = 3
self.rect.x -= self.speed
if self.keypress[pygame.K_d]:
self.speed = 3
self.rect.x += self.speed
#self.rect.x += 1
if self.rect.left > width:
self.rect.right = 0
if self.rect.right < 0:
self.rect.left = 1280
class Enemy(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("missile.png")
self.rect = self.image.get_rect()
self.rect.x = random.randrange(50,width)
self.rect.y = random.randrange(-100,-40)
self.speedy = random.randrange(1,5)
def enmove(self):
self.rect.y = self.rect.y + self.speedy
if self.rect.top > height:
self.rect.x = random.randrange(50,width)
self.rect.y = random.randrange(-100,-40)
self.speedy = random.randrange(1,5)
class bullet(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((32,32))
self.rect = self.image.get_rect()
def bmove(self):
pass
player = Player()
for r in range(9):
enemy = Enemy()
enemies.add(enemy)
while True:
pygame.event.pump()
'main loop'
player.move()
enemy.enmove()
all_sprites.add(player)
screen.fill(black)
all_sprites.draw(screen)
enemies.draw(screen)
hits = pygame.sprite.spritecollide(player,enemies,False)
if hits == True:
player.all_sprites.remove(player)
print('true')
all_sprites.update()
pygame.display.update()
print(hits)
Your problem seem to be that you move only last enemy:
enemy.enmove()
You should try iterate your enemies group and move every enemy seperately

How to set up co-ordinates correctly for my game

How to make the red block appear between grey and green block.
In the above picture i changed my rectangle x position of donkey to 160 then only i can able to see the red block if not means i'll hide under grey block.
this is my code
class Road(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((200, 500))
self.image.fill(grey)
self.rect = self.image.get_rect()
self.rect.centerx = width/2
#self.rect.left = width-200
#print self.rect.left
self.speedy = 5
def update(self):
self.rect.y += self.speedy
if self.rect.y > 0:
self.rect.y = 0
class Donkey(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 100))
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.x = 200
print 'x:',self.rect.x
self.rect.y = -54
print 'y:',self.rect.y
self.speedy = random.randint(8,10)
def update(self):
self.choice = (200, 300)
self.rect.y += self.speedy
if self.rect.top > height:
self.rect.x = random.choice(self.choice)
print 'x:', self.rect.x
self.rect.y = random.randrange(-100, -40)
print 'y', self.rect.y
self.speedy = random.randint(8,10)
class Race_car(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((100, 100))
self.image.fill(green)
self.rect = self.image.get_rect()
self.rect.x = 200
self.rect.bottom = height
self.speedy = -0.1
def update(self):
#self.speedx = 0
self.rect.y += self.speedy
keypressed = pygame.key.get_pressed()
if keypressed[pygame.K_RIGHT]:
self.rect.x = 300
elif keypressed[pygame.K_LEFT]:
self.rect.x = 200
#Group, object for game_hearth
game_hearth = pygame.sprite.Group()
road = Road()
game_hearth.add(road)
#Group, object for donkey
donkey = Donkey()
donkeys = pygame.sprite.Group()
game_hearth.add(donkey)
donkeys.add(donkey)
#Group, object for racecar
racecar = Race_car()
racecars = pygame.sprite.Group()
game_hearth.add(racecar)
racecars.add(racecar)
when i run my code after commenting the Race_car class the red blocks working fine, see
so the thing is i want to display the both red and green block above the grey road. so how to do it without commenting any class in my program. i know its some co-ordinate mistake but i don't know where to change it.
From the Pygame docs:
The Group does not keep sprites in any order, so the draw order is
arbitrary.
You should probably switch to pygame.sprite.OrderedUpdates:
This class derives from pygame.sprite.RenderUpdates(). It maintains
the order in which the Sprites were added to the Group for rendering.
This makes adding and removing Sprites from the Group a little slower
than regular Groups.
#Group, object for game_hearth
game_hearth = pygame.sprite.OrderedUpdates()
road = Road()
game_hearth.add(road)
#Group, object for donkey
donkey = Donkey()
donkeys = pygame.sprite.OrderedUpdates()
game_hearth.add(donkey)
donkeys.add(donkey)
#Group, object for racecar
racecar = Race_car()
racecars = pygame.sprite.OrderedUpdates()
game_hearth.add(racecar)
racecars.add(racecar)

Categories