Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Build Flappy Bird 3000 using the Ring programming language

0.00/5 (No votes)
12 Oct 2016 2  
Getting started with 2D games development and build the Flappy Bird 3000 game using the Ring programming language.

Introduction

In this article we will learn about using the Ring programming language for 2D games development, Also we will create the Flappy Bird Game. Our version of the game will let you win once you get the score of 3000, so I will call it Flappy Bird 3000 game.

The Ring language is simple, trying to be natural, encourage organization and comes with transparent and visual implementation. It comes with compact syntax and a group of features that enable the programmer to create natural interfaces and declarative domain-specific languages in a fraction of time. It is very small, fast and comes with smart garbage collector that puts the memory under the programmer control. It supports many programming paradigms, comes with useful and practical libraries. The language is designed for productivity and developing high quality solutions that can scale.

You can download Ring from this link

Background

Check the next articles about Ring

(1) The Ring Programming Language

(2) Syntax Flexibility in the Ring Language

Also check the next Tutorials

(1) Getting Started

(2) Control Structures

(3) Functions

(4) Lists

(5) Classes

(6) Functional Programming

(7) Declarative Programming 

About the Ring Language

The next comments enable you to understand Ring code quickly if you are new to Ring

* Dynamic Language 

* Not Case Sensitive

* Load libraries using the 'Load' Command

* Support using the 'Main' Function

* Create new objects using the 'New' keyword

* Access object attributes and methods using the braces { } 

* Write comments after # 

* Comes with Garbage Collector 

 

Using Ring Game Engine

To start using the game engine, use the "gameengine.ring" library

Then create an object from the Game class 

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

        oGame = New Game        # Create the Game Object
        {
                        # Game Code
        }                       

In the next examples we will learn about using many features provided by "gameengine.ring"

The next table present the Game class attributes.

Attributes Description
FPS Number determines how many times the draw() method will be called per second.
FixedFPS Number determines how many times the animate() method will be called per second.
Title String determines the window title of the game.
aObjects List contains all objects in the game
shutdown True/False value to end the game loop

The next table present the class methods.

Method Description
refresh() Delete objects.
settitle(cTitle) Set the window title using a string parameter.
shutdown() Close the application.

The next table present a group of keywords defined by the class.

Keyword Description
sprite Create new Sprite object and add it to the game objects.
text Create new Text object and add it to the game objects.
animate Create new Animate object and add it to the game objects.
sound Create new Sound object and add it to the game objects.
map Create new Map object and add it ot the game objects.

Creating the Game Window

The next example create the Game object using (New Game), The object name is oGame.

Using braces { } we access the oGame object attributes and methods.

We will set the 'title' attribute value to "My First Game"

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
        }                       # Start the Events Loop

Drawing Text

To draw text, We need to use the Text Class

Class Name : Text

Parent Class : Sprite Class

The next table present the class attributes.

Attributes  Description
size                                   Number determine the font size
font                                  String determine the font file name
text                                     String determine the text to be displayed
color                                  Number determine the color

The next table present the class methods.

Method Description
Draw(oGame)                                             Draw the object

 

The next example load the game engine using the 'Load' command

The execution starts from the main function

Inside the main function we create new object from the Game Class

The created object name is oGame, We access this object using braces to modify the object attributes and methods.

Inside the object (oGame) we created new object from the Text class uning text { }

The 'test' keyword is defined by the Game class to create new object and return this object that we can access using braces { }

We will set the text attribute to "game development using ring is very fun!"

And using the file attribute we will determine the font file name : "fonts/pirulen.ttf"

The font size is 20

Using the color attribute we will set the text color to black using rgb(0,0,0)

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)
                }
        }               # Start the Events Loop

The next screen shot presents the application in the runtime.

Moving Text

The next example using the Text class to display a text and move it around the screen

To move the text we set the 'animate' attribute to True

We have the 'direction' attribute, by setting it to GE_DIRECTION_INCVERTICAL we will move the text from the top to the down direction.

The 'point' attribute determine when the movement will stop. we have y=150 and it will be increased until y = the point attribute value (i.e. 400).

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)      # Color = black
                }
                text {
                        x = 10  y=150
                        # Animation Part =====================================
                        animate = true                  # Use Animation
                        direction = GE_DIRECTION_INCVERTICAL    # Increase y
                        point = 400                     # Continue until y=400
                        nStep = 3                       # Each time y+= 3
                        #=====================================================
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "welcome to the real world!"
                        color = rgb(0,0,255)            # Color = Blue
                }
        }                                       # Start the Events Loop

Playing Sound

Class Name : Sound

Parent Class : GameObject Class

The next table present the class attributes.

Attributes Description
file String determine the sound file name.
once True/False determine to play the file one time or not (loop).

The next table present the class methods.

Method Description
playsound()                                     Play the sound file

 

The next example uses sound { } to create a sound object to play sound files

The example will determine the sound file name using the 'file' attribute

We will set the 'file' attribute value to "sound/music1.wav"

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)      # Color = black
                }
                text {
                        x = 10  y=150
                        # Animation Part ======================================
                        animate = true                          # Use Animation
                        direction = GE_DIRECTION_INCVERTICAL    # Increase y
                        point = 400             # Continue until y=400
                        nStep = 3               # Each time y+= 3
                        #======================================================
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "welcome to the real world!"
                        color = rgb(0,0,255)    # Color = Blue
                }
                Sound {                                 # Play Sound
                        file = "sound/music1.wav"       # Sound File Name
                }
        }                                       # Start the Events Loop

 Animation

Class Name : Animate

Parent Class : Sprite Class

The next table present the class attributes.

Attributes Description
frames                                   Number determine the number of frames
frame                                   Number determine the active frame
framewidth                                   Number determine the frame width.
animate                                   True/False determine using animate or not.
scaled                                   True/False determine scaling image or not.

The next table present the class methods.

Method Description
Draw(oGame)                                               Draw the object

 

The next example uses animate { } to create an object from the animate class.

This class will play a sequence of images 

We have one image file "images/fire.png" that we will determine using the 'file' attribute.

Using the framewidth attribute we will determine the widht of each frame (framewidth = 40)

We have 13 frames that we will display.

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"

        animate {
          file = "images/fire.png"
          x = 100
          y = 200
          framewidth = 40
          height = 42
          nStep = 3      # Used for delay
          transparent = true
          state = func oGame,oSelf {  # Called by engine each frame
                oSelf {
                  nStep--
                  if nStep = 0
                        nStep = 3
                        if frame < 13      # we have 13 frames in animation
                          frame++   # move to next frame
                        else
                          oGame.remove(oself.nIndex)   # remove object
                        ok
                  ok
                }
          }
         }


  }          # Start the Events Loop

Animation and Functions

We can call a function to create new objects

By calling this function using a for loop we can create many objects 

In the next example we have the showfire() function that create objects of the type (animate).

Load "gameengine.ring"  # Give Control to the Game Engine

func main               # Called by the Game Engine

  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"
        for x = 70 to 700 step 50
          for y = 70 to 500 step 50
                showfire(oGame,x,y)
          next
        next

  }          # Start the Events Loop

func showfire oGame,nX,nY
  oGame {
        animate {
          file = "images/fire.png"
          x = nX
          y = nY
          framewidth = 40
          height = 42
          nStep = 3      # Used for delay
          transparent = true
          state = func oGame,oSelf {  # Called by engine each frame
                oSelf {
                  nStep--
                  if nStep = 0
                        nStep = 3
                        if frame < 13      # we have 13 frames in animation
                          frame++   # move to next frame
                        else
                          frame=1
                        ok
                  ok
                }
          }
         }
  }

The next screen shot presents the application in the runtime.

Sprite - Automatic Movement using Keyboard

In the next example we will use sprite { } to create new object of the Sprite class.

By setting the 'Move' attribute to 'True' we can move the sprite using the keyboard arrows 

Load "gameengine.ring"                          # Give control to the game engine

func main                                       # Called by the Game Engine

        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=true       # we can move it using keyboard arrows
                        Scaled=true
                }
        }                                       # Start the Events Loop

Sprite - Keypress event

The next example create a Sprite object, but displate the default movement by setting the 'Move' attribute to False.

Using the Keypress attribute we can define anonymous function to be called when a key is pressed

The anonymous function will take parameters like the Game Object (oGame), the Sprite object (oSelf) and the pressed key code (nKey)

We can check the pressed key value using Switch statement then we can update the x and y values according to the pressed key.

Load "gameengine.ring"                          # Give control to the game engine

func main                                       # Called by the Game Engine

        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                }
        }                                       # Start the Events Loop

Sprite - Mouse event

The next example create a sprite object using sprite { } then using the Mouse attribute we determine an anonymous function that will be called to handle the mouse events.

The anonymous function will take 4 parameters : oGame,oSelf,nType,aMouseList

oGame  = Game Object

oSelf = Sprite Object

nType = Event Type

aMouseList = Mouse Information (x,y)

Load "gameengine.ring"                          # Give control to the game engine

func main                                       # Called by the Game Engine

        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                        mouse = func oGame,oSelf,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        oSelf {
                                                x = aMouseList[GE_MOUSE_X]
                                                y = aMouseList[GE_MOUSE_Y]
                                        }
                                ok
                        }
                }
        }                                       # Start the Events Loop

Sprite - State event

The next example present how to use the state attribute in the Sprite class to define anonymous function that will be called each frame update.

The next example uses the State and anoymous function to prevent moving the object/sprite outside the screen.

Load "gameengine.ring"                          # Give control to the game engine

func main                                       # Called by the Game Engine

        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                        mouse = func oGame,oSelf,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        oSelf {
                                                x = aMouseList[GE_MOUSE_X]
                                                y = aMouseList[GE_MOUSE_Y]
                                        }
                                ok
                        }
                        state = func oGame,oSelf {
                                oself {
                                        if x < 0 x = 0 ok
                                        if y < 0 y = 0 ok
                                        if x > ogame.width-width
                                                x= ogame.width - width ok
                                        if y > ogame.height-height
                                                y=ogame.height - height ok
                                }
                        }
                }
        }                                       # Start the Events Loop

 

Animate - Events

As sprites, the Animate Class suppor using the KeyPress, Mouse and State events

The next example present this.

We will create the bird, animate it, and move it up after pressing space.

Also the bird will be moved down automatically after some frames from pressing space button.

Load "gameengine.ring"                          # Give control to the game engine

func main                                       # Called by the Game Engine

        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"

                animate {

                        file = "images/fbbird.png"
                        x = 10
                        y = 10
                        framewidth = 20
                        scaled = true
                        height = 50
                        width = 50
                        nStep = 3
                        transparent = true

                        state = func oGame,oSelf {
                                oSelf {

                                        # Animation
                                                nStep--
                                                if nStep = 0
                                                        nStep = 3
                                                        if frame < 3
                                                                frame++
                                                        else
                                                                frame=1
                                                        ok
                                                ok

                                        # Move Down
                                                y += 3
                                                if y > 550 y=550 ok

                                }

                        }

                        keypress = func ogame,oself,nKey {
                                oself {
                                        if nkey = key_space
                                                y -= 55
                                                if y<=0 y=0 ok
                                        ok
                                }
                        }

                        mouse = func ogame,oself,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        cFunc = oself.keypress
                                        call cFunc(oGame,oSelf,Key_Space)
                                ok
                        }
                }
        }                                       # Start the Events Loop

The next screen shot presents the application in the runtime.

Map

Class Name : Map

Parent Class : Sprite Class

The next table present the class attributes.

Attributes Description
aMap                                    List determine the map content using numbers.
aImages                                    List determine the image used for each number in the map.
BlockWidth                                    Number determine the block width (default = 32).
BlockHeight                                    Number determine the block height (default = 32).
Animate                                     True/False determine the animation status.

The next table present the class methods.

Method Description
getvalue(x,y)       Return the item value in the Map according to the visible part

 

Using the Map class we can display and move maps

The map uses a list to determine the map content using Numbers

Each number represent an image that will be used for drawing.

The next example create a map and move it to the left

Load "gameengine.ring"        # Give control to the game engine

func main          # Called by the Game Engine

oGame = New Game      # Create the Game Object
{
  title = "My First Game"

  Map {

        blockwidth = 80
        blockheight = 80

        aMap = [
                [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
        ]

        aImages = ["images/fbwall.png",
                 "images/fbwallup.png",
                 "images/fbwalldown.png"]

        state = func oGame,oSelf {
          oSelf {
                x -= 3
                if x < - 2100  x = 0  ok
          }
        }

  }
}          # Start the Events Loop

The next screen shot presents the application in the runtime.

Map Events

We can define events for the Map to take actions and respond to the environment

The next example uses the mouse attribute to define an anonymous function to be called when the user click on a location in the map.

If the user clicked on a location with an image, the image will disapper

If the user clicked on a location without an image, an image will be added to the map.

Load "gameengine.ring"        # Give control to the game engine

func main          # Called by the Game Engine

  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"

        Map {

          blockwidth = 80
          blockheight = 80

          aMap = [
                   [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
          ]

          aImages = ["images/fbwall.png",
                         "images/fbwallup.png",
                         "images/fbwalldown.png"]

          state = func oGame,oSelf {
                oSelf {
                  x -= 3
                  if x < - 2100  x = 0  ok
                }
          }

          mouse = func ogame,oself,nType,aMouseList {
                if nType = GE_MOUSE_UP
                  oSelf {
                        mX = aMouseList[GE_MOUSE_X]
                        mY = aMouseList[GE_MOUSE_Y]
                        nValue = GetValue(mX,mY)
                        nRow = GetRow(mX,mY)
                        nCol = GetCol(mX,mY)
                        Switch nValue
                        On 1  aMap[nRow][nCol] = 0
                        On 2  aMap[nRow][nCol] = 0
                        On 3  aMap[nRow][nCol] = 0
                        On 0  aMap[nRow][nCol] = 1
                        Off
                  }
                ok
          }

        }
  }          # Start the Events Loop

The next screen shot presents the application in the runtime.

Flappy Bird 3000 Game

After understanding the previous examples, We can see and understand the game

The Flappy Bird 3000 Game source code

We have also in the game, the GameState class to store custom information for our game.

The next code for starting the game and displaying the game information

Also supporting (Play Again) Feature

oGameState = NULL

Load "gameengine.ring"

func main

  oGame = New Game


  while true

        oGameState = New GameState

        oGame {
          title = "Flappy Bird 3000"
          sprite
          {
                file = "images/fbback.png"
                x = 0 y=0 width=800 height = 600 scaled = true animate = false
                keypress = func ogame,oself,nKey {
                  if nkey = key_esc or nKey = GE_AC_BACK
                        ogame.shutdown()
                  but nKey = key_space
                        oGameState.startplay=true
                        ogame.shutdown=true
                  ok
                }
                mouse = func ogame,oself,nType,aMouseList {
                  if nType = GE_MOUSE_UP
                        cFunc = oself.keypress
                        call cFunc(oGame,oSelf,Key_Space)
                  ok
                }
          }
          text {
                animate = false
                size = 35
                file = "fonts/pirulen.ttf"
                text = "Flappy Bird 3000"
                x = 150  y=50
          }
          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "Version 1.0"
                x = 280  y=100
          }
          text {
                animate = false
                size = 16
                file = "fonts/pirulen.ttf"
                text = "(C) 2016, Mahmoud Fayed"
                x = 245  y=140
          }

          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "To Win Get Score = 3000"
                x = 150  y=270
          }

          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "Press Space to start"
                x = 190  y=470
          }
          text {
                animate = false
                size = 20
                file = "fonts/pirulen.ttf"
                text = "Press Esc to Exit"
                x = 260  y=510
          }

          animate {
                file = "images/fbbird.png"
                x = 200
                y = 200
                framewidth = 20
                scaled = true
                height = 50
                width = 50
                nStep = 3
                transparent = true
                animate = true
                direction = ge_direction_random
                state = func oGame,oSelf {
                  oSelf {
                        nStep--
                        if nStep = 0
                          nStep = 3
                          if frame < 3
                                frame++
                          else
                                frame=1
                          ok
                        ok
                        if x <= 0 x=0 ok
                        if y <= 0 y=0 ok
                        if x >= 750 x= 750 ok
                        if y > 550 y=550 ok
                  }
                }
          }

          Sound {
                file = "sound/music2.wav"
          }
        }
        if oGameState.startplay
          oGame.refresh()
          playstart(oGame)
          oGame.refresh()
        ok

  end

The next function playstart() contains the actual code for playing the game

 

func playstart oGame

    oGame {
        FPS = 60
        FixedFPS = 120
        Title = "Flappy Bird 3000"
        Sprite {
            file = "images/fbback.png"
            x = 0 y=0 width=800 height = 600 scaled = true animate = false
            keypress = func ogame,oself,nKey {
                if nkey = key_esc or nKey = GE_AC_BACK
                    ogame.shutdown()
                ok
            }
        }

        Map {
            blockwidth = 80
            blockheight = 80
            aMap = [
                     [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
                ]
            newmap(aMap)
            aImages = ["images/fbwall.png","images/fbwallup.png",
                    "images/fbwalldown.png"]
            state = func oGame,oSelf {
                if oGameState.gameresult = false
                    px = oGame.aObjects[3].x
                    py = oGame.aObjects[3].y
                    oSelf {
                        x -=  3
                        if x < - 2100
                            x = 0
                            newmap(aMap)
                        ok
                        nCol =  getcol(px,0)
                        if nCol=11 or nCol=15 or nCol=19 or nCol=23 or nCol=27
                            if nCol != oGameState.lastcol
                                oGameState.lastcol = nCol
                                oGameState.Score += 100
                                oGame { Sound {
                                    once = true
                                    file = "sound/sfx_point.wav"
                                } }
                                checkwin(oGame)
                            ok
                        ok
                    }
                    if  oSelf.getvalue(px+40,py) != 0 or
                        oSelf.getvalue(px+40,py+40) != 0 or
                        oSelf.getvalue(px,py) != 0 or
                        oSelf.getvalue(px,py+40) != 0
                        oGameState.gameresult = true
                        oGame {
                            text {
                                point = 550
                                size = 30
                                nStep = 3
                                file = "fonts/pirulen.ttf"
                                text = "Game Over !!!"
                                x = 500    y=10
                                state = func ogame,oself {
                                    if oself.y >= 550
                                            ogame.shutdown = true
                                    ok
                                        if oself.y = 90
                                        ogame {
                                            Sound {
                                                once = true
                                                file = "sound/sfx_die.wav"
                                            }
                                        }
                                    ok
                                }
                            }
                            Sound {
                                once = true
                                file = "sound/sfx_hit.wav"
                            }
                        }
                    ok
                ok
            }
        }

        animate {
            file = "images/fbbird.png"
            x = 10
            y = 10
            framewidth = 20
            scaled = true
            height = 50
            width = 50
            nStep = 3
            transparent = true
            state = func oGame,oSelf {
                oSelf {
                    nStep--
                    if nStep = 0
                        nStep = 3
                        if frame < 3
                            frame++
                        else
                            frame=1
                        ok
                    ok
                }

                if not oGameState.playerwin
                    oGameState.down --
                    if oGameState.down = 0
                        oGameState.down = 3
                        oself {
                            y += 25
                            if y > 550 y=550 ok
                        }
                    ok
                ok

            }
            keypress = func ogame,oself,nKey {
                if oGameState.gameresult = false
                    oself {
                        if nkey = key_space
                            y -= 55
                            oGameState.down = 60
                            if y<=0 y=0 ok
                        ok
                    }
                ok
            }
            mouse = func ogame,oself,nType,aMouseList {
                if nType = GE_MOUSE_UP
                    cFunc = oself.keypress
                    call cFunc(oGame,oSelf,Key_Space)
                ok
            }
        }

        text {
            animate = false
            point = 400
            size = 30
            file = "fonts/pirulen.ttf"
            text = "Score : " + oGameState.score
            x = 500    y=10
            state = func oGame,oSelf {
                oSelf { text = "Score : " + oGameState.score }
            }
        }

    }

The next function newmap() is used to create new map (random maps)

 

func newmap aMap
    aV = [
    [1,1,3,0,0,2,1,1],
    [1,3,0,0,0,2,1,1],
    [1,1,1,3,0,2,1,1],
    [1,1,1,3,0,0,0,0],
    [0,0,0,0,2,1,1,1],
    [0,0,2,1,1,1,1,1],
    [0,0,0,2,1,1,1,1],
    [1,1,1,3,0,2,1,1],
    [1,1,1,1,1,3,0,0],
    [3,0,0,2,1,1,1,1],
    [3,0,0,2,3,0,0,2]
    ]
    for x = 10 to 24 step 4
        aVar = aV[ (random(10)+1) ]
        for y = 1 to 8
            aMap[y][x] = aVar[y]
        next
    next

The next function checkwin() is used to check if the player win or not

We do this by checking the score

if the scope = 300 the player wins.

func checkwin ogame
    if oGameState.score = 3000
        oGameState.gameresult = true
        oGameState.playerwin = true
        oGame {
            text {
                point = 400
                size = 30
                nStep = 3
                file = "fonts/pirulen.ttf"
                text = "You Win !!!"
                x = 500    y=10
                state = func ogame,oself {
                    if oself.y >= 400
                        ogame.shutdown = true
                        oGameState.value = 0
                    ok
                }
            }
        }
    ok

The next class for storing the game state and important information like the score.

Class GameState
    down = 3
    gameresult = false
    Score = 0
    startplay=false
    lastcol = 0
    playerwin = false

 

The next screen shot presents the game during the runtime.

Points of Interest

Ring is a new language, Also the game engine is new, Many things can be added to make Ring and the Engine a better work, Also you can help and contribute

Once you understand how to use the Game Engine, You can create many games in short time. Game Engines are used for producivity. The Ring Game Engine can be used for prototyping games.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here