Tell me more ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a platforming game that is similar to doodle jump. I have code with a preset lvl, but I want the game to generate platforms randomly as the player ascends. Another problem I have is that the game doesn't scroll up as the character (block in this case) move up. If anyone can make suggestions I would really appreciate it.

I got the camera to work in my answer. [complete]

Generator algorithm [work in progress] ;get 2 or more pages of platforms and output them on top of each other randomly ;or get a algorithm to generate the platforms within 2 ranges of the x/y axis

NOTE:Does anyone know how to set it so player can spawn on the other side of the screen if they go off-screen?

import pygame
import math
from pygame import *
DISPLAY = (800, 640)
DEPTH = 32
FLAGS = 0
# in blocks, 25 x 20
def main():
    pygame.init()
    screen = display.set_mode(DISPLAY, FLAGS, DEPTH)
    display.set_caption("Rocket Jump!")
    timer = time.Clock()
    up = down = left = right = False
    bg = Surface((32,32))
    bg.convert()
    bg.fill(Color("#000000"))
    entities = pygame.sprite.Group()
    player = Player(32, 32)
    platforms = []
    x = y = 0
    level = [
    "                        ",
    "                        ",
    "           E            ",
    "        PPPPPP          ",
    "        pppppp          ",
    "  PPPPP pppppp          ",
    "                   PPPPP",
    "                        ",
    "                        ",
    "              PPPPP     ",
    "                        ",
    "                        ",
    "       PPPPPP           ",
    "                        ",
    "                  PPPPP ",
    "                        ",
    "          PPPPPP        ",
    "                        ",
    "PPPPP                   ",
    "                        ",]
    # build the level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = ExitBlock(x, y)
                platforms.append(e)
                entities.add(e)
            x += 32
        y += 32
        x = 0

    entities.add(player)
    while 1:
        timer.tick(60)
        for e in pygame.event.get():
            if e.type == QUIT: raise SystemExit, "QUIT"
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                raise SystemExit, "ESCAPE"
            if e.type == KEYDOWN and e.key == K_UP:
                            pass
            if e.type == KEYDOWN and e.key == K_DOWN:
                down = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right = True

            if e.type == KEYUP and e.key == K_UP:
                up = False
            if e.type == KEYUP and e.key == K_DOWN:
                down = False
            if e.type == KEYUP and e.key == K_LEFT:
                left = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False
        # draw background
        for y in range(20):
            for x in range(25):
                screen.blit(bg, (x * 32, y * 32))

        # update player, draw everything else
        player.update(up, down, left, right, platforms)
        entities.draw(screen)

        pygame.display.flip()

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)


class Player(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = Surface((32, 32))
        self.image.convert()
        self.image.fill(Color("#FFFFF0"))
        self.rect = Rect(x, y, 32, 32)


    def update(self, up, down, left, right, platforms):
        if up:
            # only jump if on the ground
            if self.onGround: self.yvel -= 8
        if down:
            pass
        if left:
            self.xvel = -5
        if right:
            self.xvel = 5
        if not self.onGround:
            # only accelerate with gravity if in the air
            self.yvel += 0.3
            # max falling speed
            if self.yvel > 30: self.yvel = 30
        if not(left or right):
            self.xvel = 0
        # increment in x direction
        self.rect.left += self.xvel
        # do x-axis collisions
        self.collide(self.xvel, 0, platforms)
        # increment in y direction
        self.rect.top += self.yvel
        # assuming we're in the air
        self.onGround = False;
        # do y-axis collisions
        self.collide(0, self.yvel, platforms)

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if sprite.collide_rect(self, p):
                if isinstance(p, ExitBlock):
                    event.post(event.Event(QUIT))
                if xvel > 0: self.rect.right = p.rect.left
                if xvel < 0: self.rect.left = p.rect.right
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = -8
                if yvel < -8: self.rect.top = p.rect.bottom

class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((22, 22))
        self.image.convert()
        self.image.fill(Color("#DDDDDD"))

        self.rect = Rect(x, y, 22, 22)

    def update(self):
        pass

class ExitBlock(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image.fill(Color("#00FFFF"))

if(__name__ == "__main__"):
    main()

I finally fixed the camera so now it will scroll as I'm moving. I'm still working on the randomly generated platform algorythm, but for now I'll just keep working at it

import pygame
from pygame import *

WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)

DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30

def main():
    global cameraX, cameraY
    pygame.init()
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
    pygame.display.set_caption("Use arrows to move!")
    timer = pygame.time.Clock()

    up = down = left = right = running = False
    bg = Surface((32,32))
    bg.convert()
    bg.fill(Color("#FFFFFF"))
    entities = pygame.sprite.Group()
    player = Player(32, 32)
    platforms = []

    x = y = 0
    level = [
    "                E         ",
    "              PPPPP       ",
    "                          ",
    "                          ",
    "       PPPPPP             ",
    "                          ",
    "                  PPPPP   ",
    "                          ",
    "          PPPPPP          ",
    "                          ",
    "PPPPP                     ",
    "                          ",
    "        PPPPPP            ",
    "                          ",
    "  PPPPP                   ",
    "                   PPPPP  ",
    "                          ",
    "        PPPPPP            ",
    "                          ",
    "  PPPPP                   ",
    "                   PPPPP  ",
    "                          ",
    "                          ",
    "              PPPPP       ",
    "                          ",
    "                          ",
    "       PPPPPP             ",
    "                          ",
    "                  PPPPP   ",
    "                          ",
    "          PPPPPP          ",
    "                          ",
    "PPPPP                     ",
    "                          ",
    "        PPPPPP            ",
    "                          ",
    "  PPPPP                   ",
    "                   PPPPP  ",
    "                          ",
    "                          ",
    "              PPPPP       ",
    "                          ",
    "                          ",
    "       PPPPPP             ",
    "                          ",
    "                  PPPPP   ",
    "                          ",
    "          PPPPPP          ",
    "                          ",
    "PPPPPP                    ",
    "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",]
    # build the level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = ExitBlock(x, y)
                platforms.append(e)
                entities.add(e)
            x += 32
        y += 32
        x = 0

    total_level_width  = len(level[0])*32
    total_level_height = len(level)*32
    camera = Camera(complex_camera, total_level_width, total_level_height)
    entities.add(player)

    while 1:
        timer.tick(60)

        for e in pygame.event.get():
            if e.type == QUIT: raise SystemExit, "QUIT"
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                raise SystemExit, "ESCAPE"
            if e.type == KEYDOWN and e.key == K_UP:
                up = True
            if e.type == KEYDOWN and e.key == K_DOWN:
                down = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right = True
            if e.type == KEYDOWN and e.key == K_SPACE:
                running = True

            if e.type == KEYUP and e.key == K_UP:
                up = False
            if e.type == KEYUP and e.key == K_DOWN:
                down = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False
            if e.type == KEYUP and e.key == K_LEFT:
                left = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False

        # draw background
        for y in range(32):
            for x in range(32):
                screen.blit(bg, (x * 32, y * 32))

        camera.update(player)

        # update player, draw everything else
        player.update(up, down, left, right, running, platforms)
        for e in entities:
            screen.blit(e.image, camera.apply(e))

        pygame.display.update()

class Camera(object):
    def __init__(self, camera_func, width, height):
        self.camera_func = camera_func
        self.state = Rect(0, 0, width, height)

    def apply(self, target):
        return target.rect.move(self.state.topleft)

    def update(self, target):
        self.state = self.camera_func(self.state, target.rect)

def simple_camera(camera, target_rect):
    l, t, _, _ = target_rect
    _, _, w, h = camera
    return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)

def complex_camera(camera, target_rect):
    l, t, _, _ = target_rect
    _, _, w, h = camera
    l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h

    l = min(0, l)                           # stop scrolling at the left edge
    l = max(-(camera.width-WIN_WIDTH), l)   # stop scrolling at the right edge
    t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom
    t = min(0, t)                           # stop scrolling at the top
    return Rect(l, t, w, h)

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Player(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.xvel = 800
        self.yvel = 640
        self.onGround = False
        self.image = Surface((32,32))
        self.image.fill(Color("#00FFFF"))
        self.image.convert()
        self.rect = Rect(x, y, 32, 32)

    def update(self, up, down, left, right, running, platforms):
        if up:
            # only jump if on the ground
            if self.onGround: self.yvel -= 10
        if down:
            pass
        if running:
            self.xvel = 12
        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:
            # only accelerate with gravity if in the air
            self.yvel += 0.3
            # max falling speed
            if self.yvel > 100: self.yvel = 100
        if not(left or right):
            self.xvel = 0
        # increment in x direction
        self.rect.left += self.xvel
        # do x-axis collisions
        self.collide(self.xvel, 0, platforms)
        # increment in y direction
        self.rect.top += self.yvel
        # assuming we're in the air
        self.onGround = False;
        # do y-axis collisions
        self.collide(0, self.yvel, platforms)

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if isinstance(p, ExitBlock):
                    pygame.event.post(pygame.event.Event(QUIT))
                if xvel > 0:
                    self.rect.right = p.rect.left
                    print "collide right"
                if xvel < 0:
                    self.rect.left = p.rect.right
                    print "collide left"
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = -8
                if yvel < -8:
                    self.rect.top = p.rect.bottom


class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((32, 12))
        self.image.convert()
        self.image.fill(Color("#000000"))
        self.rect = Rect(x, y, 32, 12)

    def update(self):
        pass

class ExitBlock(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image.fill(Color("#00FFFF"))

if __name__ == "__main__":
    main()
share
If you are having a specific problem in an algorithm you tried to write about random level generation, I'm sure plenty of people will be more than happy to help you. But most of the people on Stackoverflow I think are not of the mindset to write entire algorithms for you – Dan F May 2 at 18:47

migrated from stackoverflow.com May 2 at 19:23

closed as not a real question by Laurent Couvidou, msell, bummzack, Anko, Josh Petrie May 11 at 15:21

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, see the FAQ.

2 Answers

I actually made a game like this in cocos2d. I chose something similar to a GDC talk about the making of Jetpack Joyride. Which is:

  1. Randomly generate about 1000 pixels of platforms at a time. Let's call this a section.
  2. When the players starts to get close to the top of this section, go generate another section.

This allows you to maybe kind of add some flavor to your sections based on how far the player is to the game. Later in the game you would want it to be more complex, so the algorithm for generating the sections can make more complex configuration of platforms. There's a lot you can do with this that I won't go into, but it's the approach I took and it works great.

share

For actually randomly generating a platform, you define the:

x = max horizontal distance away from last platform
y = max vertical distance away from last platform

Use these values along with a random number generator to figure out the new distance. And like I stated in the previous post, you want to change this as the game proceeds. For instance the max vertical distance could be larger for a more challenging part of the game.

share

Not the answer you're looking for? Browse other questions tagged or ask your own question.