[PyGame] Terrible Sprite controls, need help. - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: [PyGame] Terrible Sprite controls, need help. (/thread-23168.html) Pages:
1
2
|
RE: Terrible Sprite controls, need help. - michael1789 - Dec-16-2019 I'm running the event loop you posted. while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False delta = clock.tick(60) keys = pygame.key.get_pressed() window.fill(pygame.Color('black')) ship.update(keys, delta) pygame.display.flip() RE: Terrible Sprite controls, need help. - Windspar - Dec-16-2019 When I get more time. I play around with the math. Example rough draft. import pygame import math pygame.init() window = pygame.display.set_mode((800, 800)) clock = pygame.time.Clock() class Ship(pygame.sprite.Sprite): def __init__(self, position, anchor="center"): self.original_image = pygame.Surface((10, 20), pygame.SRCALPHA) self.original_image.fill((100, 200, 200)) self.image = self.original_image.copy() self.rect = self.image.get_rect(**{anchor: position}) self.position = pygame.Vector2(self.rect.center) self.start_position = pygame.Vector2(position) self.angle = 180 self.velocity = pygame.Vector2(0, 0) self.decay = 0.98 self.thrust = 0.0005 self.max_speed = 0.1 self.rotate_speed = 0.06 self.direction = self.calculate_direction() self.backpedal = 2 def calculate_direction(self): rads = math.radians(self.angle) return pygame.Vector2(math.sin(rads), math.cos(rads)) def draw(self, surface): surface.blit(self.image, self.rect) def movement(self, keys, delta): if keys[pygame.K_r]: self.reset() # Forwards Thrust if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]: speed = self.direction * self.thrust * delta self.velocity += speed if self.velocity.x > self.max_speed: self.velocity.x = self.max_speed if self.velocity.y > self.max_speed: self.velocity.y = self.max_speed # Backwards Thrust elif keys[pygame.K_DOWN] or keys[pygame.K_s]: speed = self.direction * self.thrust * delta / self.backpedal self.velocity -= speed if self.velocity.x < -self.max_speed: self.velocity.x = -self.max_speed if self.velocity.y < -self.max_speed: self.velocity.y = -self.max_speed if keys[pygame.K_LEFT] or keys[pygame.K_a]: self.angle = (self.angle + self.rotate_speed * delta) % 360 self.update_rotation() elif keys[pygame.K_RIGHT] or keys[pygame.K_d]: self.angle = (self.angle - self.rotate_speed * delta) % 360 self.update_rotation() # Drifting self.velocity * self.decay self.position += self.velocity * delta self.rect.center = self.position def reset(self): pass def update_rotation(self): self.image = pygame.transform.rotate(self.original_image, self.angle) self.rect = self.image.get_rect(center=self.rect.center) self.direction = self.calculate_direction() def update(self, keys, delta): self.movement(keys, delta) self.draw(window) ship = Ship((400, 400)) run = True while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False delta = clock.tick(60) keys = pygame.key.get_pressed() window.fill(pygame.Color('black')) ship.update(keys, delta) pygame.display.flip() RE: Terrible Sprite controls, need help. - Windspar - Dec-17-2019 Here a smooth space movement example. import pygame import math pygame.init() window = pygame.display.set_mode((800, 800)) clock = pygame.time.Clock() class Text(pygame.sprite.Sprite): def __init__(self, text, font, color, position, anchor="topleft"): super().__init__() self.font = font self.color = color self.position = position self.anchor = anchor self.render(text) def render(self, text): self.image = self.font.render(text, 1, self.color) self.rect = self.image.get_rect(**{self.anchor: self.position}) class Ship(pygame.sprite.Sprite): def __init__(self, position, anchor="center"): super().__init__() self.original_image = pygame.Surface((10, 20), pygame.SRCALPHA) self.original_image.fill((100, 200, 200)) self.image = self.original_image.copy() self.rect = self.image.get_rect(**{anchor: position}) self.position = pygame.Vector2(self.rect.center) self.start_position = pygame.Vector2(self.position) self.angle = 180 self.velocity = pygame.Vector2(0, 0) self.decay = 0.999 self.thrust = 0.0006 self.max_speed = 0.8 self.rotate_speed = 0.06 self.direction = self.calculate_direction() self.backpedal = 2 self.speed_cap = lambda n: max(min(n, self.max_speed), -self.max_speed) def calculate_direction(self): rads = math.radians(self.angle) return pygame.Vector2(math.sin(rads), math.cos(rads)) def draw(self, surface): surface.blit(self.image, self.rect) def movement(self, keys, delta): if keys[pygame.K_r]: self.reset() # Forwards Thrust if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]: self.velocity += self.direction * self.thrust * delta self.velocity.x = self.speed_cap(self.velocity.x) self.velocity.y = self.speed_cap(self.velocity.y) # Backwards Thrust elif keys[pygame.K_DOWN] or keys[pygame.K_s]: self.velocity -= self.direction * self.thrust * delta / self.backpedal self.velocity.x = self.speed_cap(self.velocity.x) self.velocity.y = self.speed_cap(self.velocity.y) if keys[pygame.K_LEFT] or keys[pygame.K_a]: self.angle = (self.angle + self.rotate_speed * delta) % 360 self.update_rotation() elif keys[pygame.K_RIGHT] or keys[pygame.K_d]: self.angle = (self.angle - self.rotate_speed * delta) % 360 self.update_rotation() # Drifting self.position += self.velocity self.rect.center = self.position self.velocity *= self.decay def reset(self): self.angle = 180 self.velocity = pygame.Vector2(0, 0) self.update_rotation() self.position = pygame.Vector2(self.start_position) self.rect.center = self.position def update_rotation(self): self.image = pygame.transform.rotate(self.original_image, self.angle) self.rect = self.image.get_rect(center=self.rect.center) self.direction = self.calculate_direction() def update(self, keys, delta): self.movement(keys, delta) self.draw(window) ship = Ship((400, 400)) run = True current_velocity = pygame.Vector2(ship.velocity) velocity = "x: {:.3f}, y: {:.3f}" font = pygame.font.Font(None, 28) text = Text(velocity.format(0, 0), font, pygame.Color('white'), (10, 10)) sprites = pygame.sprite.Group() sprites.add(ship, text) while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False delta = clock.tick(60) keys = pygame.key.get_pressed() window.fill(pygame.Color('black')) sprites.update(keys, delta) if current_velocity != ship.velocity: current_velocity = pygame.Vector2(ship.velocity) text.render(velocity.format(*current_velocity)) sprites.draw(window) pygame.display.flip() RE: Terrible Sprite controls, need help. - michael1789 - Dec-17-2019 Wow, this thing works amazingly. Thank-you so very much. I shall give this code a place of honor. RE: Terrible Sprite controls, need help. - Windspar - Dec-17-2019 Still needs a little work. It moving to fast on angles. Max speed should be adjust by ship direction. Let max speed equals 0.8. angle 180 max speed would be (0, 0.8). angle 45 max speed would be (0.565685, 0.565685). RE: Terrible Sprite controls, need help. - Windspar - Dec-18-2019 Angle max speed fix. import pygame import math pygame.init() window = pygame.display.set_mode((800, 800)) clock = pygame.time.Clock() class Text(pygame.sprite.Sprite): def __init__(self, text, font, color, position, anchor="topleft"): super().__init__() self.font = font self.color = color self.position = position self.anchor = anchor self.render(text) def render(self, text): self.image = self.font.render(text, 1, self.color) self.rect = self.image.get_rect(**{self.anchor: self.position}) class Ship(pygame.sprite.Sprite): def __init__(self, position, anchor="center"): super().__init__() self.original_image = pygame.Surface((10, 20), pygame.SRCALPHA) self.original_image.fill((100, 200, 200)) self.image = self.original_image.copy() self.rect = self.image.get_rect(**{anchor: position}) self.position = pygame.Vector2(self.rect.center) self.start_position = pygame.Vector2(self.position) self.angle = 180 self.velocity = pygame.Vector2(0, 0) self.decay = 0.999 self.thrust = 0.0006 self.max_speed = 0.8 self.rotate_speed = 0.06 self.direction = self.calculate_direction() self.backpedal = 2 #self.speed_cap = lambda n: max(min(n, self.max_speed), -self.max_speed) def calculate_direction(self): rads = math.radians(self.angle) return pygame.Vector2(math.sin(rads), math.cos(rads)) def draw(self, surface): surface.blit(self.image, self.rect) def movement(self, keys, delta): if keys[pygame.K_r]: self.reset() # Forwards Thrust if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]: self.speed_cap(self.direction * self.thrust * delta) # Backwards Thrust elif keys[pygame.K_DOWN] or keys[pygame.K_s]: self.speed_cap(-(self.direction * self.thrust * delta / self.backpedal)) if keys[pygame.K_LEFT] or keys[pygame.K_a]: self.angle = (self.angle + self.rotate_speed * delta) % 360 self.update_rotation() elif keys[pygame.K_RIGHT] or keys[pygame.K_d]: self.angle = (self.angle - self.rotate_speed * delta) % 360 self.update_rotation() # Drifting self.position += self.velocity self.rect.center = self.position self.velocity *= self.decay def reset(self): self.angle = 180 self.velocity = pygame.Vector2(0, 0) self.update_rotation() self.position = pygame.Vector2(self.start_position) self.rect.center = self.position def speed_cap(self, speed): rads = math.radians(self.angle) max_speed = pygame.Vector2(abs(math.sin(rads)), abs(math.cos(rads))) * self.max_speed if speed.x > 0: if self.velocity.x < max_speed.x: self.velocity.x += speed.x else: if self.velocity.x > -max_speed.x: self.velocity.x += speed.x if speed.y > 0: if self.velocity.y < max_speed.y: self.velocity.y += speed.y else: if self.velocity.y > -max_speed.y: self.velocity.y += speed.y def update_rotation(self): self.image = pygame.transform.rotate(self.original_image, self.angle) self.rect = self.image.get_rect(center=self.rect.center) self.direction = self.calculate_direction() def update(self, keys, delta): self.movement(keys, delta) self.draw(window) ship = Ship((400, 400)) run = True current_velocity = pygame.Vector2(ship.velocity) velocity = "x: {:.3f}, y: {:.3f}" font = pygame.font.Font(None, 28) text = Text(velocity.format(0, 0), font, pygame.Color('white'), (10, 10)) sprites = pygame.sprite.Group() sprites.add(ship, text) while run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False delta = clock.tick(60) keys = pygame.key.get_pressed() window.fill(pygame.Color('black')) sprites.update(keys, delta) if current_velocity != ship.velocity: current_velocity = pygame.Vector2(ship.velocity) text.render(velocity.format(*current_velocity)) sprites.draw(window) pygame.display.flip() RE: Terrible Sprite controls, need help. - michael1789 - Dec-18-2019 You've really gone above and beyond for me. I appreciate the effort immensely. |