6
\$\begingroup\$

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()
\$\endgroup\$
  • \$\begingroup\$ your indentations are a bit to big \$\endgroup\$ – D.C Feb 17 '16 at 13:03
  • \$\begingroup\$ they are only four characters which is common...? \$\endgroup\$ – nephi12 Oct 24 '16 at 23:29
5
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ im confused about number 4. what do you mean? and number 6. other than that, thanks! \$\endgroup\$ – nephi12 Jan 8 '14 at 18:52
  • 1
    \$\begingroup\$ Number 6, see "unnamed numerical constants": en.m.wikipedia.org/wiki/Magic_number_(programming). initial_platforms=15 would be clearer \$\endgroup\$ – jonrsharpe Jan 8 '14 at 19:05
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ – jonrsharpe Jan 8 '14 at 19:09
  • \$\begingroup\$ sorry to respond years later, but i wanted to thank you, your simple suggestions completely changed my coding style, and helped me write much better code. thanks! \$\endgroup\$ – nephi12 Oct 24 '16 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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