diff --git a/asset/asset.svg b/asset/asset.svg index 6b764c7..59acdb9 100644 --- a/asset/asset.svg +++ b/asset/asset.svg @@ -25,9 +25,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="20.055905" - inkscape:cx="-1045.8998" - inkscape:cy="197.95561" + inkscape:zoom="1.7727083" + inkscape:cx="-995.66764" + inkscape:cy="192.7389" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" @@ -36,7 +36,10 @@ inkscape:window-height="1023" inkscape:window-x="0" inkscape:window-y="27" - inkscape:window-maximized="1"> + inkscape:window-maximized="1" + inkscape:snap-grids="true" + inkscape:snap-to-guides="true" + inkscape:snap-intersection-paths="true"> @@ -57,13 +60,6 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> - + cx="-242.91277" + cy="219.68893" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + r="4.8156528" /> diff --git a/main.py b/main.py index a925ea2..abdee44 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,7 @@ import pygame -from models import Game, Perso, Carte +from models import Game, Perso, Carte, Camera pygame.init() @@ -24,7 +24,8 @@ RED=(255,0,0) carte = Carte('map_1.png') perso = Perso('Alice',660,1570,center_screen,pygame.K_z,pygame.K_s,pygame.K_q,pygame.K_d,323,'perso.png','canon.png','projectile1_right.png') -game = Game(carte,perso) +camera = Camera(660,1570,screen_width,screen_height,0.3) +game = Game(carte,perso,camera) clock = pygame.time.Clock() @@ -36,7 +37,7 @@ while not done: keystate = pygame.key.get_pressed() + pygame.mouse.get_pressed() - perso.check_keys(keystate,screen_width,screen_height,carte) + perso.check_keys(keystate,screen_width,screen_height,carte,camera) screen.fill(BACKGROUND) diff --git a/models.py b/models.py index c1a8579..a90a4f1 100644 --- a/models.py +++ b/models.py @@ -9,53 +9,85 @@ from math import atan, degrees,radians, cos, sin img_path = 'asset/' +max_fire_rate = 10 # in fires per seconds + cap_speed = 10 acceleration = 2 deceleration = 1.1 + class Game(): - def __init__(self,carte,perso): + def __init__(self,carte,perso,camera): self.carte = carte self.perso = perso + self.camera = camera def draw(self,surface): # draw the map - self.carte.draw(surface,self.perso.get_draw_offset()) + self.carte.draw(surface,self.camera) # draw the projectiles and remove them if needed to_remove = [] for k,proj in enumerate(self.perso.projectiles): if not proj.is_out(self.carte): proj.move() - proj.draw(surface, self.perso.get_draw_offset()) + #proj.draw(surface,camera) else: to_remove.append(k) if to_remove != []: for k in to_remove[::-1]: del self.perso.projectiles[k] - self.perso.draw(surface) + self.perso.draw(surface,self.camera) + self.camera.draw(surface) + + def get_offset(self): + #Return the position of the elements on the screen (camera) + return (self.perso.posx-self.camera.posx,self.perso.posy-self.camera.posy) + class Carte(): def __init__(self,texture): + self.posx = 0 + self.posy = 0 self.img = pygame.image.load('maps/'+texture).convert_alpha() self.rect = self.img.get_rect() self.mask = pygame.mask.from_surface(self.img) - def draw(self,surface,offset): - surface.blit(self.img,offset) + def draw(self,surface,camera): + offsetx,offsety = camera.get_offset() + surface.blit(self.img,(self.posx-offsetx,self.posy-offsety)) -class Perso(): +class Camera(): + def __init__(self,start_posx,start_posy,screen_width,screen_height,box_ratio): + self.posx = start_posx + self.posy = start_posy + self.screen_height = screen_height + self.screen_width = screen_width + self.box_ratio = box_ratio + self.box = pygame.Rect(int(screen_width*box_ratio), + int(screen_height*box_ratio), + int(screen_width*(1-2*box_ratio)), + int(screen_height*(1-2*box_ratio))) + + def draw(self,surface): + pass + # pygame.draw.line(surface, (255,0,0), (int(surface.get_width()/2-20),int(surface.get_height()/2)), (int(surface.get_width()/2+20),int(surface.get_height()/2)), 3) + # pygame.draw.line(surface, (255,0,0), (int(surface.get_width()/2),int(surface.get_height()/2-20)), (int(surface.get_width()/2),int(surface.get_height()/2+20)), 3) + # pygame.draw.rect(surface, (0,255,0), self.box, 3) + def get_offset(self): + return (int(self.posx-self.screen_width/2),int(self.posy-self.screen_height/2)) + + +class Perso(): def __init__(self,name,posx,posy,center_screen,key_up,key_down,key_left,key_right,key_fire,texture,texture_canon,texture_proj): self.name = name self.posx = posx self.posy = posy - self.posx_screen = center_screen[0] - self.posy_screen = center_screen[1] self.speed = [0,0] self.key_up = key_up @@ -79,7 +111,7 @@ class Perso(): self.projectiles = [] self.last_fire = time() - def check_keys(self,keystate,screen_width,screen_height,carte): + def check_keys(self,keystate,screen_width,screen_height,carte,camera): # If an interresting key is pressed if keystate[self.key_left] or keystate[self.key_right] or keystate[self.key_up] or keystate[self.key_down]: @@ -106,41 +138,83 @@ class Perso(): if not (keystate[self.key_up] or keystate[self.key_down]): self.speed[1] = int(self.speed[1]/deceleration) - # Update the position on x axis - self.posx = self.posx+self.speed[0] - # If new position cause to enter a wall, rollback to last position (i.e. don't move) - if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): - self.posx = self.posx-self.speed[0] - self.speed[0] = 0 - - # Update the position on y axis - self.posy = self.posy+self.speed[1] - if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): - self.posy = self.posy-self.speed[1] - self.speed[1] = 0 + # get pos of player on screen to check collision with the movement box + offsetx,offsety = camera.get_offset() + posx_screen = self.posx-offsetx + posy_screen = self.posy-offsety + + # perso in the box: + if camera.box.collidepoint(posx_screen,posy_screen): + print("IN THE BOX") + + # X AXIS + temp_pos = self.posx + self.posx = self.posx+self.speed[0] + if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): + self.posx = temp_pos + self.speed[0] = 0 + + # Recalculate position on screen to detect an exit of the box + posx_screen = self.posx-offsetx + if not camera.box.collidepoint(posx_screen,posy_screen): + # Exit of the box, move the box so that the player stays in it + camera.posx = camera.posx + self.speed[0] + + # Y AXIS + temp_pos = self.posy + self.posy = self.posy+self.speed[1] + if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): + self.posy = temp_pos + self.speed[1] = 0 + + # Recalculate position on screen to detect an exit of the box + posy_screen = self.posy-offsety + if not camera.box.collidepoint(posx_screen,posy_screen): + # Exit of the box, move the box so that the player stays in it + camera.posy = camera.posy + self.speed[1] + + + # perso not in the box + else: + print("NOT IN THE BOX") + # X AXIS + temp_pos = self.posx + self.posx = self.posx+self.speed[0] + if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): + self.posx = temp_pos + self.speed[0] = 0 + # If the perso really move, camera follow + else: + camera.posx = camera.posx + self.posx-temp_pos + + # Y AXIS + temp_pos = self.posy + self.posy = self.posy+self.speed[1] + if carte.mask.overlap(self.mask, (self.posx-self.perso_rect.center[0],self.posy-self.perso_rect.center[1])): + self.posy = temp_pos + self.speed[1] = 0 + # If the perso really move, camera follow + else: + camera.posy = camera.posy + self.posy-temp_pos if keystate[self.key_fire]: self.fire('bullet','asset/projectile') - def draw(self,surface): - #Calculate player rotation: - # if self.speed != [0,0]: - # if self.speed[0]!=0: - # self.degres_perso = -1*degrees(atan(self.speed[1]/self.speed[0])) - # if self.speed[0] < 0: - # self.degres_perso = 180+self.degres_perso - # else: - # self.degres_perso = ((self.speed[1]>0)*2-1)*-90 - # self.perso = pygame.transform.rotate(self.img_perso,self.degres_perso) + def draw(self,surface,camera): + + #Get offset and compute player position in screen + offsetx,offsety = camera.get_offset() + posx_screen = self.posx-offsetx + posy_screen = self.posy-offsety #Calculate canon rotation: x_mouse, y_mouse = pygame.mouse.get_pos() - if x_mouse==self.posx_screen: + if x_mouse==posx_screen: x_mouse+=0.1 - self.degres_canon = -1*degrees(atan((y_mouse-self.posy_screen)/(x_mouse-self.posx_screen))) - if x_mouse < self.posx_screen: + self.degres_canon = -1*degrees(atan((y_mouse-posy_screen)/(x_mouse-posx_screen))) + if x_mouse < posx_screen: self.degres_canon = 180+self.degres_canon self.canon = pygame.transform.rotate(self.img_canon,self.degres_canon) @@ -148,22 +222,19 @@ class Perso(): self.perso_rect = self.perso.get_rect() self.canon_rect = self.canon.get_rect() - # Blits - surface.blit(self.perso,(self.posx_screen-self.perso_rect.center[0],self.posy_screen-self.perso_rect.center[1])) - #hitbox = pygame.Rect(self.posx_screen-self.perso_rect.center[0],self.posy_screen-self.perso_rect.center[1],self.perso_rect[2],self.perso_rect[3]) - #print(hitbox) - surface.blit(self.canon,(self.posx_screen-self.canon_rect.center[0],self.posy_screen-self.canon_rect.center[1])) - #pygame.draw.rect(surface, (255,0,0), hitbox, 2) + + # blit player and canon + surface.blit(self.perso,(posx_screen-self.perso_rect.center[0],posy_screen-self.perso_rect.center[1])) + surface.blit(self.canon,(posx_screen-self.canon_rect.center[0],posy_screen-self.canon_rect.center[1])) + + #pygame.draw.rect(surface, (255,0,0), (int(move_box_ratio*scwidth),int(move_box_ratio*scheight),int(scwidth*(1-2*move_box_ratio)),int(scheight*(1-2*move_box_ratio))), 2) def fire(self,name,texture): - if (time()-self.last_fire> 0.2): + if (time()-self.last_fire> 1/max_fire_rate): new_proj = Projectile(name,self.texture_proj,(self.posx,self.posy),20,self.degres_canon) self.projectiles.append(new_proj) self.last_fire = time() - def get_draw_offset(self): - return((self.posx_screen-self.posx,self.posy_screen-self.posy)) - class Projectile(pygame.sprite.Sprite):