Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Example Driving a car. Turning with reverse need fix.
- import os
- import pygame
- from types import SimpleNamespace
- from pygame.sprite import Sprite, Group
- # Wrap pygame builtin colors into namespace.
- color = SimpleNamespace(**pygame.color.THECOLORS)
- # Interface
- class Scene:
- def __init__(self, manager):
- self.manager = manager
- def on_draw(self, surface): pass
- def on_event(self, event): pass
- def on_update(self, delta): pass
- def on_quit(self):
- self.manager.quit()
- # Handles what scene is active
- class Manager:
- def __init__(self, caption, width, height, center=True, flags=0):
- if center:
- os.environ['SDL_VIDEO_CENTERED'] = '1'
- # Basic pygame setup
- pygame.display.set_caption(caption)
- self.surface = pygame.display.set_mode((width, height), flags)
- self.rect = self.surface.get_rect()
- self.clock = pygame.time.Clock()
- self.running = False
- self.delta = 0
- self.fps = 60
- self.scene = Scene(self)
- def mainloop(self):
- self.running = True
- while self.running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- self.scene.on_quit()
- else:
- self.scene.on_event(event)
- self.scene.on_update(self.delta)
- self.scene.on_draw(self.surface)
- pygame.display.flip()
- self.delta = self.clock.tick(self.fps)
- def quit(self):
- self.running = False
- class Text(Sprite):
- def __init__(self, text, font, color, position, anchor="topleft"):
- Sprite.__init__(self)
- self.font = font
- self.color = color
- self.position = position
- self.anchor = anchor
- self.render(text)
- def draw(self, surface):
- surface.blit(self.image, self.rect)
- def render(self, text):
- self.image = self.font.render(text, 1, self.color)
- self.rect = self.image.get_rect(**{self.anchor: self.position})
- class SimpleSprite(Sprite):
- def __init__(self, image, position, anchor="topleft"):
- Sprite.__init__(self)
- self.image = image
- self.rect = image.get_rect(**{anchor: position})
- def draw(self, surface):
- surface.blit(self.image, self.rect)
- class Movement:
- def __init__(self, sprite, speed=2, rotate_speed=120, friction=0.1, max_speed=400):
- self.angle = 180
- self.sprite = sprite
- self.center = sprite.rect.center
- self.orignal_image = sprite.image
- self.velocity = pygame.Vector2(0, 0)
- self.vector = self.get_vector()
- self.speed = speed * 0.001
- self.friction = friction * 0.001
- self.max_speed = max_speed * 0.001
- self.rotate_speed = rotate_speed * 0.001
- def apply_friction(self, delta):
- friction = self.get_vector() * self.friction * delta
- friction = abs(friction.elementwise())
- if self.velocity.x > 0:
- self.velocity.x -= friction.x
- if self.velocity.x < 0:
- self.velocity.x = 0
- elif self.velocity.x < 0:
- self.velocity.x += friction.x
- if self.velocity.x > 0:
- self.velocity.x = 0
- if self.velocity.y > 0:
- self.velocity.y -= friction.y
- if self.velocity.y < 0:
- self.velocity.y = 0
- elif self.velocity.y < 0:
- self.velocity.y += friction.y
- if self.velocity.y > 0:
- self.velocity.y = 0
- def forward(self):
- self.velocity += self.vector * self.speed
- self.speed_cap()
- def get_vector(self):
- vector = pygame.Vector2(0, 0)
- vector.from_polar((1, self.angle))
- vector.x, vector.y = vector.y, vector.x
- return vector
- def move(self, delta):
- self.center += self.velocity * delta
- self.sprite.rect.center = self.center
- def reverse(self):
- self.velocity -= self.vector * self.speed * 0.5
- self.speed_cap()
- def rotate_left(self, delta):
- self.angle = (self.angle + self.rotate_speed * delta) % 360
- self.rotation()
- def rotate_right(self, delta):
- self.angle = (self.angle - self.rotate_speed * delta) % 360
- self.rotation()
- def rotation(self):
- image = pygame.transform.rotate(self.orignal_image, self.angle)
- self.sprite.image = image
- self.sprite.rect = image.get_rect(center=self.center)
- self.vector = self.get_vector()
- self.velocity.rotate_ip(self.velocity.angle_to(self.vector))
- def speed_cap(self):
- mspeed = self.max_speed * self.get_vector()
- mspeed = abs(mspeed.elementwise())
- if self.velocity.x > 0:
- self.velocity.x = min(self.velocity.x, mspeed.x)
- else:
- self.velocity.x = max(self.velocity.x, -mspeed.x)
- if self.velocity.y > 0:
- self.velocity.y = min(self.velocity.y, mspeed.y)
- else:
- self.velocity.y = max(self.velocity.y, -mspeed.y)
- class Keys:
- def __init__(self, movement,
- up=(pygame.K_UP, pygame.K_w),
- down=(pygame.K_DOWN, pygame.K_s),
- left=(pygame.K_LEFT, pygame.K_a),
- right=(pygame.K_RIGHT, pygame.K_d)):
- self.up = up
- self.down = down
- self.left = left
- self.right = right
- self.movement = movement
- def update(self, delta, pressed):
- if any([pressed[k] for k in self.up]):
- self.movement.forward()
- elif any([pressed[k] for k in self.down]):
- self.movement.reverse()
- else:
- self.movement.apply_friction(delta)
- if any([pressed[k] for k in self.left]):
- self.movement.rotate_left(delta)
- elif any([pressed[k] for k in self.right]):
- self.movement.rotate_right(delta)
- self.movement.move(delta)
- class Player:
- def __init__(self, center):
- surface = pygame.Surface((6, 10), pygame.SRCALPHA)
- surface.fill(color.firebrick)
- self.sprite = SimpleSprite(surface, center, "center")
- self.movement = Movement(self.sprite)
- self.keys = Keys(self.movement)
- def draw(self, surface):
- self.sprite.draw(surface)
- def update(self, delta, pressed):
- self.keys.update(delta, pressed)
- class MainScene(Scene):
- def __init__(self, manager):
- Scene.__init__(self, manager)
- self.player = Player(manager.rect.center)
- self.position_template = "{:.2f}, {:.2f}"
- position = self.position_template.format(*self.player.movement.velocity)
- font = pygame.font.Font(None, 28)
- self.str_position = Text(position, font, color.lawngreen, (10, 10))
- def on_draw(self, surface):
- surface.fill(color.black)
- self.player.draw(surface)
- self.str_position.draw(surface)
- def on_update(self, delta):
- pressed = pygame.key.get_pressed()
- self.player.update(delta, pressed)
- position = self.position_template.format(*self.player.movement.velocity)
- self.str_position.render(position)
- if __name__ == "__main__":
- pygame.init()
- manager = Manager("Example", 800, 600)
- manager.scene = MainScene(manager)
- manager.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement