Skip to content

Instantly share code, notes, and snippets.

@NaPs
Created January 3, 2009 17:53
Show Gist options
  • Select an option

  • Save NaPs/42908 to your computer and use it in GitHub Desktop.

Select an option

Save NaPs/42908 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
#coding=utf8
import pygame; import pygame.font; pygame.init()
from pygame.locals import *
import sys
from random import randint
import time
import math
is_neg = lambda x: not x == abs(x)
class Shuttle(pygame.sprite.Sprite):
'''This class represent a shuttle.
Arguments:
- initial_position: The first position to draw the shuttle on
the screen.
Attributes:
- speed: Current speed of shuttle
- angle: Current angle of moving vector
- angle_displ: Current angle of shuttle for displaying
Methods:
- update(): Update the position of shuttle
- draw(surface): Draw the shuttle on `surface`
- accelerate(): Increase the speed of shuttle (used by timer)
- deccelerate(): Decrease the speed of shuttle (used by timer)
'''
DIRS = {
(0, 1): 270, # haut
(1, 0): 0, # droite
(1, 1): 315, # haut-droite
(0, -1): 90, # bas
(-1, 0): 180, # gauche
(-1, -1): 135, # bas-gauche
(1, -1): 45, # bas-droite
(-1, 1): 225, # haut-gauche
}
def __init__(self, world_limits, initial_position=(200, 200)):
pygame.sprite.Sprite.__init__(self)
self.position = initial_position
self.world_limits = world_limits
pygame.time.set_timer(USEREVENT + 1, 40)
self.keys = [] # List of keys currently pushed
self.speed = 0 # The current speed
self.max_speed = 6 # Max speed
self.angle = 0 # Angle of moving vector
self.displ_angle = 0
ix, iy = initial_position
self.points = [
(ix + 4, iy),
(ix, iy),
(ix, iy + 4),
(ix + 4, iy + 6),
(ix + 2, iy + 8),
(ix - 2, iy + 8),
(ix - 4, iy + 6),
(ix - 4, iy - 6),
(ix - 2, iy - 8),
(ix + 2, iy - 8),
(ix + 4, iy - 6),
(ix, iy - 4),
(ix, iy),
]
self.rect = None
def _rad_angle(self):
'''Return the current angle of moving vector in radian'''
angle = self.angle
if angle > 180:
angle -= 360
return angle * math.pi / 180
def update(self):
'''Update the shuttle position'''
self.make_motion()
self.make_rotation()
def draw(self, surface):
'''Draw the shuttle on `surface`'''
pygame.draw.lines(
surface,
(255, 255, 255),
True,
self.points
)
pygame.draw.circle(
surface,
(50, 50, 50),
self.position,
100,
1
)
pygame.draw.aaline(
surface,
(100, 0, 0),
self.position,
pygame.mouse.get_pos(), # FIX : FAIRE UN CALCUL POUR QUE LE LASER AILLES JUSQU'AU BOUT DE LA SURFACE
)
pygame.draw.line(
surface,
(255, 0, 0),
(pygame.mouse.get_pos()[0] - 5, pygame.mouse.get_pos()[1]),
(pygame.mouse.get_pos()[0] + 6, pygame.mouse.get_pos()[1]),
2
)
pygame.draw.line(
surface,
(255, 0, 0),
(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1] - 5),
(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1] + 6),
2
)
def make_accel(self):
'''Make the acceleration (or decceleration) by incremention or
decrementation of speed (called by a timer)'''
if self.keys:
if self.speed < self.max_speed:
self.speed += 1
if self.speed > self.max_speed:
self.speed = self.max_speed
else:
if self.speed > 0:
self.speed -= 1
if self.speed < 0:
self.speed = 0
def make_motion(self):
'''Move the shuttle on the game'''
if self.keys:
dir = [0, 0]
for k in self.keys:
if k == K_UP:
dir[1] += 1
elif k == K_DOWN:
dir[1] -= 1
elif k == K_LEFT:
dir[0] -= 1
elif k == K_RIGHT:
dir[0] += 1
if dir != [0, 0]:
if self.DIRS[tuple(dir)] != self.angle:
self.speed = int(self.speed/3.0)
self.angle = self.DIRS[tuple(dir)]
# Moving position point of shuttle
xp, yp = self.position
move_xp = xp + (self.speed * math.cos(self._rad_angle()))
move_yp = yp + (self.speed * math.sin(self._rad_angle()))
self.position = (move_xp, move_yp)
if self.position[0] >= self.world_limits[0] \
or self.position[0] <= self.world_limits[2] \
or self.position[1] >= self.world_limits[1] \
or self.position[1] <= self.world_limits[3]:
self.position = (xp, yp)
else:
# Moving all points of shuttle
new_points = []
for x, y in self.points:
move_x = x + (self.speed * math.cos(self._rad_angle()))
move_y = y + (self.speed * math.sin(self._rad_angle()))
new_points.append((move_x, move_y))
self.points = new_points
def accelerate(self, key):
'''Increase speed of shuttle (called by timer).'''
self.keys.append(key)
def deccelerate(self, key):
'''Decrease speed of shuttle (called by timer)'''
self.keys.remove(key)
def make_rotation(self):
'''Calculate the fix angle and apply it with _rotate()'''
# Retrieving angles and fixing for 0°
angle = self.angle
if angle == 0: angle = 360
displ_angle = self.displ_angle
if displ_angle == 0: displ_angle = 360
# Calculating fix angle
fix_angle = angle - self.displ_angle
# Applying some fix to fix_angle in some cases
if fix_angle > 180:
fix_angle = fix_angle - 360
elif fix_angle < -180:
fix_angle = fix_angle + 360
if fix_angle > 360:
fix_angle = fix_angle % 360
elif fix_angle < -360:
fix_angle = fix_angle % -360
# Applying rotation
if abs(fix_angle) > 5:
self._rotate(int(fix_angle/8))
else:
self._rotate(fix_angle)
def _rotate(self, deg):
'''Rotate shuttle in degrees'''
self.displ_angle += deg
self.displ_angle = self.displ_angle % 360
rad = deg * math.pi / 180
for i, p in enumerate(self.points):
x, y = p
xc, yc = self.position
new_x = math.cos(rad) * (x - xc) - math.sin(rad) * (y - yc) + xc
new_y = math.sin(rad) * (x - xc) + math.cos(rad) * (y - yc) + yc
self.points[i] = (new_x, new_y)
def main():
screen_size = (640, 480)
screen = pygame.display.set_mode(screen_size)
pygame.mouse.set_visible(False)
clock = pygame.time.Clock()
shuttle = Shuttle(world_limits=(400, 400, 10, 10))
while 0xBeef:
clock.tick(60)
for event in pygame.event.get():
# General events
if event.type == QUIT:
sys.exit()
# Keyboard events :
elif event.type == KEYDOWN:
if event.key == K_UP or event.key == K_DOWN \
or event.key == K_RIGHT or event.key == K_LEFT:
shuttle.accelerate(event.key)
elif event.type == KEYUP:
if event.key == K_UP or event.key == K_DOWN \
or event.key == K_RIGHT or event.key == K_LEFT:
shuttle.deccelerate(event.key)
if event.key == K_ESCAPE:
sys.exit()
# User events :
elif event.type == USEREVENT + 1: # Event from shuttle
shuttle.make_accel()
screen.fill((0, 0, 0)) # Space is black :)
screen.convert()
# Updating sprites
shuttle.update()
shuttle.draw(screen)
pygame.display.flip()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment