19 July 2015

Making a Python game - Start and end screens - Part 4

Last time in this series, we got the game to the point , where it seems like it is finally playable.But as the game's programmer some things are obvious to to you and me that wouldn't be that obvious  to someone else , they might even have no idea what to do !
so we shall add a start screen , with instructions on how to play.
we also saw that the game quits too quickly after the player hits the obstacle , we don't even get to final score !,
so, we shall add an end screen to display this final score as well as the current game speed.

Let's begin by adding some constants and variables to store our game's instructions and states

The constant "STARTSCREEN_TEXT"  stores the entire instructions you want to display on the startscreen  , divided in multiple pages and lines, ready to be displayed on the screen.

The variable "startstate" stores the page number on the start screen.

Next, we will add the startscreen and endscreen functions to the game.

startscreen displays the first page of the "STARTSCREEN_TEXT" and waits for a key press , if "space" is pressed then it moves to the next page , else if "esc" is pressed it skips the start screen and directly enters the game

endscreen simply shows the score and the game speed and waits for the player to press "esc" , on doing so it will quit the game.

now that our functions have been defined , we will integrate them in our game.
we need to show the start screen , before our game loop and the endscreen after our game loop, so we call these functions in these respective positions.



now , try running the game , you will see something like this ,

The startscreen.
The game play , is exactly like the last version

The Score and speed displayed after crashing into an opponent

you will see that the game looks really good at this point , however , we still need to add an option to replay the game,instead of just quitting the game after the player loses. that will require some restructuring of the code. but we'll leave that for some other time
The code for this post can be found at the Git repo in the file "Cgame_part3.py"



14 July 2015

Making a Python game - Obstacles - Part 3

In the previous posts in this series , we have seen the following parts to making our game.
  1. Setting up our system
  2. Basic input and output
so far our game displays as such :





Now let's add the obstacles , so we need to keep in mind the following :
  • We need to move the screen so that the generated objects move towards the player.
  • We need our obstacles to generate randomly , but not block the player's route completely .
  • We need to give player points for dodging every obstacle, for the score.
  • We need to progressively increase the rate of the obstacle generation , and movement speed ,making the game harder to play as time goes on.
lets look at the additions to the code , now that we know our objectives ,

first of all , we need to import new modules, "time and random".

import mlcd,pygame,time,random

the "time" modules provides us timing functions so that the logic runs at a set "speed" and "random" module allows us to make random decisions.

next , we will add some more constants and variables.

OBSTACLE_CHAR="|"
game={"speed":4.05,"level":2.5,"obstacle":0}
lasttime=time.time()
curtime=0.0

"OBSTACLE_CHAR" stores our obstacles, again like the "PLAYER_CHAR" it can be changed ,just keep it a single character. "game" dictionary stores the movement speed, current level and obstacle count for the game."lasttime" and "curtime" , store the time to check if the game logic is running at a certain speed (not faster than human capability)






now we begin by adding the speed check for our game logic,inside the game loop,
we get the current time and see
if 1/speed time has passed,if yes then update 

variable for lasttime and then run the code for logic.






The above section of the code , checks if the player and the obstacle are at the same column, and if true , updates the values for score,level and speed being on the same line means from next cycle the obstacle cant cause any problems for the player , hence we also remove it from the count of current obstacles.





we now move every character (except for player) one position to the left,but you  will realize that once we do that, the leftmost characters are lost and the rightmost positions have no new values(the old ones are garbage for us). so now we need to add  new characters to the rightmost position , which will either be blank space(" ") or our "OBSTACLE_CHAR" in a random fashion, provided it doesn't block the path  completely.The code for doing this is here.
Now,all we are left to add is the obstacle collision,
#check for collision
if screenbuff[player["line"]][player["position"]]==OBSTACLE_CHAR:
done=True #player lost
after the "done=True" you may also add a "print" statement to display the final score in your console , however we will add a start screen , instructions and an endscreen which will display the code and instructions on how to play the game on the LCD itself, in a future post. Here are some screenshots of the game ,as it is now,
Code for this post is available on the git repo as the new file "Cgame_part2.py"

11 July 2015

Making a Python game -Basic I/O-Part 2

In the previous post , we setup our system and prepared our working directory , in this post we will begin with coding a few key components of the game , and see how they work.
  • Open the "Cgame_part1.py"  by right clicking and selecting "edit with IDLE" , or you may use notepad if you prefer , i just like using IDLE because u can run the programs directly.

  • You can download the code from my Git Repo directly , so focus on understanding what each bit does in this post.

Coding the basic components

  1. Begin by importing the modules needed for this part of the game.

    import mlcd,pygame

    This allows us to use the functions contained in these modules, so we can use them in our game
  2. Next we create a few constants and variables to store the state of our game, we will discuss them as they come up.
    PLAYER_CHAR=">"

    This constant basically defines how our player is going to look on the screen, changing this will change the shape of our ship , you are free to play with this value, but remember to keep it a single character.
    screenbuff=[[" "," "," "," "," "," "," "," "," "," "," "," "], [" "," "," "," "," "," "," "," "," "," "," "," "]]

    This variable stores the state of that part of the screen where our obstacles and ship will be,think of it like a  virtual map of the playable area on the screen.
    player={"position":0,"line":0,"score":000}     
    keys={"space":False,"quit":False}
    These are two "dictionary" type variables to store the states of the pressed keys and the player's position and score.
  3. Now that we are done with creating the variables we need to use , we will create a function that will allow us to get the pressed keys using pygame.
    def keypress(): (refer to the code from git repo)

  4. The function first resets the keystates so that we don't get duplicate keypresses,
    then it checks the pygame key events and sets our keystate to true if the key is pressed and crosschecks it with a key up or key down event to ensure we don't send the keys if the key has been pressed and never released(which would cause the game to move things too fast).
  5. Now we can move on to the main part , the game loop,
         done=False
         #initialize mlcd as 16x2 character lcd
         mlcd.init(16,2)
         while not done:
             #add player to the buffer
             screenbuff[player["line"]][player["position"]]=PLAYER_CHAR
             #ready the lines for drawing on lcd
             lines=[''.join(screenbuff[0]) + "|scr",
                       ''.join(screenbuff[1]) + "|"+str(player["score"])]
             mlcd.draw(lines)
             #remove player from buffer
             screenbuff[player["line"]][player["position"]]=" "
             #get keypresses
             keypress()
             #modify player line (move the player) if space is pressed
             if keys["space"]:
                 if player["line"]==0:
                     player["line"]=1
                 else:
                     player["line"]=0
             #quit
             if keys["quit"]:
                 print("game quit")
                 done=True

Break down of the game loop

Before the loop begins,we set the control variable "done" to False , and initialize the mlcd display,

  1. first , we add the player to the screenbuff, so that the entire gameplay data is ready to be put on the screen ,we do this with the line

                 screenbuff[player["line"]][player["position"]]=PLAYER_CHAR
  2. with the next two lines , we create a list, containing the gameplay data , and the score , and display the entire data on to the screen.
                 lines=[''.join(screenbuff[0]) + "|scr",
                           ''.join(screenbuff[1]) + "|"+str(player["score"])]
                 mlcd.draw(lines)
  3. on the next line , we remove the player character from the gameplay data in the screenbuff, so that we don't end up putting the player character in it's last position.
                 #remove player from buffer

                 screenbuff[player["line"]][player["position"]]=" "
  4. Next , we get the keypresses and if space is pressed ,the player character switches lanes and if esc is pressed , we quit the loop by setting the loop condition "done" to true.this works because our looping condition is "while not done".
                 #get keypresses

                 keypress()
                 #modify player line (move the player) if space is pressed
                 if keys["space"]:
                     if player["line"]==0:
                         player["line"]=1
                     else:
                         player["line"]=0
                 #quit
                 if keys["quit"]:
                     print("game quit")
                     done=True
That ends the game loop , outside the loop block , we simply add one line to exit pygame after we are done executing everything.

        pygame.quit()


Running this program displays a tiny 16x2 character lcd box like so,


and pressing the space key will switch the line of the player " > " and pressing the esc will quit the game. be sure to click the box , if your input doesn't respond , the window needs to be in focus for pygame to catch the key input.

so there you go, you have the basic Input and output of the game ready. now all we need to add are the obstacles and their movement across the screen,then we add a difficulty system and a few instructions on how to play, and our first game ,will be ready !
EDIT: added in part 3

if you are enjoying this series or have any questions , hit me up in the comments below , and i'll be glad to help