Posts: 419
Threads: 34
Joined: May 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()
Posts: 544
Threads: 15
Joined: Oct 2016
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()
99 percent of computer problems exists between chair and keyboard.
Posts: 544
Threads: 15
Joined: Oct 2016
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()
99 percent of computer problems exists between chair and keyboard.
Posts: 419
Threads: 34
Joined: May 2019
Wow, this thing works amazingly. Thank-you so very much. I shall give this code a place of honor.
Posts: 544
Threads: 15
Joined: Oct 2016
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).
99 percent of computer problems exists between chair and keyboard.
Posts: 544
Threads: 15
Joined: Oct 2016
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()
99 percent of computer problems exists between chair and keyboard.
Posts: 419
Threads: 34
Joined: May 2019
You've really gone above and beyond for me. I appreciate the effort immensely.
|