Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This is a game I made in Python. While it is not my first, I am not happy with the result. I would like suggestions on ways I can make it better, more user-friendly, and more enjoyable. Also, if you have suggestions on how to get the same effect, but with cleaner, more organized code, please make them.

Please feel free to make any suggestions you feel will help me, except to use a GUI.

(P.S. I am fourteen and self-taught, so my coding style and abilities may be hugely less than yours. Please forgive my ignorance.)

#!/usr/bin/python
import curses
import random
import time
import math

class game:
    ''' game by ben miller '''

    def __init__(self):
        self.instuctmsg = ['use a and d to move left and right','use w to jump if you are on the bottom',
        'dont fall once you get high up','bounce on platforms to get higher',
        'go through platforms from the bottom to jump higher','','hit any key to play the game']

        self.ratio = {'plat':30,'player':6,'update':15}
        self.platlen = 5
        self.numlevels = 5

    def __call__(self):
        self.quit = False
        self.screen.nodelay(1)
        curses.noecho()
        self.screen.clear()
        self.gameover = False
        self.scorea = [self.dims[0]-1]
        self.score = 0
        self.upc = 0
        self.oupc = 0
        self.x = self.dims[1]/2
        self.y = self.dims[0]-1
        self.platforms = [[1,self.dims[1]/2+5]]
        self.draw()
        self.screen.refresh()
        self.screen.getch()
        self.oq = -1
        self.q = -1

        i = 0
        for i in range(15):
            self.makeplat()
            self.update()
            self.update()
            self.update()
        while 1:
                if i % self.ratio['plat'] == 0:
                    self.makeplat()

                if i % self.ratio['player'] == 0:
                    if self.oupc != int(bool(self.upc)):
                        self.oupc = (int(bool(self.upc))+1)%2
                    if self.upc > 0:
                        if i % 15 == 0:
                            if self.y != self.dims[0]-1:
                                self.y += 1

                        if self.y == 0: 
                            self.screen.clear()
                            self.screen.addstr(self.dims[0]/2-1,self.dims[1]/2-9,'you win that level')
                            self.screen.addstr(self.dims[0]/2,self.dims[1]/2-11,'press space to continue')
                            self.screen.nodelay(0)
                            p = -1
                            while p != ord(' '):
                                p = self.screen.getch()

                            break

                        if self.screen.inch(self.y-1,self.x) == ord('#'):
                            self.upc += 2

                        self.move(self.y-1,self.x)
                        self.upc-=1

                    elif self.y != self.dims[0]-1:
                        if self.screen.inch(self.y+1,self.x) == ord('#'):
                            self.upc = 8
                        else:
                            self.move(self.y+1,self.x)

                if i % self.ratio['update'] == 0:
                    self.update()

                self.score = self.dims[0]-1-min(self.scorea)
                if self.score > 15 and self.y > self.dims[0]-5:
                    self.screen.clear()
                    self.screen.addstr(self.dims[0]/2-1,self.dims[1]/2-4,'game over')
                    self.screen.addstr(self.dims[0]/2,self.dims[1]/2-8,'your score is: '+str(self.score))
                    self.screen.addstr(self.dims[0]/2+1,self.dims[1]/2-11,'press space to continue')
                    self.screen.nodelay(0)
                    p = -1
                    while p != ord(' '):
                        p = self.screen.getch()

                    self.gameover = True
                    break

                self.screen.clear()
                self.draw()
                self.screen.refresh()
                self.q = self.screen.getch()
                if self.q != self.oq:
                    self.oq = self.q
                    self.key()
                if self.q == ord('q'):
                    self.gameover = True
                    self.quit = True
                    break
                i+=1
                time.sleep(0.02)


    def move(self,y,x):
        ''' this moves the player '''

        if x >= 0 and x <= self.dims[1]-1:
            self.screen.addch(self.y,self.x,' ')
            self.y = y
            self.x = x
            self.scorea.append(self.y)

    def makeplat(self):
        ''' this makes a random platform '''

        y = 1
        time.sleep(0.0005)
        x = random.randrange(1,self.dims[1]-7)
        self.platforms.append([y,x])

    def draw(self):
        ''' this displays the game '''

        for platform in self.platforms:
            for i in range(self.platlen):
                self.screen.addch(platform[0],platform[1]+i,'#')
                self.screen.move(self.dims[0]-1,self.dims[1]-1)
        self.screen.addch(self.y,self.x,'@')
        self.screen.move(self.dims[0]-1,self.dims[1]-1)

    def update(self):
        ''' moves platforms down a line '''

        for platform in self.platforms:
            platform[0]+=1
            if platform[0] == self.dims[0]:
                del self.platforms[self.platforms.index(platform)]

    def key(self):

        #left
        if self.q == ord('a'):
            if self.x == 0:
                self.move(self.y,self.dims[1]-1)
            else:
                self.move(self.y,self.x-1)

        #right
        elif self.q == ord('d'):
            if self.x == self.dims[1]-1:
                self.move(self.y,0)
            else:
                self.move(self.y,self.x+1)

        #jump
        elif self.q == ord('w') and self.y == self.dims[0]-1:
            self.upc = 7

        #drop
        elif self.q == ord('s') and self.y not in [self.dims[0]-1,self.dims[0]-2]:
            if ord('#') not in [self.screen.inch(self.y+1,self.x),self.screen.inch(self.y+2,self.x)]:
                self.upc = 0
                self.move(self.y+2,self.x)
            #else:
                #i dont like this for now
                #self.remove()


    def remove(self):
        '''this removes any platforms the player drops onto'''
        for platform in self.platforms:
            if platform[0] in [self.y+1,self.y+2]:
                for j in range(self.platlen):
                    if self.x == platform[1]+j:
                        del self.platforms[self.platforms.index(platform)]

    def instructions(self):
        self.screen.nodelay(0)
        self.screen.clear()
        for i in range(len(self.instuctmsg)):
            self.screen.addstr(self.dims[0]/2-int(round(len(self.instuctmsg)))/2+i,self.dims[1]/2-len(self.instuctmsg[i])/2-1,self.instuctmsg[i])
        self.screen.move(self.dims[0]-1,self.dims[1]-1)
        self.screen.refresh()
        self.screen.getch()


    def start(self):
        self.screen = curses.initscr()
        self.dims = self.screen.getmaxyx()
        self.dims = [self.dims[0],self.dims[1]]
        if self.dims[1] > 80:
            self.dims[1] = 80

        self.instructions()
        for z in range(0,self.numlevels-1,10/(self.numlevels-1)):
            self.ratio = {'plat':30+z,'player':6,'update':15-z}
            self()
            if self.gameover: break
        if not self.gameover:
            self.screen.clear()
            self.screen.addstr(self.dims[0]/2-1,self.dims[1]/2-3,'YOU WIN')
            self.screen.addstr(self.dims[0]/2,self.dims[1]/2-11,'press space to continue')
            p = -1
            while p != ord(' '):
                p = self.screen.getch()
        elif self.quit:
            self.screen.clear()
        else:
            self.screen.clear()
            self.screen.addstr(self.dims[0]/2-1,self.dims[1]/2-4,'YOU LOSE')
            self.screen.addstr(self.dims[0]/2,self.dims[1]/2-11,'press space to continue')
            p = -1
            while p != ord(' '):
                p = self.screen.getch()
        curses.endwin()


jump = game()
jump = jump.start
if __name__ == '__main__': jump()
share|improve this question
add comment

1 Answer

up vote 4 down vote accepted

A few suggestions:

  1. Follow PEP8's code conventions (e.g. spaces after commas, line lengths);
  2. Put your start() instance method immediately after __init__(); it took me a while to work out where self.dims had come from! Or, even better, combine the two methods;
  3. Take your opportunities to make functions. For example, you repeatedly use self.screen.addstr to put some lines of centred text on the screen, you could make a function centred_text(list_of_lines) to save some duplication;
  4. If you call something (e.g. self.update) repeatedly, consider refactoring it - self.update(3) or for _ in range(3): self.update() would be neater;
  5. Keep going with the OOP - try refactoring to create a Platform class and a Player class (the latter paves the way to two-player mode!);
  6. Try to factor out magic numbers, like the initial 15 platforms; and
  7. Use clearer variable names than oq and upc.

Hope that's useful!

share|improve this answer
    
im confused about number 4. what do you mean? and number 6. other than that, thanks! –  nephi12 Jan 8 at 18:52
    
Number 6, see "unnamed numerical constants": en.m.wikipedia.org/wiki/Magic_number_(programming). initial_platforms=15 would be clearer –  jonrsharpe Jan 8 at 19:05
    
Number 4, self.update(); self.update(); self.update() is a bit awkward, try for _ in range(3): self.update() or give self.update an argument for the number of times to run –  jonrsharpe Jan 8 at 19:09
    
okay, thanks! you have been very helpful. –  nephi12 Jan 8 at 21:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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