From 7607ac804ab1778cef2e9a80736112396da3ced2 Mon Sep 17 00:00:00 2001 From: "Goncalo Lourenco (dacostag)" Date: Wed, 29 Apr 2020 16:08:00 +0100 Subject: [PATCH] Improved platform collision Further improved player/platform collision but it's still a little buggy when jumping against a block on its side while having another one below --- __pycache__/settings.cpython-38.pyc | Bin 1035 -> 1020 bytes __pycache__/sprites.cpython-38.pyc | Bin 4299 -> 4341 bytes main.py | 66 ++++++++++++++++------------ settings.py | 17 ++++--- sprites.py | 16 ++++--- 5 files changed, 59 insertions(+), 40 deletions(-) diff --git a/__pycache__/settings.cpython-38.pyc b/__pycache__/settings.cpython-38.pyc index 470431f84f9f6cd076450c9613d58645217eab05..c876cacaa6778e421f86a76c832041d4d5e272fd 100644 GIT binary patch delta 256 zcmeC?_`|Lp%FD~e00d8_uZ&y7%)sy%#6bpZK#l_t7hjsF-5Zw98YP|15G9i;o5GMH z(ahw+5Ni-6mnySBK2HV zGbi3tVq~7o$Qa0YYjQASB%|QuwT!0HFQb4eUesgASM|`^(d~~ z#LT?-w4D6>qFby*iFxU%w-_^Tu_YE1q~@ipWGGSv=}?_q&K$yMGWiU%7B342Bh!Bt L78WKxMlnVJbGkY) delta 287 zcmeyv-p!#M%FD~e00dg8E8=>Y85kaeILLq($Z-JT;zbj+d(~1TQY2HPQlwL4Qe;!) zQsmQlqoh+9gBdgxUV=3FWhwy8csZGmQHhadvLRz2W7Onk#z;o~$#)q|>x&qHN{X0( zgeFrFHxio%i4C$3swN%C1cFM3m%o6NCR1iE(10R72-^#Zt&U*7i~>r(tOco&xy6)U ze2cB1GCeUj^%iUSW*a76M$VNCMM^-~BBjX%%pr_6laDfMiL!DqGBJQ5g8mBtb_z1b diff --git a/__pycache__/sprites.cpython-38.pyc b/__pycache__/sprites.cpython-38.pyc index f370e6b6255a81f349f37a57be4f29793c01c7de..69b4e612658fb5eeed0cefd513a79d073cfe1a37 100644 GIT binary patch delta 304 zcmX@D_*IcFl$V!_0SIn%u8d<6-^ka>F?la%2BY(2H7?7^3pm~|dQ9%+G}s)()yc>h zwD}JA8%Fh1pz>lJkS0bhMjl2ECN?HEMm|P1MlnVXAYXuq4=g(QJ+C#R{bX%EYi3ps zuF08v@%0TrJvEG3Ak3J?RKpO@RKlFalEu1!t%hMCBO_28D8^pHkj0+Gv4As$F@-6G zIfZ#43tWT+CX&un%TmHs!_o}W!3~t>Uci&W3N{18=3U4D6z8h}+L6T<&tJm~rWpk$ zTk$JO3*O>R%*lx_E-1<@Ni8mN1Ul*#TY6D`X+iPi82(0{W}rZ^7?5CKSR&(nrJq delta 274 zcmYL^ze)o^5XR@*+uLmRa+?!E`q-#wVJm5bSf>fG^qR%wuGDm{Nc_{;%?sRhwvxy2 z6?_E2%0futt{@H!GxMAIKA5l3+sMxI+)xO0^K!8mzS<|v``vF$c-I^=>m{bV)hC(IlQ) zfIK{v(o-$#v{4RDxWpyxKaqcAA#UZW 0: - hits = pygame.sprite.spritecollide(self.player, self.platforms, False) - if hits: - lowest = hits[0] - for hit in hits: - if hit.rect.bottom > lowest.rect.bottom: - lowest = hit - #if self.player.pos.x < lowest.rect.right +20 and self.player.pos.x > lowest.rect.left + 20: - if self.player.pos.y < lowest.rect.centery: - self.player.pos.y = lowest.rect.top - self.player.vel.y = 0 - self.player.jumping = False - - # if player reaches 3/4 of width of the screen - if self.player.rect.x >= (width * 0.6): + # check if player hits platform + hits = pygame.sprite.spritecollide(self.player, self.platforms, False) + if hits: + lowest = max(hits, key=lambda x: x.rect.bottom) + highest = min(hits, key=lambda x: x.rect.bottom) + #print("Player pos top:", str(self.player.rect.left), "y", str(self.player.pos.x), "bottom", + #str(self.player.rect.right)) + if self.player.pos.y < lowest.rect.centery - 5: # if falling on block - player remains on top of it + self.player.pos.y = lowest.rect.top + self.player.vel.y = 0 + self.player.jumping = False + # if player hits block from the side + if self.player.rect.right > highest.rect.left or self.player.rect.left < highest.rect.right: + if self.player.pos.y > highest.rect.centery: + if self.player.rect.right > highest.rect.left: + self.player.pos.x = highest.rect.left - 18 # 18 is 1 pixel more then half the width of the player sprite + if self.player.rect.left < highest.rect.right: + self.player.pos.x = highest.rect.right + 18 + self.player.vel.x = 0 + self.player.vel.y = 2 + + if self.player.pos.y > lowest.rect.bottom: # if jumping from below - player hits his head on the platform + self.player.rect.top = lowest.rect.bottom + 5 + self.player.vel.y = 0 + + # if player reaches 3/5 of width of the screen + if self.player.rect.right >= (width * 0.6): self.player.pos.x -= abs(self.player.vel.x) for plat in self.platforms: - plat.rect.x -= self.player.vel.x + plat.rect.x -= abs(self.player.vel.x) # if player reaches 1/5 of the left side of the screen move screen - if self.player.rect.x <= (width * 0.2): + if self.player.rect.left <= (width * 0.2): self.player.pos.x += abs(self.player.vel.x) for plat in self.platforms: - plat.rect.x -= self.player.vel.x + plat.rect.x += abs(self.player.vel.x) # Die, by falling of the screen if self.player.rect.bottom > height + 60: @@ -110,7 +122,7 @@ class Game: def draw(self): # Game loop - draw/render - self.screen.fill(BG_colour) + self.screen.fill((146, 244, 255)) self.all_sprites.draw(self.screen) self.screen.blit(self.player.image, self.player.rect) self.draw_text("Score: " + str(self.score), 26, (255, 255, 255), 40, 15) @@ -122,10 +134,10 @@ class Game: # game start screen pygame.mixer.music.load(os.path.join(self.sound_dir, '01 - Opening.ogg')) pygame.mixer.music.play(loops=-1) - self.screen.fill(BG_colour) - self.draw_text(title, 48, (255, 255, 255), width / 2, int(height / 4) + 50) - self.draw_text("Arrows to move, Z to shoot", 22, (255, 255, 255), width / 2, int(height / 2)) - self.draw_text("Press a key to play", 22, (255, 255, 255), width / 2, int(height / 2) + 40) + self.screen.fill((209, 206, 29)) + self.draw_text(title, 48, (255, 255, 255), width // 2, height // 4 + 50) + self.draw_text("Arrows to move, Z to shoot", 22, (255, 255, 255), width // 2, height // 2) + self.draw_text("Press a key to play", 22, (255, 255, 255), width // 2, height // 2 + 40) pygame.display.flip() self.wait_for_key() pygame.mixer.music.fadeout(1000) @@ -137,9 +149,9 @@ class Game: if not self.running: return self.screen.fill(BG_colour) - self.draw_text("GAME OVER", 48, (255, 255, 255), width / 2, int(height / 4) + 50) - self.draw_text("Final Score: " + str(self.score), 22, (255, 255, 255), width / 2, int(height / 2)) - self.draw_text("Press a key to play again", 22, (255, 255, 255), width / 2, int(height / 2) + 40) + self.draw_text("GAME OVER", 48, (255, 255, 255), width // 2, height // 4 + 50) + self.draw_text("Final Score: " + str(self.score), 22, (255, 255, 255), width / 2, height // 2) + self.draw_text("Press a key to play again", 22, (255, 255, 255), width // 2, height // 2 + 40) pygame.display.flip() self.wait_for_key() pygame.mixer.music.fadeout(1000) diff --git a/settings.py b/settings.py index 188ac6b..80c0e04 100644 --- a/settings.py +++ b/settings.py @@ -21,12 +21,17 @@ score_font = '8-BIT WONDER.ttf' player_acc = 0.9 player_friction = -0.12 player_gravity = 1.2 -player_jump = 15 +player_jump = 17 # Starting platforms - # X Y -platform_list = [(0, 220),(35, 220), (70, 220), (105, 220), - (0, 425), (35, 425), (70, 425), (105, 425), - (800 / 2, 250), (365, 250), (330, 250), (295, 250), - (90, 125)] +platform_list = [(0, 220), (35, 220), (70, 220), (105, 220), + (90, 125) + ] + +main_floor = [] + +for i in range(0, 50): + main_floor.append((i * 35, height-35)) + main_floor.append((i * 35, height-70)) + diff --git a/sprites.py b/sprites.py index db6386f..7820b75 100644 --- a/sprites.py +++ b/sprites.py @@ -64,6 +64,11 @@ class Player(pygame.sprite.Sprite): self.jump_frame_l = pygame.transform.flip(self.jump_frame_r, True, False) self.jump_frame_l.set_colorkey((0, 0, 0)) + def jump_cut(self): + if self.jumping: + if self.vel.y < -3: + self.vel.y = -3 + def jump(self): # jump only if standing on a platform self.rect.y += 2 @@ -74,12 +79,6 @@ class Player(pygame.sprite.Sprite): self.jumping = True self.vel.y = -player_jump - - def jump_cut(self): - if self.jumping: - if self.vel.y < -3: - self.vel.y = -3 - def update(self): self.animate() self.acc = vec(0, player_gravity) @@ -97,7 +96,7 @@ class Player(pygame.sprite.Sprite): self.vel.x = 0 self.pos += self.vel + 0.5 * self.acc - self.rect.midbottom = self.pos + self.rect.midbottom = self.pos # why is it recognized as a typo?? def animate(self): now = pygame.time.get_ticks() @@ -105,6 +104,7 @@ class Player(pygame.sprite.Sprite): self.walking = True else: self.walking = False + # show walking animation if self.walking: if (now - self.last_update) > 100: self.last_update = now @@ -116,6 +116,7 @@ class Player(pygame.sprite.Sprite): self.image = self.walk_frames_l[self.current_frame] self.rect = self.image.get_rect() self.rect.bottom = bottom + # show idle animation if not self.jumping and not self.walking: if (now - self.last_update) > 400: self.last_update = now @@ -128,6 +129,7 @@ class Player(pygame.sprite.Sprite): class Platform(pygame.sprite.Sprite): def __init__(self, game, x, y): + self.groups = game.all_sprites, game.platforms pygame.sprite.Sprite.__init__(self) self.game = game images = [self.game.spritesheet2.get_image(576, 792, 70, 70),