How can I make my sprite move accross the screen? [duplicate] - pygame

This question already has answers here:
How to make a circle move diagonally from corner to corner in pygame
(1 answer)
How to make smooth movement in pygame
(2 answers)
Closed 2 years ago.
When a certain value is met I want my enemy sprite to return to his intial position,but now hes just disappearing and reappearing in that position.
I'm only changing the Y position
def update(self):
self.count += 1
x_component = self.ship.rect.centerx-self.enemy2X
y_component = self.ship.rect.centery-self.enemy2Y
distance = math.hypot(x_component, y_component)
if distance < 200:
self.currentState = 1
print distance
elif distance > 200:
self.currentState = 0
self.enemy2Y=68
print self.enemy2Y

Related

Pygame need to build sprite from a rotating and non rotating image [duplicate]

This question already has answers here:
How to set the pivot point (center of rotation) for pygame.transform.rotate()?
(5 answers)
How can you rotate an image around an off center pivot in Pygame
(1 answer)
How do I rotate an image around its center using Pygame?
(6 answers)
Closed 22 days ago.
I have an interesting problem with sprits in pygame.
Essentially, I am trying to create an archer sprite which will follow a target.
To do so, I need it to rotate. Naturally, I don't want the whole archer to rotate - just his shoulders/head etc. To do so I have create two separate spritesheets (for the top and bottom)
I can then create the sprite image using:
class Archer(pygame.sprite.Sprite):
def __init__(self, group, pos, size):
super().__init__(group)
self.pos = pos
self.assets_legs = GetAssets('../graphics/archer_fixed.png', size)
self.frames_legs = self.assets_legs.sprite_images
self.assets_body = GetAssets('../graphics/archer_rotate.png', size)
self.frames_body = self.assets_body.sprite_images
self.frame_index = 0
self.angle = 0
self.archer = [self.frames_legs[round(self.frame_index)], self.frames_body[round(self.frame_index)]]
self.image = pygame.Surface((size), pygame.SRCALPHA)
for image in self.archer:
self.image.blit(image, (0,0))
This is fine and works well. However, when I want to rotate the top half and blit this to the self.image, as in:
def rotate(self):
self.rot_img = self.archer[1]
self.rot_img = pygame.transform.rotate(self.rot_img, 1)
self.image = pygame.Surface((75,75), pygame.SRCALPHA)
self.archer = [self.frames_legs[round(self.frame_index)], self.rot_img]
for image in self.archer:
self.image.blit(image, (0,0))
self.rect = self.image.get_rect(center = self.pos)
I get strange artifacts. I suspect because I am trying to blit a surface with a rotated dimension to a self.image. The only work around I can think of is to create two separate sprites and then have them track each other, but the must be a way to do this in one class.
Any ideas?
Cheers

make enemy ricochet off walls pygame [duplicate]

This question already has answers here:
How do I make my monster move randomly in my game
(1 answer)
How do I randomly move objects in a maze using pygame? [closed]
(1 answer)
Closed 24 days ago.
This post was edited and submitted for review 23 days ago and failed to reopen the post:
Original close reason(s) were not resolved
Note: This is different to my previous question. The previous question I posted was about the enemy following the player, but here I want the zombie to roam around. My plan is to link these together (once they both work correctly) and have the zombie roam around until the player is within a certain radius. I would appreciate if this can be reopened as this is a different problem!
So i am trying to create an enemy that moves around the map and 'bounces' off any walls it collides with. I have tried to adapt some code i used making pong a while ago. I tried to break the problem down and consider where the enemy is hitting the wall from, but i feel like i may be overcomplicating it? Here is a video of the bug: https://imgur.com/a/H2qOMZD
This is my current code.
class Enemy(pygame.sprite.Sprite):
def __init__(self, position):
super().__init__(enemy_group, all_sprites_group)
self.position = pygame.math.Vector2(position)
self.wander_speed = pygame.math.Vector2((6 * random.choice((-1,1))), (6 * random.choice((-1,1))))
def walk_around(self):
self.velocity = self.wander_speed
print(self.velocity)
self.position += self.velocity
self.base_zombie_rect.centerx = self.position.x
self.base_zombie_rect.centery = self.position.y
self.base_zombie_rect.centerx, self.base_zombie_rect.centery = self.position.x, self.position.y
self.check_collision_2()
self.rect.center = self.base_zombie_rect.center
self.position = (self.base_zombie_rect.centerx, self.base_zombie_rect.centery)
def check_collision_2(self):
for sprite in obstacles_group:
if sprite.rect.colliderect(self.base_zombie_rect):
if self.base_zombie_rect.top < sprite.rect.bottom and self.base_zombie_rect.centery > sprite.rect.bottom: # UP collision
print("UP COLLISION")
self.velocity.y *= -1
if self.base_zombie_rect.bottom > sprite.rect.top and self.base_zombie_rect.centery < sprite.rect.top: # DOWN collision
print("DOWN COLLISION")
self.velocity.y *= -1
if self.base_zombie_rect.left < sprite.rect.right and self.base_zombie_rect.centerx > sprite.rect.right: # LEFT collision
print("RIGHT COLLISION")
self.velocity.x *= -1
if self.base_zombie_rect.right > sprite.rect.left and self.base_zombie_rect.centerx < sprite.rect.left: # RIGHT collision
print("LEFT COLLISION")
self.velocity.x *= -1

Draw detection radius around square sprite [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
Pygame collision with masks
(1 answer)
Closed 6 months ago.
I would like to draw sprites with 2 features: a base image (let's say a square image that I pass as argument) and a togglable view of their circular detection radius, for debug purposes and checking that collisions with a circular mask actually work.
Note: the main question is not about to detect collisions as in How do I detect collision in pygame?, but rather can a sprite have several surfaces attached to it and why is my draw_mask_outline function returning croppped circles? (see attached screenshots)
Here's an example of my class:
class Robot(pygame.sprite.Sprite):
def __init__(self, x, y, image, detection_radius, mouse_group, *groups):
super().__init__(*groups)
# extra image added for changing color if mouse is detected within
# detection radius
# I have used the mouse as a debug tool but in the end the Robot
# should have no knowledge of the other groups positions (and should
# not be able to compute a euclidean distance from a sprite group) but
# simply detect if a sprite of a certain sprite group has entered its
# radius
other_img = pygame.Surface((30, 30))
other_img.fill('black')
self.img_idx = 0
self.images = [image, other_img]
self.image = self.images[self.img_idx]
self.pos = pygame.Vector2(x, y)
self.rect = image.get_rect(center=self.pos)
self.detection_radius = detection_radius
self.mask_surface = pygame.Surface((detection_radius * 2, detection_radius * 2), pygame.SRCALPHA)
self.detection_mask = self.make_circle(self.notice_radius)
self.mask = pygame.mask.from_surface(
self.make_circle_surface(detection_radius))
sekf.mouse_group = mouse_group
def draw_mask_outline(self):
# this function should draw the outline of the circular detection mask
display_surf = pygame.display.get_surface()
pts = self.mask.outline()
for pt in pts:
x = pt[0] + self.rect.centerx
y = pt[1] + self.rect.centery
pygame.draw.circle(display_surf, 'black', (x, y), 1)
def make_circle_surface(self, radius):
# I used this function to generate the circular surface
mask_surf = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA)
pygame.draw.circle(mask_surf, (0, 0, 0), (self.rect.centerx, self.rect.centery), radius)
return mask_surf
def collision(self):
# collision detection function, if mouse inside detection radius do something
if pygame.sprite.spritecollide(self, self.mouse_group, False, pygame.sprite.collide_mask):
pygame.draw.circle(pygame.display.get_surface(), (0, 0, 0), (self.rect.centerx, self.rect.centery), self.notice_radius, 1)
self.img_idx = 1
self.image = self.images[self.img_idx]
else:
self.img_idx = 0
self.image = self.images[self.img_idx]
def update(self):
# the overall update function where all the robot logic will happen
self.draw_mask_outline()
As fas as I've understood how the lib works, I should create a surface around the original image, big enough to fit the circle but this does not seem compatible with already having a self.image. Then I should draw a circle on that new surface.
Will this new surface follow the sprite when it moves too?
I managed to draw the circle inside the original image but this is not what is expected since the starting is smaller than the circle. In some cases, I also managed to generate surfaces, transform them to mask, then using the mask to generate an outline (hence the self.mask) but these outlines are always drawn far away from the sprite positions, are incomplete or completely missing...
Here are some screenshots of the current version and what I could achieve.
When the mouse is outside the detection ring, outlines are drawn with a severe offset, are sometimes incomplete and some robots have no outline.
Displaced and incomplete outlines
When the mouse is inside, the collision function draws the correct circle (but this is not the mask).
Collisions debug ring
Here are links to some solutions that I have tested and that did not work (if I've understood them correctly that is...):
pygame: mask non-image type surfaces
Pygame: Why i can't draw a circle sprite
how to create a circular sprite in pygame
OOP Pygame Circle
Ultimately the goal is to have the robots roam around and detect sprites from another group of robots that enter their detection radius.
Any help would be very much appreciated!

I'm trying to make my bullet look at my cursor [duplicate]

This question already has answers here:
How do you point the barrel towards mouse in pygame?
(1 answer)
calculating direction of the player to shoot pygame
(1 answer)
How to move a sprite according to an angle in Pygame
(3 answers)
Closed 7 months ago.
I've got my player in the center of my screen and I want a bullet at a fixed distance from the player pointing at my cursor. I've got the fixed distance down and the angle in degrees, but the bullet spins around violently when I move my cursor. What am I doing wrong?
radius = 100
mouse = pg.mouse.get_pos()
delta_x = mouse[0] - (Width/2)
delta_y = -(mouse[1] - (Height/2))
Rotation = math.degrees(math.atan2(delta_y, delta_x))
if Rotation > 0:
angle = (360 - Rotation)
elif Rotation < 0:
angle = -(Rotation)
x, y = (radius*(math.sin(angle))), (radius*(math.cos(angle)))
Bullet_x = (Width/2 + x)
Bullet_y = (Height/2 + y)
screen.blit(Bullet, (Bullet_x, Bullet_y))

Image rotation in pygame [duplicate]

This question already has answers here:
How do I rotate an image around its center using Pygame?
(6 answers)
How can you rotate an image around an off center pivot in Pygame
(1 answer)
Closed 2 years ago.
I've got a little problem that I can't seem to solve. I can't find it on stackoverflow yet.
It's about rotating an image. I've got two 'gamepieces' in the example here, where I can show the problem. If I click on one line, it rotates 90 degrees. But after it rotated 180 degrees (which is precise, because I made sure it ends on exactly 90, 180, 270 etc degrees) the images don't connect well anymore. if I rotate it another 180 degrees, then it's fine again..
Screen 1, nothing bad here:
Screen 2, here you see the two lines don't connect well.
I tried changing the resolution to different pixel sizes (64, 64) and (81, 81) for example. But this does not cure the problem.
And here is part of the code:
class Piece:
def __init__(self, piece, x, y):
self.image = pygame.image.load(piece)
self.rotated_image = self.image
self.rect = self.rotated_image.get_rect()
self.rect.center = x, y
self.current_degrees = 0
self.degrees = 0
self.values = [0, 1, 0, 1]
def rotate_piece(self):
self.rotated_image = pygame.transform.rotozoom(self.image, lerp(self.current_degrees, self.degrees, 0.3), 1)
self.rect = self.rotated_image.get_rect(center=self.rect.center)
self.current_degrees = lerp(self.current_degrees, self.degrees, 0.3)
def rotate_values(self):
temp = self.values[0]
for i in range(len(self.values) - 1):
self.values[i] = self.values[i+1]
self.values[3] = temp
print(self.values)
pieces = []
piece1 = Piece(images['line'], 32, 32)
piece2 = Piece(images['line'], 96, 32)
pieces.append(piece1)
pieces.append(piece2)