Skip to content

216. Building a game – demo

July 14, 2015

I’ll now build a small game using the ideas from the previous post.

It is extremely simple, so the game code doesn’t get in the way of seeing how the design works.

  1. A spaceship flies around inside a circle, and
  2. you touch the screen to make it go toward your finger.
  3. Keep the spaceship inside the circle as long as possible.

Key functions

Here are the important functions – setup, draw and touched. You can see how simple the code is to read.

--these are all the "states", each has a table of functions
Splash,MainMenu,Help,Settings={},{},{},{}
Play,GameOver,HighScores={},{},{}

function setup()
   ship=readImage("Space Art:Red Ship Bank Left")
   ChangeState(Splash) --set state to splash initially
end

function draw()
   state.draw() 
end

function touched(t)
    --not all states need a touched function 
    --so we'll check if there is one
    if state.touched then state.touched(t) end
end

Splash state

The splash state draws the spaceship coming towards us for 5 seconds, then switches to the main menu. Here is the code.

function Splash.draw()
    background(255)
    sprite(ship,WIDTH/2,HEIGHT/2,ElapsedTime*50)
    if ElapsedTime>5 then ChangeState(MainMenu) end
end

The ChangeState function not only changes the state variable, but it also runs a setup function if there is one. I added this, because if, for example, you replay the game, you need to reset the ship position, scores, etc, each time.

function ChangeState(s)
    state=s --change state
    if s.setup then s.setup() end --run setup if there is one
end

Main menu

Now here are all the main menu functions

--list of main menu options, and the new state to set
--when they are touched
MainMenu.options={{"Help",Help}, {"Settings",Settings},
      {"Play",Play}, {"High Scores",HighScores}} 

function MainMenu.setup()
    SetupMenu(MainMenu.options)
end

function MainMenu.draw()
    DrawMenu()
end

function MainMenu.touched(t)
    local s=MenuTouch(t)
    if s then ChangeState(s) end
end

Note that the setup function runs another function SetupMenu. This is because we also have a Settings menu which works the same way as this one, and I don’t want to write the same code twice. So SetupMenu is used for both sets of menus, making the code above very compact. There is also a DrawMenu function which is used by all menu states.

Note also that the touched function calls MenuTouch, which tests if we touched one of the menu items. If we did, it returns the second item from the MainMenu.options table above, eg if we touched “High Scores”, it will return HighScores, which is the table for the high scores state.  The touched function will then change states.

I’m not going to explain these “helper” functions, SetupMenu, DrawMenu and MenuTouch, in this post, because they are fairly straightforward. You can see them in the full code, linked at the end.

Help state

The code for the Help menu item is simple enough

function Help.draw()
    background(184, 206, 215, 255) 
    text("HELP TEXT GOES HERE",WIDTH/2,HEIGHT/2)
end

function Help.touched()
    ChangeState(MainMenu) --returns to main menu
end

Settings

The settings menu is another menu, of course.

--(say) we want to run one of these functions 
--when something is touched
function SettingDifficulty()
    print("Set difficulty") --your code in here    
end
function SettingJumpLevel()
    print("Jumping levels") --your code in here
end
function SettingMain() --back to main menu
    ChangeState(MainMenu) 
end

--list of settings options, and the functions to run, when touched
Settings.options={{"Difficulty",SettingDifficulty}, 
    {"Jump to level",SettingJumpLevel},
    {"Return to Main Menu",SettingMain}} 

function Settings.setup()
    SetupMenu(Settings.options)
end

function Settings.draw()
    DrawMenu()
end

function Settings.touched(t)
    --if something is touched, run the function returned
    f=MenuTouch(t) 
    if f then f() end
end

You can see that this uses the same menu functions as MainMenu, to set up, draw, and test for touches on menu items.

The touched function is a little different because the menu items aren’t other states, ie we don’t want to go away from the Settings state if we touch one of them. Instead, we want to write a function for each item and run it if that item is touched. The Settings.options table tells us what function to run for each item.

 Play

The Play state does need a setup function, as you can see.

function Play.setup()
    pos=vec2(WIDTH/2,HEIGHT/2) --initial position
    vel=vel or vec2(1,0) --direction
    speed=1 --speed
    startTime=ElapsedTime
end

function Play.draw()
    background(0)
    Play.DrawShip()
end

function Play.DrawShip()
    pos=pos+vel
    speed=math.min(10,speed+0.01)
    fill(236, 236, 233, 50)
    ellipse(WIDTH/2,HEIGHT/2,600)
    pushMatrix()
    translate(pos.x,pos.y) --see note below
    rotate(math.deg(math.atan2(vel.y,vel.x))-90) --see note
    sprite(ship,0,0)
    popMatrix()
    --end of game when you move >300 pixels from centre of screen
    if pos:dist(vec2(WIDTH/2,HEIGHT/2))>300 then state=GameOver end
end

function Play.touched(t)
    vel=vec2(t.x-pos.x,t.y-pos.y):normalize()*speed
end

The ship rotates, to point to the last touch. We have to subtract 90 degrees, because although the ship starts off moving to the right – which is an angle of 0 degrees in Codea – the image is drawn facing up the screen, so we need to rotate it an additional 90 degrees to the right, ie -90 degrees.

Note that the touched function subtracts the current position from the touched point to get direction, and uses the normalize function to give it a length of 1, so we can then multiply by speed.

Game Over and High Scores

I won’t show them here because they are very simple (in fact, I haven’t programmed high scores, because it depends on how you want to store user names and scores). You can see them in the full code below.

Summary

I hope you agree that this approach makes it far easier to build, debug, and add more features to your program, because it is laid out so clearly, and broken into small parts that can be modified on their own, rather than as part of a huge tangle of code.

Full code

The code is here.

 

Advertisement

From → Games, Graphics

One Comment

Trackbacks & Pingbacks

  1. Index of posts | coolcodea

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: