B4J Tutorial [BANanoCreateJS] Beginning HTML5 games with CreateJS

Discussion in 'B4J Tutorials' started by Mashiane, Jun 20, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Ola

    BANanoCreateJS

    This is one of my bucket list things I've been wanting to look at, game development. So I have been looking for a simple js library to use.

    As the lib BANanoCreateJS is not finished (we have a long way to go, really) and this is just a first attempt at this, I have never ever developed a game before so this is a learning curve that we can experience as we go along and perhaps help each other solve some issues with this. I'm sure there are people who know how to do this with eyes closed. ;)

    So I spent a couple of hours yesterday reading and practicing and was just able to get my dancing butterflies working. On the code one will notice that just above the BANano version of the code, there is a commented javascript version so that we get the drift. Some of the things there I cant even explain myself so you will have to experience it for yourself.

    When it comes to games, there is a lot apparently that one has to look at, for example
    • FPS - frames per second.
    • Collision Detection
    • Events
    • The stages
    • Resources - music, images etc
    To mention a few things, here is what the butterflies are doing...



    The CreateJS lib is available here. Its defined as...

    A suite of modular libraries and tools which work together or independently to enable rich interactive content on open web technologies via HTML5.

    Hopefully this can be a community project. The intention is to explore the canvas in parallel exploring the CreateJS library whilst working on this pet project. Oh yes, there are game engines that I found via google that one does not even have to code, but hey, let the adventure begin!

    Ta!

    NB: You might want to clear the cache of your internet browser if you make any changes to the code.
     
    Last edited: Aug 4, 2019
    aeric, fredo, Johan Hormaza and 2 others like this.
  2. Mashiane

    Mashiane Expert Licensed User

    Let's simplify things a little. Let's create a stage (where our game will run), add three butterflies at different co-ordinates, after 1 second we move the position of the second butterfly.

    GamesLesson1.gif

    First we need to define all our variables / resources to use in the game in process_globals...

    Code:
    'Static code module
    Sub Process_Globals
        
    Private game As BANanoCreateJS
        
    Private BANano As BANano  'ignore
        Private bf1 As BANanoObject
        
    Private bf2 As BANanoObject
        
    Private bf3 As BANanoObject
    End Sub
    We then call init to create our canvas and the stage so that we can start adding our game resources as soon as the game is started and ready.

    Code:
    Sub Init
        game.Initialize(Me, 
    "body""canvas"1000800"", CreateMap("border""black solid 1px"))
        
    'add resources to the manifest for the game
        game.AddManifest("butterfly""./assets/butterfly.png")
        
    'start the game at 60 frames per second
        game.Start(60)
    End Sub
    We have a butterfly picture that we will use on the stage, so lets add it to the 'manifest' so that its ready whenever we need it. We then start the game at 60 frames per second. This will fire the game_ready event.

    On game_ready (the stage is set), lets add the characters, i.e. butterflies.

    Code:
    Sub game_ready
        
    'the game is ready, lets create the objects to play with
        Log("game_ready")
        
    'get resource from manifest
        Dim img As BANanoObject = game.getManifest("butterfly")
        
    'add 3 images to the canvas
        bf1 = game.NewBmp(img)
        bf2 = game.NewBmp(img)
        bf3 = game.NewBmp(img)
        
    'set the locations
        game.SetX(bf2, 200)
        game.SetX(bf3, 
    400)
        
    'add the images to the stage
        game.AddChildren(Array(bf1,bf2,bf3))
        
    'update the game to ensure our objects are showing
        game.Update
        
    'after 1 second, move the butterfly
        BANano.Window.SetTimeout(BANano.CallBack(Me, "movebutterfly"Null), 1000)
    End Sub
    We get the butterfly image from the 'manifest' / 'memory' and use that to create 3 butterflies for the stage using createjs methods. We also set the X positions of the butterflies, being 200, and 400 for the 2nd and 3rd butterfly.

    We then use the AddChild method to add each of the elements to the stage and then 'refresh' the stage by calling game.update.

    This will just create images on the canvas without any type of action. So we want the second butterfly to move after 1 second, so we fire the SetTimeOut method to call the 'movebutterfly' method.

    Code:
    Sub moveButterFly
        
    'get the last position of butterfly Y pos
        Dim bf2Y As Long = game.GetY(bf2)
        
    'increment it by 200
        bf2Y = bf2Y + 200
        
    'set the new position
        game.SetY(bf2,bf2Y)
        
    'update the game
        game.update
    End Sub
    The movebutterfly method reads the last position of butterfly 2 and moves it down the stage. Each time we have a change to the object we need to update the stage after setting all properties.

    Lol. For a while there I started to think about the Romeo and Juliet play I watched. This is starting to make sense when I look at it from an acting perspective. There is a stage, there are actors, they follow a script, move, cry, collide etc. ;)

    We will add more functionality to this as we go along. Enjoy!
     

    Attached Files:

  3. Mashiane

    Mashiane Expert Licensed User

    Introducing Tweening

    In out last example we made a demo using SetTimeOut and just moved the butterfly to a Y position without any animation. With tweening we can do better.

    This lesson demonstrates the following process

    1. Draw your butterfly image.
    2. Create a timer that would execute until a desired increment is reached.
    3. At each interval, clear your butterfly graphics.
    4. Redraw your butterfly with a new, slightly incremented y value.
    5. Check if the number of ticks Or desired butterfly y position is reached.
    6. Clear your timer.

    So here we want the Y position of the image to be 100, when the image is added, its position is 0 in this case. We will use Tweening to do the steps 1 - 6.

    GamesLesson2.gif

    This is achieved with..

    Code:
    Sub game_ready
        
    'get the image from loaded resources
        Dim img As BANanoObject = game.getManifest("butterfly")
        
    'create a new bitmap
        bf1 = game.NewBmp(img)
        
    'add it to the stage
        game.AddChild(bf1)
        
    'update the stage
        game.update
        
        
    'get the object you want to animate, remove it, change position, redraw in new position
        'animation should run for 1 second
        game.Tween_Get(bf1,False)
        
    'change the properties you need
        Dim toPos As Map = CreateMap()
        
    'y should be current position + 100
        Dim y As Long = game.IncrementY(bf1,100)
        toPos.Put(
    "y", y)
        
    'animation should be exactly 1 second
        game.Tween_To2(toPos, 1000)
    End Sub

    Sub game_update
        
    'Log("game_update on each tick")
        Dim y As Long = game.GetY(bf1)
        
    Log(y)
        
    'refresh the game each time the tick fires
        game.update
    End Sub
    So within 1 second, the butterfly Y position should be moved to 100 paces. So

    1. We get the image to animate
    2. We change the properties of the image
    3. We move the image to the new position within 1 second.
    4. Each time the ticker fires, it calls game_update, so there we can process the stage update to reflect the new changes.

    NB: As this is a lib in development, some things are being added as we go along and some things will change. Each lesson code comes with new changes and anything changed will be reflected.

    NB: Please first clear the browser cache to run this example.
     

    Attached Files:

    joulongleu and Johan Hormaza like this.
  4. Mashiane

    Mashiane Expert Licensed User

    Lesson 3 - 9

    Our lesson 2 introduced us to tweening, a process of having to be able with just a few calls one is able to redraw their images. Lessons 3 - 9 takes one through tweening (using wait) and also a tweening callback that can be ran when the tweening is complete.

    Lesson 3: Demonstrating another tweening property. We change the alpha property of the image to make it fade into the stage..

    GamesLesson03.gif

    Lesson 4: Demonstrating Tweening Wait i.e. before an image animates, wait for some millisecords for it to fire. Notice the delay with the animation start up.

    GamesLesson04.gif

    Lesson 5: Dancing Butterflies - a more detailed easier example explaining the concept

    GamesLesson05.gif

    Lesson 6: Now that we have seen how animation and tweening works, lets look at how to add shapes to the stage with some shapes. We have been adding pngs before. We end up animating one at the center of it.

    GamesLesson06.gif

    Lesson 7: Let's create a bouncing ball. It happens to be yellow!

    GamesLesson07.gif

    Lesson 8: Let's create a UI widget, a progress bar, this can be used when your game is loading and preparing to load.

    GamesLesson8.gif

    Lesson 9: Now that we know how to create shapes and load images to our stage, lets add some events. We have added a mouseover and mouseout events to our circle.

    GamesLesson9.gif

    Soon we will be looking at sprites and other things and eventually developing a game.

    Watch this space. #Excited4Days
     

    Attached Files:

    joulongleu likes this.
  5. Mashiane

    Mashiane Expert Licensed User

    Our first HTML5 game, ColorDrop

    Color Drop is a simple color-matching game where the player must drop each game piece in the correct slot by matching their colors.
    • Four square slots are displayed on the top of the screen.
    • Four blocks are randomly placed on the bottom of the screen, each with a color that matches a slot at the top of the screen.
    • The player must drag each block into its corresponding slot, which is accomplished by matching their colors.
    • If a player drops it in the wrong slot, the block will animate back to where it was grabbed.
    • If a player drops it in the correct slot, it should animate to snap in place of the slot.
    • Once the player fills all four slots, alert the user that they have won the game.


    ColorDrop.gif
     

    Attached Files:

    ellpopeb4a and joulongleu like this.
  6. Mashiane

    Mashiane Expert Licensed User

    Lesson 11: Events & No Ticking

    In lesson 11, we take a look at the creating a circle on the stage, add an event so that when the circle is clicked it moves to the mouse position. We also add a mouse_up event to the stage so that when the mouse is clicked within the stage, the circle moves directly there.

    For this lesson we are not tweening and we are not using FPS to run a tick. Simply by updating the stage the changes made are updated when we click.

    CircleClick.gif

    The code is rather simple

    On int, we prepare the game so that its ready for us to add the display objects.

    Code:
    Sub Init
        
    'create the canvas and the stage for the game to be created
        game.Initialize(Me, "body""canvas"1000800"", CreateMap("border""black solid 1px"))
        
    'prepare the stage
        game.Prepare
    End Sub
    this generates a game_ready event where we add our circle..

    Code:
    Sub game_ready
        
    Dim e As BANanoEvent
        game.OnMouseUp(BANano.CallBack(Me,
    "game_mouseup",Array(e)))
        
    'create a circle within a parent game
        circle.Initialize2(game)
        
    'fill color red
        circle.graphics.beginFill("red")
        
    'x = 0, y = 0, radius = 50
        circle.graphics.drawCircle(0050)
        
    'set the x & y
        circle.setx(100)
        
    circle.sety(100)
        
    circle.Add
        game.Update
       
        
    'add click event to circle
        circle.OnClick(BANano.CallBack(Me, "circle_click"Array(e)))
    End Sub
    We add a mouseup event to the game to detect when a user clicks the game area
    We add a circle using Initialize2 this time (this automatically links the object to the game) and specify the shape properties
    After we have added the circle to the game with .Add we update the game stage and then add a click event to the circle.

    When the circle is clicked, we read its X (axis) position, increment that by 10px and then update the circle position and also update the stage.

    Code:
    'fire when clicked
    Sub circle_click(e As BANanoEvent)
        
    Log("circle_click")
        
    'get the shape from the event
        Dim clickedShape As CreateJSShape = game.GetEventShape(e)
        
    'get the x position
        Dim x As Int = clickedShape.GetX
        x = x + 
    10
        clickedShape.SetX(X)
        game.update
    End Sub
    Now, when the stage is clicked anywhere, we want to move the circle to that xy point.

    Code:
    Sub game_mouseup(e As BANanoEvent)
        
    'get the stage point, this returns x & y
        Dim pt As CreateJSPoint = game.GetStagePoint(e)
        
    'set the circle points
        circle.SetX(pt.x)
        
    circle.SetY(pt.y)
        game.update
    End Sub
    We use .GetStagePoint to get the X/Y position at where the mouse pointer rested. You will note this is derived from the BANanoEvent object. We get the point and then set the circle position for x and y and then update the stage.

    Ta!

    PS: Some improvements were made to ColorDrop for ease of use. This is part of this code. This included assigning a BANanoObject back to CreateJSShape.
     

    Attached Files:

    joulongleu likes this.
  7. Mashiane

    Mashiane Expert Licensed User

    Lesson 12: We look at drag and drop where one can drag and drop an image. This uses another event handler for the shape.

    Lesson12DnD.gif

    Lesson 13: We add the tweening to the shape class this time around. This makes it a better implementation than directly to the game class.

    Lesson13DropOut.gif

    Lesson 14: We explore transforming images using the .SetTransform method

    Lesson14SetTransform.gif

    See code in the next lesson...
     
  8. Mashiane

    Mashiane Expert Licensed User

    Lesson 15: SpriteSheets

    This is just an introduction to the spritesheets and their functionality. So we get to get grant running. We have created CreateJSSprite, CreateJSSpriteSheet and CreateJSAnimation classes for this.

    The SpriteSheet

    sprite.png

    From this sprite-sheet we create an animation for running and jumping.

    Lesson15SpriteSheet.gif

    We define the SpriteSheet and the grant Sprite.

    Code:
    Private ss As CreateJSSpriteSheet
        
    Private grant As CreateJSSprite
    On game_ready, we create the spritesheet to make the game work.

    Code:
    Sub game_ready
        ss.Initialize(
    "ss").AddImage("./assets/grant.png")
        
    'height of each sprite, width, registrations, count
        ss.SetRegX(82)
        ss.SetHeight(
    292)
        ss.SetCount(
    64)   ' the number of image frames in the sprite
        ss.SetRegY(0)
        ss.SetWidth(
    165)   ' the width of each image
        ss.SetFrameRate(30)  ' the frame rate
        'animation, starting sprite, ending sprite, next animation, speed
        ss.AddSimpleAnimation("run"025"run"1.5)   ' specify the animation, the start and ending image and the speed
        ss.AddSimpleAnimation("jump"2663"run", -1)
        
    'build the sprite to make it available to the game
        ss.BuildSpriteSheet
        
    '
        'create the sprite and add it to the stage
        grant.Initialize(ss, "grant""run")
        grant.setx(game.getcanvaswidth / 
    2)
        grant.sety(
    22)
        game.AddSprite(grant)
        
    '
        game.Start(30)
    End Sub
     

    Attached Files:

    Johan Hormaza and joulongleu like this.
  9. Mashiane

    Mashiane Expert Licensed User

    Detecting keyboard events

    In this lesson we detect keyup, keyleft, keyright, keydown movements.

    When you initialize a game, there are two events that are created, keyup and keydown. To trap these on your module, you add..

    KeyPress.gif


    Code:
    Sub game_keydown(e as bananoevent)
    End Sub
    and

    Code:
    Sub game_keyup(e as bananoevent)
    End Sub
    One then is able to detect the keys and then perform some actions.

    in pgLesson21, we do this with...

    Code:
    Sub game_keydown(e As BANanoEvent)
        
    Select Case e.KeyCode
        
    Case game.ARROW_KEY_LEFT
            
    Log("move left")
        
    Case game.ARROW_KEY_UP
            
    Log("move up")
        
    Case game.ARROW_KEY_RIGHT
            
    Log("move right")
        
    Case game.ARROW_KEY_DOWN
            
    Log("move down")          
        
    End Select
    End Sub
    Ensure the focus is on the canvas first.

    TA!

    PS: Post on #1 updated with source code...
     
    Last edited: Aug 4, 2019
  10. Mashiane

    Mashiane Expert Licensed User

    Taking again from the previous example, we create a paddle for a game. We move the paddle from left to right.

    Paddle.gif

    We prepare the stage and when the game is ready we create the paddle.

    Code:
    Sub game_ready
        
    'build the game elements
        padel.Initialize
        padel.SetWidth(
    100)
        padel.graphics.BeginFill(
    "#0000FF")
        padel.Graphics.drawRect(
    00, padel.GetWidth, 20)
        padel.SetX(
    0)
        padel.SetNextX(
    0)
        padel.SetY(game.GetCanvasHeight - 
    20)
        game.addChild(padel.Shape)
        
    'start the game, this raises, game_update
        game.Start(60)
    End Sub
    During the game execution, we trap the keypress events for left and right buttons.

    Code:
    'move padel
    Sub game_keydown(e As BANanoEvent)
        
    Select Case e.KeyCode
            
    Case game.ARROW_KEY_LEFT
                leftKeyDown = 
    True
            
    Case game.ARROW_KEY_RIGHT
                rightKeyDown = 
    True
        
    End Select
    End Sub

    'stop padel
    Sub game_keyup(e As BANanoEvent)
        
    Select Case e.KeyCode
            
    Case game.ARROW_KEY_LEFT
                leftKeyDown = 
    False
            
    Case game.ARROW_KEY_RIGHT
                rightKeyDown = 
    False
        
    End Select
    End Sub
    The game has been started at 60 frames per second, so each time a tick fires, the game_update method is executed.

    Code:
    'each time a tick runs
    Sub game_update
        
    'get the current position of the shape
        Dim nextX As Int = padel.GetX
        
    'the left key has been pressed
        If leftKeyDown Then
            nextX = padel.GetX - 
    10
            
    'ensure we dont over-run the stage
            If nextX < 0 Then
                nextX = 
    0
            
    End If
        
    else if rightKeyDown Then
            
    'if right is pressed, we get the current position
            'increment it by 10 and set it as the next position
            nextX = padel.GetX + 10
            
    'get the canvas width and ensure that the nextpos is within stage
            If (nextX > game.GetCanvasWidth - padel.GetWidth) Then
                nextX = game.GetCanvasWidth - padel.GetWidth
            
    End If
        
    End If
        
    'set the next position
        padel.SetNextX(nextX)
        
    'move the paddle to the next position
        padel.SetX(padel.GetNextX)
        
    'execute the stage update
        game.update
    End Sub
     
  11. Mashiane

    Mashiane Expert Licensed User

    Let's create a game over screen using a text component.

    gameover.jpg

    Code:
    Sub game_ready
        
    Dim txt As CreateJSText
        txt.Initialize(
    "Game Over""20px Arial""#ff7700")
        txt.SetTextBaseline(
    "middle")
        txt.SetTextAlign(
    "center")
        txt.SetX(game.GetCanvasWidth/
    2)
        txt.SetY(game.GetCanvasHeight/
    2)
        game.addChild(txt.Text)
        game.Update
    End Sub
     
  12. Mashiane

    Mashiane Expert Licensed User

    We created a Game Over screen in our previous post, let's use the DOMElement object of CreateJS now and create a tweening 'instructions' screen.

    Instructions.gif

    We add a gameholder to the body of the page. This time we render the canvas of the game to another div and use a DOMElement to use the instructions on the game. This then means we can render any html element to our game as we need.

    Code:
    Sub game_ready
        
    Dim el As CreateJSDOMElement
        el.Initialize(
    "instructions")
        el.SetAlpha(
    0)
        el.SetRegX(
    200)
        el.SetX(game.GetCanvasWidth / 
    2)
        game.addChild(el.DOMElement)
        
    '
        game.Tween_Get(el.DOMElement,False)
        game.Tween_Wait(
    1000)
        game.tween_to3(CreateMap(
    "y"40"alpha"1), 2000, game.Ease_QuadOut)
        game.Start(
    60)
    End Sub
    The instructions are just basic HTML with some styles applied to it.

    Ta!
     
    joulongleu and Johan Hormaza like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice