diff --git a/__pycache__/settings.cpython-38.pyc b/__pycache__/settings.cpython-38.pyc index c876cac..c026af0 100644 Binary files a/__pycache__/settings.cpython-38.pyc and b/__pycache__/settings.cpython-38.pyc differ diff --git a/__pycache__/sprites.cpython-38.pyc b/__pycache__/sprites.cpython-38.pyc index 69b4e61..239de78 100644 Binary files a/__pycache__/sprites.cpython-38.pyc and b/__pycache__/sprites.cpython-38.pyc differ diff --git a/img/grassLeft.png b/img/grassLeft.png new file mode 100644 index 0000000..2f24f39 Binary files /dev/null and b/img/grassLeft.png differ diff --git a/img/grassMid.png b/img/grassMid.png new file mode 100644 index 0000000..035adda Binary files /dev/null and b/img/grassMid.png differ diff --git a/img/grassRight.png b/img/grassRight.png new file mode 100644 index 0000000..53f4d96 Binary files /dev/null and b/img/grassRight.png differ diff --git a/main.py b/main.py index 82f739e..6b31a17 100644 --- a/main.py +++ b/main.py @@ -33,21 +33,32 @@ class Game: self.spritesheet1 = SpriteSheet(os.path.join(img_dir, spritesheet1)) self.spritesheet2 = SpriteSheet(os.path.join(img_dir, spritesheet2)) - # load sound + # load soundself. self.sound_dir = os.path.join(self.dir, 'sound') self.jump_sound = pygame.mixer.Sound(os.path.join(self.sound_dir, 'Jump13.wav')) + # load map + self.map_data = [] + with open(os.path.join(self.dir, 'map.txt'), 'rt') as f: + for line in f: + self.map_data.append(line) + def new(self): # starts a new game not a new program self.score = 0 self.all_sprites = pygame.sprite.Group() self.platforms = pygame.sprite.Group() - self.player = Player(self) + self.tile = pygame.sprite.Group() + + # spawn walls from map + for row, tiles in enumerate(self.map_data): + for col, tile in enumerate(tiles): + if tile == '1': + Tile(self, col, row) + if tile == 'P': + self.player = Player(self, col, row) #spawns player at 'P' map location self.all_sprites.add(self.player) - for plat in platform_list: - p = Platform(self, *plat) - self.all_sprites.add(p) - self.platforms.add(p) + pygame.mixer.music.load(os.path.join(self.sound_dir, '04 - Sanctuary.ogg')) self.run() @@ -56,7 +67,7 @@ class Game: pygame.mixer.music.play(loops=-1) self.playing = True while self.playing: - self.clock.tick(fps) + self.dt = self.clock.tick(fps) / 1000 self.events() self.update() self.draw() @@ -65,42 +76,25 @@ class Game: def update(self): # Game loop - Update self.all_sprites.update() - # check if player hits platform - hits = pygame.sprite.spritecollide(self.player, self.platforms, False) + # wrap around the screen + if self.player.pos.x > width: + self.player.pos.x = 0 + if self.player.pos.x < 0: + self.player.pos.x = width + + hits = pygame.sprite.spritecollide(self.player, self.tile, 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 + if self.player.y < lowest.y: # if falling on block - player remains on top of it + self.player.y = lowest.y - 1.3 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 + # collision when the player hits the block from below + if self.player.y > lowest.y - 0.5: + self.player.y = lowest.y + 1 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 -= abs(self.player.vel.x) - - # if player reaches 1/5 of the left side of the screen move screen - 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 += abs(self.player.vel.x) # Die, by falling of the screen if self.player.rect.bottom > height + 60: @@ -120,9 +114,16 @@ class Game: if event.key == pygame.K_UP: self.player.jump_cut() + def draw_grid(self): + for x in range(0, width, tilesize): + pygame.draw.line(self.screen, (169, 169, 169), (x, 0), (x, height)) + for y in range(0, height, tilesize): + pygame.draw.line(self.screen, (169, 169, 169), (0, y), (width, y)) + def draw(self): # Game loop - draw/render self.screen.fill((146, 244, 255)) + self.draw_grid() 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) diff --git a/map.txt b/map.txt new file mode 100644 index 0000000..75e23bb --- /dev/null +++ b/map.txt @@ -0,0 +1,15 @@ +.............................. +....P.....1................... +.............................. +.............................. +...............11............. +.............................. +....111....................... +...................111........ +...........111................ +................111........... +.............................. +.....111............111....... +1..........11111.............. +1............................1 +111111111111111111111111111111 \ No newline at end of file diff --git a/settings.py b/settings.py index 80c0e04..e06ae5f 100644 --- a/settings.py +++ b/settings.py @@ -1,8 +1,9 @@ import os import pygame -width = 800 -height = 425 +width = 960 # 960/32 = 30 +height = 480 # 480/32 = 15 +tilesize = 32 # 30/15 TILE SCREEN fps = 30 basic_font = 'courier new.ttf' textX, textY = 10, 10 @@ -17,21 +18,16 @@ sound_folder = os.path.join(game_folder, "sound") background = pygame.image.load('img/background.jpg') BG_colour = (69, 219, 222) score_font = '8-BIT WONDER.ttf' + # Player properties player_acc = 0.9 player_friction = -0.12 player_gravity = 1.2 player_jump = 17 -# Starting platforms -# X Y -platform_list = [(0, 220), (35, 220), (70, 220), (105, 220), - (90, 125) - ] - -main_floor = [] +# Platform/tile images +grass_left = pygame.image.load('img/grassLeft.png') +grass_middle = pygame.image.load('img/grassMid.png') +grass_right = pygame.image.load('img/grassRight.png') -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 7820b75..cfcef1c 100644 --- a/sprites.py +++ b/sprites.py @@ -1,8 +1,6 @@ # Sprite classes from settings import * import pygame -from random import choice - vec = pygame.math.Vector2 @@ -21,21 +19,22 @@ class SpriteSheet: class Player(pygame.sprite.Sprite): - def __init__(self, game): + def __init__(self, game, x, y): pygame.sprite.Sprite.__init__(self) self.game = game + self.load_images() + self.image = self.standing_frames[0] + self.image.set_colorkey((0, 0, 0)) self.walking = False self.jumping = False self.current_frame = 0 self.last_update = 0 - self.load_images() - self.image = self.standing_frames[0] - self.image.set_colorkey((0, 0, 0)) self.rect = self.image.get_rect() - self.rect.center = (width / 2, height / 2) - self.pos = vec(width / 2, height / 2) # x and y position - self.vel = vec(0, 0) # velocity in x and y axis - self.acc = vec(0, 0) # acceleration in x and y axis + self.x = x + self.y = y + self.pos = vec(x * tilesize, y * tilesize) + self.vel = vec(0, 0) + self.acc = vec(0, 0) def load_images(self): self.standing_frames = [self.game.spritesheet1.get_image(67, 190, 66, 92), @@ -71,9 +70,9 @@ class Player(pygame.sprite.Sprite): def jump(self): # jump only if standing on a platform - self.rect.y += 2 - hits = pygame.sprite.spritecollide(self, self.game.platforms, False) - self.rect.y -= 2 + self.y += 1 + hits = pygame.sprite.spritecollide(self, self.game.tile, False) + self.y -= 1 if hits and not self.jumping: self.game.jump_sound.play() self.jumping = True @@ -94,9 +93,11 @@ class Player(pygame.sprite.Sprite): self.vel += self.acc if abs(self.vel.x) < 0.1: self.vel.x = 0 - self.pos += self.vel + 0.5 * self.acc + self.x += (self.vel.x + 0.5 * self.acc.x) / 32 + self.y += (self.vel.y + 0.5 * self.acc.y) / 32 - self.rect.midbottom = self.pos # why is it recognized as a typo?? + self.rect.x = self.x * tilesize + self.rect.y = self.y * tilesize def animate(self): now = pygame.time.get_ticks() @@ -109,33 +110,32 @@ class Player(pygame.sprite.Sprite): if (now - self.last_update) > 100: self.last_update = now self.current_frame = (self.current_frame + 1) % len(self.walk_frames_l) - bottom = self.rect.bottom if self.vel.x > 0: self.image = self.walk_frames_r[self.current_frame] else: 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 self.current_frame = (self.current_frame + 1) % len(self.standing_frames) - bottom = self.rect.bottom self.image = self.standing_frames[self.current_frame] self.rect = self.image.get_rect() - self.rect.bottom = bottom -class Platform(pygame.sprite.Sprite): +class Tile(pygame.sprite.Sprite): # tile based def __init__(self, game, x, y): - self.groups = game.all_sprites, game.platforms - pygame.sprite.Sprite.__init__(self) + self.groups = game.all_sprites, game.tile + pygame.sprite.Sprite.__init__(self, self.groups) self.game = game - images = [self.game.spritesheet2.get_image(576, 792, 70, 70), - self.game.spritesheet2.get_image(720, 792, 70, 70)] - self.image = choice(images) - self.image.set_colorkey((0, 0, 0)) + self.image = pygame.Surface((tilesize, tilesize)) + self.image.fill((0, 128, 0)) self.rect = self.image.get_rect() - self.rect.x = x - self.rect.y = y + self.x = x + self.y = y + self.rect.x = x * tilesize + self.rect.y = y * tilesize + +class Powerup(pygame.sprite.Sprite): + pass diff --git a/tile_testing.py b/tile_testing.py new file mode 100644 index 0000000..39a57be --- /dev/null +++ b/tile_testing.py @@ -0,0 +1,30 @@ +import pygame + + +class spritesheet(object): + def __init__(self, filename): + self.sheet = pygame.image.load(filename).convert() + + # Load a specific image from a specific rectangle + def image_at(self, rectangle, colorkey=None): + "Loads image from x,y,x+offset,y+offset" + rect = pygame.Rect(rectangle) + image = pygame.Surface(rect.size).convert() + image.blit(self.sheet, (0, 0), rect) + if colorkey is not None: + if colorkey is -1: + colorkey = image.get_at((0, 0)) + image.set_colorkey(colorkey, pygame.RLEACCEL) + return image + + # Load a whole bunch of images and return them as a list + def images_at(self, rects, colorkey=None): + "Loads multiple images, supply a list of coordinates" + return [self.image_at(rect, colorkey) for rect in rects] + + # Load a whole strip of images + def load_strip(self, rect, image_count, colorkey=None): + "Loads a strip of images and returns them as a list" + tups = [(rect[0] + rect[2] * x, rect[1], rect[2], rect[3]) + for x in range(image_count)] + return self.images_at(tups, colorkey)