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.
Leave a Reply