Goldenrod Adventure: The Best Platformer of 2024

I have been working on a making a platformer game for a shot while. I am calling it “Goldenrod Adventure” because most of it is two shades of one color. The game is only 4 levels, but still a decent game nonetheless in my opinion. Here is some of the code for the main file which is what runs the game.

import pygame
from settings import Settings
from map import Map
from player import Player
import time 
class Game:
    def __init__(self):
        self.clock = pygame.time.Clock()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((1500,1000))
        self.enemies = pygame.sprite.Group() 
        self.check_points = pygame.sprite.Group()
        pygame.display.set_caption("Goldenrod Adventure")
        self.map = Map(self)
        self.current_level = 1
        self._load_level()
        self.player = Player(self)
        self.running = True
        self.vertical_tracker = 0
        
        


        
    def run(self):
        while self.running:

            #Check events
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RIGHT:
                        self.player.moving_right = True

                            
                            
                    if event.key == pygame.K_LEFT:
                        self.player.moving_left = True


                    if event.key == pygame.K_SPACE:
                        self.player.jump()

                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_RIGHT:
                        self.player.moving_right = False
                    if event.key == pygame.K_LEFT:
                        self.player.moving_left = False

            #Update
            
            self.player.move(self.map)
            self.player.update(self.map)



            for enemy in self.enemies.sprites():
                enemy.move(self.map)
                enemy.update(self.map)
                
            self.scroll()
            


            #Draw Screen
            self.screen.fill(self.settings.bg_color)
            self.map.draw()
            self.player.draw()
            for enemy in self.enemies.sprites():
                enemy.draw()
            for cp in self.check_points.sprites():
                cp.draw()
            pygame.display.flip()
            self._check_dead()
            self._check_level_clear()
            self.clock.tick(60)

    def _load_level(self):
        self.map.load_level(self.current_level, self)

        



    def scroll(self):
        if (self.player.rect .x >= self.screen.get_rect().right - self.settings.scroll_offset)\
        and self.player.moving_right:
            self.player.rect.x -=self.settings.player_speed
            for object in self.map.map_objects:
                object.rect.x -= self.settings.player_speed
            for enemy in self.enemies:
                enemy.rect.x -=  self.settings.player_speed
            for cp in self.check_points:
                cp.rect.x -=  self.settings.player_speed

        if self.player.rect.top < self.screen.get_rect().top + self.settings.scroll_offset*2:
            self.vertical_tracker += self.player.y_acceleration
            if self.vertical_tracker < 0:
                
                self.vertical_tracker += self.player.y_acceleration
                self.player.rect.y -= self.player.y_acceleration
                for object in self.map.map_objects:
                    object.rect.y -= self.player.y_acceleration
                for enemy in self.enemies:
                    enemy.rect.y -= self.player.y_acceleration
                for cp in self.check_points:
                    cp.rect.y -= self.player.y_acceleration
            
    def _check_dead(self):
        collisions = pygame.sprite.spritecollideany(self.player, self.enemies)
        
        
        #if collisions and self.player.rect.bottom > collisio
        
        if self.player.rect.y > self.screen.get_rect().bottom + 100 or collisions:
            
            self.player.respawn(self)
            self.map.load_level(self.current_level, self)
            time.sleep(0.5)
            
    def _check_level_clear(self):
        if pygame.sprite.spritecollideany(self.player, self.check_points):
            self.current_level += 1
            self.player.respawn(self)
            self.map.load_level(self.current_level, self)



game = Game()
game.run() 

And here are a few screenshots from the game.

A basic obstacle

Bob, an enemy (Red), standing near the player (Dark Goldenrod Color)

I also have the rest of my code as of current, but will keep updating if I have good ideas.

Map Code:

import pygame
import pygame.sprite
from enemy import Enemy
from enemy import BigEnemy

class Object(pygame.sprite.Sprite):
    def __init__(self, game, x, y, width=200, height=30):
        super().__init__()
        self.screen = game.screen
        self.rect = pygame.Rect(x,y, width, height)
        self.color = "Goldenrod"

    def draw(self):
        pygame.draw.rect(self.screen, self.color, self.rect)


class Map:
    def __init__(self, game):
        self.map_objects = pygame.sprite.Group()
        self.check_point_x = 0
        self.settings = game.settings

    def load_level(self, level, game, offset=0):
        self.map_objects.empty()
        game.enemies.empty()
        game.check_points.empty()
        if level == 1:

            floor2 = Object(game, 500, 600, 400, 10)
            block1 = Object(game, 900, 300, width= self.settings.player_width, height= 500)
            floor3 = Object(game, 1200, 600, 400, 10)
            self.map_objects.add(Object(game, 0, 700, 400, 10))
            self.map_objects.add(floor2)
            self.map_objects.add(block1)
            self.map_objects.add(floor3)
            self.map_objects.add(Object(game,2000, 50))
            self.map_objects.add(Object(game,1800, 300))
            self.map_objects.add(Object(game, 3000, 800, 500))
            self.map_objects.add(Object(game, 4000, 400, 500))

            game.check_points.add(Flag(game, 5000, 500, 500))

            enemy = Enemy(game, 200, 300)
            game.enemies.add(enemy)

        if level == 2:
            self.map_objects.add(Object(game, 0, 900, 900, 100))
            self.map_objects.add(Object(game, 1200, 600, 100))
            self.map_objects.add(Object(game, 1500, 500, 100, self.settings.player_width))
            self.map_objects.add(Object(game, 2000, 900, 600, self.settings.player_width))
            self.map_objects.add(Object(game, 2800, 565, 100))

            game.check_points.add(Flag(game, 3500, 565, 100))

        if level == 3:
            floor2 = Object(game, 500, 600, 400, 10)
            floor3 = Object(game, 1200, 600, 400, 10)
            self.map_objects.add(Object(game, 0, 700, 400, 10))
            self.map_objects.add(floor2)
            self.map_objects.add(floor3)
            self.map_objects.add(Object(game,2000, 50))
            self.map_objects.add(Object(game,1800, 300))
            self.map_objects.add(Object(game, 3000, 800, 500))
            self.map_objects.add(Object(game, 4000, 400, 500))

            game.check_points.add(Flag(game, 5000, 500, 500))

            enemy = Enemy(game, 200, 300)
            enemy2 = Enemy(game, 180, 300)
            enemy3 = Enemy(game, 160, 300)
            enemy4 = Enemy(game, 140, 300)
            enemy5 = Enemy(game, 120, 300)
            
            enemy6 = Enemy(game, 500, 200)
            enemy7 = Enemy(game, 530, 200)
            enemy8 = Enemy(game, 560, 200)
            
            game.enemies.add(enemy)
            game.enemies.add(enemy2)
            game.enemies.add(enemy3)
            game.enemies.add(enemy4)
            game.enemies.add(enemy5)
            game.enemies.add(enemy6)
            game.enemies.add(enemy7)
            game.enemies.add(enemy8)
        
        for object in self.map_objects.sprites():
            object.rect.x += offset

        if level ==4:
            self.map_objects.add(Object(game, 0, 700, 800, 30))
            game.check_points.add(Flag(game, 800, 700, 500))
            benemy = BigEnemy(game, 400, 10)
            game.enemies.add(benemy)


            
            


    def draw(self):
        for object in self.map_objects:
            object.draw()
        



class Flag(Object):
    def __init__(self, game, x, y, width=30, height=30, type = "end_level"):
        super().__init__(game, x, y, width, height)
        self.color = "Dark Goldenrod"
        self.type = type

Enemy Code:

from player import Player
import pygame

class Enemy(Player):
    def __init__(self,game, x, y):
        super().__init__(game)

        self.x = x
        self.y = y
        self.color = "Red"
        self.rect.topleft = (x, y)
        self.speed = 1
        self.moving_left = True

class BigEnemy(Player):
    def __init__(self,game, x, y):
        super().__init__(game)

        self.x = x
        self.y = y
        self.color = "Red"
        self.rect.topleft = (x, y)
        self.speed = 1
        self.moving_left = False
        self.rect = pygame.Rect(0,0,self.settings.player_width*40,30)

Player Code:

import pygame.sprite

class Player(pygame.sprite.Sprite):
    """A class to manage the player sprite"""

    def __init__(self, game) -> None:
        super().__init__()
        self.respawn_x = 0
        self.respawn_y = 500
        self.screen = game.screen
        self.settings = game.settings
        self.color = "Dark Goldenrod"
        self.rect = pygame.Rect(0,0,self.settings.player_width,30)
        self.rect.topleft = (0, 500)
        self.y_acceleration = 0
        self.falling = True
        self.moving_left = self.moving_right = False
        self.jump_count = 0
        self.speed = self.settings.player_speed
    
    def draw(self):
        pygame.draw.rect(self.screen, self.color, self.rect)
        #Change to blit if you want to use an image

    def update(self, map):
        
        if self.falling:
            self.rect.y += self.y_acceleration

            self.y_acceleration += float(self.settings.y_acceleration)
        self._check_collisions(map)
        
        


    def landed(self):
        self.falling = False
        self.y_acceleration = 0
        self.jump_count=0
        

    def move(self, map):

        if self.moving_right and not self.collide("right", map.map_objects):
            self.rect.x += self.speed
        if self.moving_left and not self.collide("left", map.map_objects) and self.rect.left > 0:
            self.rect.x -= self.speed

 
    def jump(self):
        if self.jump_count <= 1:
            self.jump_count += 1
            self.y_acceleration = -8 #Testing
            self.falling = True

    def collide(self, direction, objects):
        if direction == "right":
            vel = self.speed

        elif direction == "left":
            vel = -self.speed

        self.rect.x += vel
        
        collided_object = None
        for obj in objects:
            if pygame.sprite.spritecollideany(self, objects):
                collided_object = obj
                
                break
        self.rect.x -= vel
        
        return collided_object
    
    def respawn(self, game):
        self.rect.topleft = (self.respawn_x, self.respawn_y)
        self.y_acceleration = 0
        self.jump_count = 0
        game.vertical_tracker = 0
        


    def _check_collisions(self, map):
        collisions = pygame.sprite.spritecollideany(self, map.map_objects)
        
        if collisions:
            if self.y_acceleration > 0 and self.falling: #aka moving down
                self.rect.bottom = collisions.rect.top  
                self.landed()          

            elif self.y_acceleration < 0 and self.falling: #Hit our head
                self.rect.top = collisions.rect.bottom
                self.y_acceleration = 0
            
        else:
            self.falling = True

Settings Code:

class Settings:
    def __init__(self):
        self.player_width = 20
        self.bg_color = (100,100,100)
        self.player_speed = float(15.69)
        self.y_acceleration = float(0.1)

        self.scroll_offset = 800

This is currently all the code I have but I will continue updating probably until around June 4th.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *