#MonthOfCode day 24 - space
import pygame | |
from time import sleep | |
import random | |
from math import cos,sin,pi | |
DISP_WIDTH = 800 | |
DISP_HEIGHT = 600 | |
class MobileElement: | |
MOMENTUM = 0.985 | |
'''abstract class representing something that moves''' | |
def __init__(self, x_init,y_init, vx_init, vy_init): | |
self.vx, self.vy = vx_init, vy_init | |
self.x,self.y = float(x_init), float(y_init) | |
self.disp_x, self.disp_y = int(round(x_init)), int(round(y_init)) | |
self.color= tuple( [random.randint(64,255) for i in xrange(3) ] ) | |
def updatePosition( self ): | |
self.x += self.vx | |
self.y += self.vy | |
self.vx *= MobileElement.MOMENTUM | |
self.vy *= MobileElement.MOMENTUM | |
def markToDisplay( self, surface): | |
raise Exception('please implement this function') | |
class SpaceShip(MobileElement): | |
'''models a moving triangle that can turn, accelerate and spawn particles''' | |
BASECOLOR = pygame.Color('blue') | |
BASE_SPEED = 10 | |
DELTA_ROTATION = 0.1 | |
def __init__(self, x_init, y_init): | |
MobileElement.__init__(self, x_init, y_init, 0., 0. ) | |
self.color = SpaceShip.BASECOLOR | |
self.angle = 0. | |
self.rotating_right = False | |
self.rotating_left = False | |
self.accelerating = False | |
self.time_accel = 0 | |
self.pts_calculators = [ | |
lambda x,y,angle: ( x + ( 0. * cos(angle) - (-30.) * sin(angle) ), | |
y + ( 0 * sin(angle) + (-40.) * cos(angle)) ), | |
lambda x,y,angle: ( x + ( -15.0 * cos(angle) - 10. * sin(angle) ), | |
y + ( -15.0 * sin(angle) + 10. * cos(angle)) ), | |
lambda x,y,angle: ( x + ( 15.0 * cos(angle) - 10. * sin(angle) ), | |
y + ( 15.0 * sin(angle) + 10. * cos(angle)) ) | |
] | |
def startAcceleration(self): | |
self.color = pygame.Color('lightblue') | |
self.accelerating = True | |
def stopAcceleration(self): | |
self.color = SpaceShip.BASECOLOR | |
self.accelerating = False | |
self.time_accel = 0 | |
def markToDisplay(self, surface): | |
pygame.draw.polygon( surface, | |
self.color, | |
[ f(self.x,self.y, self.angle) for f in self.pts_calculators ] ) | |
def updatePosition( self ): | |
if(self.rotating_right): | |
self.angle+= SpaceShip.DELTA_ROTATION | |
if self.angle>2*pi: | |
self.angle = self.angle-(2*pi) | |
if(self.rotating_left): | |
self.angle-= SpaceShip.DELTA_ROTATION | |
if self.angle<0: | |
self.angle = (2*pi) -self.angle | |
if self.accelerating: | |
ship_front = self.pts_calculators[0]( self.x, self.y, self.angle) | |
bonus_vx = ship_front[0]-self.x | |
bonus_vy = ship_front[1]-self.y | |
if (self.time_accel< 4096 ): | |
self.time_accel+= 1 | |
self.vx += ( 0.000001 * SpaceShip.BASE_SPEED * self.time_accel * bonus_vx) | |
self.vy += ( 0.000001 * SpaceShip.BASE_SPEED * self.time_accel * bonus_vy) | |
MobileElement.updatePosition( self) | |
# making the SPACE a torus-like topology | |
if( self.y<0 ): | |
self.y=DISP_HEIGHT-1 | |
elif(self.y>=DISP_HEIGHT): | |
self.y=0 | |
if( self.x<0 ): | |
self.x=DISP_WIDTH-1 | |
elif(self.x>=DISP_WIDTH): | |
self.x=0 | |
def refreshScreen(): | |
window.fill( pygame.Color('black') ) | |
ship.markToDisplay(window ) | |
pygame.display.flip() | |
# init. pygame libr; create the screen and diplays a help message in the console | |
pygame.init() | |
window = pygame.display.set_mode( (DISP_WIDTH, DISP_HEIGHT) ) | |
ship = SpaceShip( DISP_WIDTH/2, DISP_HEIGHT/2 ) | |
program_done = False | |
refreshScreen() | |
while not program_done: | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
program_done = True | |
break | |
if event.type is pygame.KEYDOWN: | |
if( pygame.key.get_pressed()[ pygame.K_UP ] ): | |
ship.startAcceleration() | |
if( pygame.key.get_pressed()[ pygame.K_RIGHT ] ): | |
ship.rotating_right=True | |
if( pygame.key.get_pressed()[ pygame.K_LEFT ] ): | |
ship.rotating_left=True | |
if event.type is pygame.KEYUP: | |
if( not pygame.key.get_pressed()[ pygame.K_UP ] ): | |
ship.stopAcceleration() | |
if( not pygame.key.get_pressed()[ pygame.K_RIGHT ] ): | |
ship.rotating_right=False | |
if( not pygame.key.get_pressed()[ pygame.K_LEFT ] ): | |
ship.rotating_left=False | |
ship.updatePosition() | |
refreshScreen() | |
sleep(0.01) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment