Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
16. November 2015

 

Announced over at the Cocos2D-x blog today, they just released version 3.9 of the popular cross platform open source 2D based C++ framework.  The release is primarily for maintenance and stability but some new functionality was added as detailed on the forum:

 

unnamed-1024x332

  1. 3D Module:
    • Added 3D MotionStreak to support streak effect.
    • Refined Sprite3D to support material system.
  2. 2D Module:
    • Added frame callback function and animation callback function.
    • Added script component system.
    • Reconstruction of 2D physics with Component.
    • Improved EditBox implementation on iOS and Win32 platform.
    • Removed dependence of libcurl on AssetsManager, AssetsManagerEx and Downloader (iOS & Android).
    • Improved particle performance.
  3. Others:
    • Supported Action inheritance, update function overwriting in JSB.
    • Improved ScrollView performance in Web engine.
    • Improved Scale9Sprite performance in Web engine.
    • Decoupled Sprite's setTexture() and updateColor() in Web engine.
    • Added support for debugging and release on real devices with Xcode7 and iOS9.

The new release can be downloaded here. (Direct link)

 

If you are interested in learning more about Cocos2d-x, we have a full tutorial series available here.

GameDev News


5. November 2015

 

In this tutorial we are going to look at playing back music in our SFML game.  We will look at streaming an ogg file from disk.  We will also quickly look at the basics of handling time in SFML as we add fast forward and rewind abilities to our music playback.

 

There is an HD version of this tutorial here.

 

Playing music files is different from playing audio files and we will deal with this in a separate tutorial.  Music files are designed to be streamed from disk, not resident in memory.  SFML supports the following file formats:

  • ogg
  • wav
  • flac
  • aiff
  • au
  • raw
  • paf
  • svx
  • nist
  • voc
  • ircam
  • w64
  • mat4
  • mat5
  • pvf
  • htk
  • sds
  • avr
  • sd2
  • caf
  • wve
  • mpc2k
  • rf64

 

You will notice a very noticeable exception from that list, the mp3 format. That is because the mp3 format is encumbered by a number of patents and should be avoided to protect yourself from potential licensing fees.  Fortunately the ogg format offers similar file sizes and similar audio quality as the mp3 format without the licensing pitfalls.  If you require to covert formats the free software Audacity is an excellent and easy choice.

 

The major difference between sound effect and music is the sound effect stays resident in memory, while a Music file is streamed from disk.  Both classes still possess a great deal of common behaviour.  In fact if you look at the inheritance tree you will see that they have a common base class.

 

image

 

Now lets finally create some code showing how to actually play and control music files.

 

// Demonstrate that the hills are alive with the sound of music
#include "SFML/Graphics.hpp"
#include "SFML/Audio.hpp"
#include <iostream>

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Music music;
  music.openFromFile("audio/goats_typicalamerican.ogg");
  music.setVolume(50);

  music.play();

  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();


      if (event.type == sf::Event::EventType::KeyPressed){

        // Up and down to control volume
        if (event.key.code == sf::Keyboard::Key::Down)
          music.setVolume(music.getVolume() - 10);
        if (event.key.code == sf::Keyboard::Key::Up)
          music.setVolume(music.getVolume() + 10);
        

        // Left and right to control tracking position
        if (event.key.code == sf::Keyboard::Key::Right){
          auto newPos = music.getPlayingOffset() + sf::seconds(5);
          music.setPlayingOffset(sf::Time(newPos));
        }
          
        if (event.key.code == sf::Keyboard::Key::Left){
          auto newPos = music.getPlayingOffset() - sf::seconds(5);
          if (newPos.asSeconds() <= 0.0f) newPos = sf::seconds(0);
          music.setPlayingOffset(sf::Time(newPos));
        }

        std::cout << "Current volume is :" << music.getVolume() << " position is: " 
          << music.getPlayingOffset().asSeconds() << std::endl;
      }
    }

    renderWindow.clear();
    renderWindow.display();
  }
}

 

You’ll notice that loading a music file is pretty much identical to loading any other asset in SFML.  Keep in mind the Music class actually owns the underlying data of the music that is played so it is not a light weight class so be careful when they are created.  However since the Music file is played from disk instead of from memory, it is safe to allocated multiple concurrent Music files, such as one per song played, without being hugely wasteful.

 

The code itself is fairly self explanitory.  You can set the volume directly on a music file that is being played, you can control music playback using vcr style play/pause/stop() controls.  You can also control the position of the sound using a combination of getPlayingOffset() and setPlayingOffset().  As you can see there are also time operators built into SFML such as sf::seconds() or sf::milliseconds() making time based math extremely simple.

 

There is a great deal more you can do with audio files, but we will cover that in the sound effects tutorial.

 

The Video

 

Programming


26. October 2015

 

In the previous tutorial we look at the process of using sprites in SFML.  Today we are going to look instead at using a sprite sheet or texture atlas.  The process is very similar to working with a normal sprite, except that you have multiple sprites on a single texture.  Loading and swapping textures in memory is an expensive operation, so holding multiple sprites together can greatly improve the speed of your game.

 

As always there is an HD video version of this tutorial available here.

 

Many game engines have implicit support for spritesheets and sprite animation, however SFML does not.  There are however libraries built on top of SFML that provide this functionality or you can roll the required functionality yourself with relative ease.  Before we can continue we need a sprite sheet, which is simply one or more images with multiple frames of animation.  This is the one I am using:

dragonFrames

 

This isn’t the full sized image however.  The source file is actually 900x1200 pixels in size.  It should be noted that this size isn’t actually ideal.  Power of two texture dimensions should be preferred ( such as 512x256, 1024x1024, 2048x2048, etc. ).  In earlier version of OpenGL including OpenGL ES 1.x, a power of two texture was actually required.  These days, it is no longer a requirement, but a PoT texture generally will perform better.  As to file dimensions, you can fairly safely go up to 2048x2048 and support even rudimentary GPU’s like the Intel HD3000 series, but sizes of 4096x4096 are generally possible on most modern desktop and mobile GPUs.   You can notice from this image that it contains 12 textures, each 300x400 pixels in size.

 

Now we need code to extract a single frame from the texture and as you will see, it’s actually remarkably easy:

// Demonstrate creating a spritesheet
#include "SFML/Graphics.hpp"

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Texture texture;
  texture.loadFromFile("images/dragonFrames.png");

  sf::Sprite sprite(texture,sf::IntRect(0,0,300,400));


  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }

    renderWindow.clear();
    renderWindow.draw(sprite);
    renderWindow.display();
  }
}

 

This will draw just a small rectangular portion of our source texture, representing the first frame, like so:

image

 

Really that’s all that there is to it.  To add animation, we simply change the rectangular source after the fact, like so:

// Demonstrate creating a spritesheet
#include "SFML/Graphics.hpp"

int main(int argc, char ** argv){
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Demo Game");

  sf::Event event;
  sf::Texture texture;
  texture.loadFromFile("images/dragonFrames.png");

  sf::IntRect rectSourceSprite(300, 0, 300, 400);
  sf::Sprite sprite(texture,rectSourceSprite);
  sf::Clock clock;

  while (renderWindow.isOpen()){
    while (renderWindow.pollEvent(event)){
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }

    if (clock.getElapsedTime().asSeconds() > 1.0f){
      if (rectSourceSprite.left == 600)
        rectSourceSprite.left = 0;
      else
        rectSourceSprite.left += 300;

      sprite.setTextureRect(rectSourceSprite);
      clock.restart();
    }

    
    renderWindow.clear();
    renderWindow.draw(sprite);
    renderWindow.display();
  }
}

 

And when run:

GIF

 

You may notice right away that animation doesn’t look right and that’s a keen eye you’ve got there.  In this example we are simply going across the top three frames of animation from left to right.  The proper animation should actually be 0,1,2,1,0 not 0,1,2,0,1,2.  That said, in a proper game you would either roll your own animation class or use an existing one.  When we get to the process of creating a complete game, we will cover this process in detail.

 

In the above example we change frames of animation by changing the sprites source texture rect with a call to setTextureRect().  As I mentioned in the previous tutorial you could actually generate a new sprite per frame if preferred, as the sf::Sprite class is very light weight.

 

The Video

Programming


25. October 2015

 

In this Closer Look At we are going to be taking a closer look at the Otter2D game engine.  The Closer Look At series is a combination of an introduction, overview and getting started tutorial that is designed to help you quickly decide if a game engine/framework/library is right for you.  Otter2D is an open sourceotterlogo C# based open source game engine built over top of the SFML framework.  Otter2D provides essentially all of the functionality of SFML as well as higher level game engine features like animations, collisions, sessions and components.

 

As always there is an HD video version of this guide available here.

 

Doing what I do for a living I generally am surprised by a game engine or tool.  If I haven’t used it personally I have at least heard of it.  Otter on the other hand took me completely by surprise and for the most part it’s been a fun (and quick!) journey.  There isn’t a ton to Otter2D, it’s a code only framework built over a framework I am already familiar with.  If you have prior SFML experience, Otter2D will come quickly to you.  Due to the composition of Otter2D, this closer look is going to lean much more toward the code/tutorial side.  Let’s jump in.

 

Getting Started

 

Otter2D is available as a zip file (direct download link) or you can build from current source on Bitbucket.  The code is distributed under this license, excerpted below:

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

In case you are wondering, there are no conditions after the colon.  So basically it’s a license that lets you do pretty much whatever you want so long as you keep the license intact.

Getting set up is easy but could be better.  Unfortunately Otter2D is not configured to be used as an external library which is a bit of an odd choice.  Instead you add the Otter2D project to your solution and link to it as a dependency in your project, like so:

image

Full instructions on getting started Visual Studio are available here.

 

Your First Application

 

Now that you’ve got Otter downloaded and configured, let’s create our first application.

using Otter;

namespace OtterScratchPad
{
    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new Entity();
            entity1.AddGraphic(Image.CreateCircle(90,Color.Red));
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

When you run this example you get:

image

 

Otter2D code is very similar to a traditional Entity Component System (ECS) in it’s approach.  Game is the heart of your application, while scene represents your game world.  The scene itself is composed of entities, which in turn contain defined components like Graphic we used above, or actual components, which we will see later.  A more common approach to the above solution is to derive your game objects from Entity instead, like so:

 

using Otter;

namespace OtterScratchPad
{
    class Player : Entity
    {
        public Player(float x, float y) : base(x, y)
        {
            this.AddGraphic(Image.CreateCircle(120, Color.Red));
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new Player(0,0);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

Those two examples are functionally equivalent.  As you can see in the second example when we pass coordinates to our Player Entity the origin by default is the top left corner, both of the screen as well as the sprite.  We will look at changing this shortly.  Congratulations however, you just created your first successful Otter2D application.  Easy eh?  Let’s move on and add some sophistication.

 

Input and Image Loading

 

In our next example, instead of creating a graphic procedurally, we are instead going to load a sprite.  For the source images, I am using the freely available sprites announced here.  Specifically I am using this sprite of a B17 bomber. 

 1

Obviously you can use whatever image you wish, so long as the file format is supported.  Keep in mind, Otter2D is built over SFML so it has the same graphics support as SFML which means your sprite can be in bmp, hdr, gif, jpg, png, pic, psd, tga formats.  Additionally in this example we are going to look at handling keyboard input to move our image left and right in response to key presses.  Alright, on to the code:

using Otter;

namespace OtterScratchPad
{
    class PlayerImage : Entity
    {
        public PlayerImage(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Right))
            {
                this.X++;
            }
            if (Input.KeyDown(Key.Left))
            {
                this.X--;
            }

            base.Update();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerImage(0,0);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

And when you run it:

example1

 

Note when you launch an Otter2D application, it doesn’t have focus and thus wont receive keyboard events.  This seems to be a bug in the underlying SFML libraries.  I spent a few minutes trying to fix it and sadly couldn’t.  Shouldn’t be a big deal as a production game wont use a console window to construct the main window, so this shouldn’t occur.  As you can see from this example, loading sprites and polling input are both trivial exercises, so let’s move on to animations.

 

Sprite Animations

 

In this example I’ve taken the three different frames of the B17 bomber and created a single 3x1 768x256 using ImageMagick.  The end result was:

ss

 

Not very exciting an animation, but each frame the propeller has turned slightly.  Let’s look at the process in Otter2D of using an animated sprite from a single sheet.  In this example we also show how to move the sprites origin or pivot point to it’s middle.

using Otter;

namespace OtterScratchPad
{
    class PlayerSpriteMap : Entity
    {
        enum Animations { Idle };
        Spritemap<Animations> spriteMap = new Spritemap<Animations>("ss.png", 256, 256);

        public PlayerSpriteMap(float x, float y) : base(x, y)
        {
            this.AddGraphic(spriteMap);
            spriteMap.CenterOrigin();
            spriteMap.Add(Animations.Idle, new int[] { 0, 1, 2 }, new float[] { 9.0f, 4.0f, 10.0f });
            spriteMap.Play(Animations.Idle);
        }
        public override void Update()
        {

            if (Input.KeyDown(Key.Right))
            {
                this.X += 300f * this.Game.RealDeltaTime / 1000;
            }
            if (Input.KeyDown(Key.Left))
            {
                this.X -= 300f * this.Game.RealDeltaTime / 1000;
            }

            base.Update();
        }

    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerSpriteMap(game.HalfWidth,game.HalfHeight);
            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

 

Run it and:

 

example2

 

You may have to squint to see it, but that is certainly an animated sprite.  Instead of using Image we instead use a SpriteMap which takes the individual sprite dimensions as well as the spritesheet file name in it’s constructor.  The entity is then centered with a call to CenterOrigin().  Animations is simply a user defined enum that is used as the key within the sprite map.  When the map is added we pass in an array of ints or strings representing the frames offset within the source image as well as the duration for each frame of animation.

 

Collisions

 

Next we will modify the earlier example so we now have two airplane sprites that can collide with each other.  In addition to adding two sprites to the world, the example has also been changed so you can create both a player and non-player sprite, so only one responds to keyboard input.  Additionally instead of simply moving via X++, we change it so we move at a fixed frame rate depending on the elapsed time since the last frame.

using Otter;

namespace OtterScratchPad
{
    class PlayerSpriteMapWithCollisions : Entity
    {
        enum Animations { Idle };
        Spritemap<Animations> spriteMap = new Spritemap<Animations>("ss.png", 256, 256);

        enum ColliderTypes { Planes };
        bool isPlayer;
        public PlayerSpriteMapWithCollisions(float x, float y, bool player) : base(x, y)
        {
            isPlayer = player;
            this.AddGraphic(spriteMap);
            spriteMap.CenterOrigin();
            spriteMap.Add(Animations.Idle, new int[] { 0, 1, 2 }, new float[] { 9.0f, 4.0f, 10.0f });
            spriteMap.Play(Animations.Idle);

            this.AddCollider(new BoxCollider(256, 256, ColliderTypes.Planes));
            this.Collider.CenterOrigin();
        }

        public override void Update()
        {
            if (isPlayer)
            {
                if (Input.KeyDown(Key.Right))
                {
                    this.X += 100f * this.Game.RealDeltaTime / 1000;
                }
                if (Input.KeyDown(Key.Left))
                {
                    this.X -= 100f * this.Game.RealDeltaTime / 1000;
                }

                // Check for collisions
                if (this.Collider.Overlap(X, Y, ColliderTypes.Planes))
                    this.X = 0f;
            }
            base.Update();
        }

    }


    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new Scene();

            Entity entity1 = new PlayerSpriteMapWithCollisions(0,game.HalfHeight,true);
            Entity entity2 = new PlayerSpriteMapWithCollisions(game.Width - 128, game.HalfHeight, false);

            scene.Add(entity1);
            scene.Add(entity2);

            game.Start(scene);
        }
    }
}

 

And run it:

example3

 

You may notice the collision isn’t amazingly accurate.  This is because in this example we used a box collider but there is some dead pixel space between our wing and the end of the image.  If you require increased accuracy you could instead us a pixel collider, but it will have a profound effect on performance.

 

Sound and Music

 

Next lets look at adding audio support to our game.  Let’s start by adding some sound effects to our player:

    class PlayerImageWithSound : Entity
    {
        // 30 cal burst:: http://www.freesound.org/people/Hamp999/sounds/151620/
        Sound sound1 = new Sound("sound1.wav");

        // Bomb drop http://www.freesound.org/people/sunch/sounds/274090/
        Sound sound2 = new Sound("sound2.wav");

        public PlayerImageWithSound(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            //Center within and without
            this.Graphic.CenterOrigin();
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Num1))
            {
                sound1.Play();
            }
            if (Input.KeyDown(Key.Num2))
            {
                sound2.Play();
            }

            base.Update();
        }
    }

 

When you hit the 1 key a certain sound effect plays, hit the 2 key a different sound effect plays.  There are two important things to note with audio in Otter2D.  Once again, it depends on SFML for the audio code so Otter supports the file formats that SFML supports ( which are too many to list ).  Additionally playing a sound halts earlier versions of that sound, so if you want multiple concurrent plays of the same sound, you need to create multiple instances.

 

Now let’s take a look at a music example.  Instead of extending another Entity, we will be creating our own Scene this time.

using Otter;

namespace OtterScratchPad
{
    class PlayerImageWithSound : Entity
    {
        // 30 cal burst:: http://www.freesound.org/people/Hamp999/sounds/151620/
        Sound sound1 = new Sound("sound1.wav");

        // Bomb drop http://www.freesound.org/people/sunch/sounds/274090/
        Sound sound2 = new Sound("sound2.wav");

        public PlayerImageWithSound(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            //Center within and without
            this.Graphic.CenterOrigin();
        }
        public override void Update()
        {
            if (Input.KeyDown(Key.Num1))
            {
                sound1.Play();
            }
            if (Input.KeyDown(Key.Num2))
            {
                sound2.Play();
            }

            base.Update();
        }
    }

    class SceneWithMusic : Scene
    {
        // Sound file is http://www.freesound.org/people/Diboz/sounds/216071/
        // Play, not looping
        public Music song = new Music("music.ogg", false);

        public SceneWithMusic() : base()
        {
            song.Play();
        }

        public override void Update()
        {
            base.Update();

            if (Input.MouseButtonPressed(MouseButton.Left))
                Music.GlobalVolume -= 0.1f;
            if (Input.MouseButtonPressed(MouseButton.Right))
                Music.GlobalVolume += 0.1f;

            if (Input.KeyPressed(Key.Space))
            {
                // Fast forward 10 seconds on spacebar if 10 seconds remain in play time
                if ((song.Offset + 10000) < song.Duration)
                    song.Offset += 10000;
            }
            if (!song.IsPlaying)
            {
                System.Console.WriteLine("Music stopped");
                Game.Close();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();
            game.Color = Color.White;

            Scene scene = new SceneWithMusic();

            Entity entity1 = new PlayerImageWithSound(0,game.HalfHeight);


            scene.Add(entity1);

            game.Start(scene);
        }
    }
}

In this example there is now music playing when you start your game and you can fast forward the song by pressing the space bar.  Additionally global (all sound effects and music ) volume can be increased and decreased using the left and right mouse button, also illustrating how easy it is to poll the mouse for input as well. 

 

Components

 

I mentioned earlier that Otter2D has component support?  Well we saw a bit of it in action with the addition of Graphic objects to our Entity.  In this case though we are going to drop in slightly more advanced components, as well as create one of our own.

    class CustomComponent : Component
    {
        public override void Update()
        {
            base.Update();
            float alpha = Entity.GetGraphic<Image>().Alpha;
            alpha -= 0.005f;
            if (alpha <= 0.0f)
                alpha = 1.0f;
            Entity.GetGraphic<Image>().Alpha = alpha;
        }
    }
    // A Player Entity with components attached
    class PlayerWithComponents : Entity
    {
        public PlayerWithComponents(float x, float y) : base(x, y)
        {
            this.AddGraphic(new Image("1.png"));

            Axis axis = Axis.CreateWASD();
            BasicMovement movement = new BasicMovement(100, 100, 20);
            movement.Axis = axis;
            AddComponents(
                axis,
                movement,
                new CustomComponent()
                );
            this.Graphic.CenterOrigin();
        }
    }

 

And when you run it:

example4

 

Here we’ve used a set of built in keys, one for applying movement to your entity.  The parameters passed in limit x and y velocity as well as the rate of acceleration.  Then we create another component that maps the WASD keys to an axis, which can be used to drive our movement component.  Finally we create a custom component that changes our alpha over time.

 

Documentation and Community

 

Otter2D’s documentation consists of a collection of examples here and a generated reference manual available here.  It’s not a huge body of work however Otter2D is extremely simple to use so doesn’t really need much more.  Additionally it is built on top of SFML, so that underlying documentation and community are also available.  That said, it is built on the C# bindings of SFML and that community is much smaller than the main SFML community.

 

In terms of community there is a small forum available here.  It’s not extremely active but it is a place to get your questions answered.  There are a handful of tutorials on the web but not a huge amount by any definition of the word.

 

Conclusion

 

Otter2D is a pretty solid 2D game engine built over top of a well established framework.  It was extremely easy to learn and use, the design is clean enough you can intuit most of the process.   On major flaw I never discussed was the support for the Ogmo level editor, which IMHO was a very bad choice.  First off, it simply doesn't work, loaded levels are mangled.  Worse though, Ogmo itself was a frustrating mess to work with… every single change to the map (adding a layer, changing size, tile format, etc. ), completely destroyed everything you had done up to that point.  Adding support for a better editor such as Tiled would be relatively short work, but this was by far the most frustrating part of working with Otter2D.

 

Otherwise it is exactly what it is.  A clean, easy to use, fairly full featured 2D C# game engine.  As it is built over SFML and in C# deploying to platforms such as Android or iOS is most likely going to be painful ( no documentation exists ) and will most certainly require a Xamarin license.  For a 2D desktop title or as a learning game engine however, Otter2D would be a very solid choice.  As odd as it sounds, Otter2D was simply fun to work with, somewhat like Love2D, especially after dealing with much more complex engines or even SFML itself.

 

The Video

Programming


22. October 2015

 

As part of the ongoing Tiled Map Editor tutorial this part looks at using Object Layers, which can be used to interface your tiled map with your games code.  This particular example includes the code using TypeScript and the Phaser game library.  If you need more information on Phaser I’ve done a tutorial series here.

 

The video of this tutorial is available here or embedded below.

 

The Code

index.html

 

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Hello Phaser</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="phaser.js"></script>
    <script src="app.js"></script>
</head>
<body>
    <div id="content"></div>
</body>
</html>

app.ts

/// <reference path="phaser.d.ts"/>


class ObjectEntity {
    height: number;
    name: string;
    properties: any;
    rectange: boolean;
    rotation: number;
    type: string;
    visible: boolean;
    width: number;
    x: number;
    y: number;
}

class SimpleGame {
    game: Phaser.Game;
    map: Phaser.Tilemap;
    layer: Phaser.TilemapLayer;
    player: Phaser.Sprite;
    winZone: Phaser.Rectangle;

    constructor() {
        this.game = new Phaser.Game(640, 480, Phaser.AUTO, 'content', {
            create: this.create, preload:
            this.preload, update: this.update, render: this.render
        });
    }
    preload() {
        this.game.load.tilemap("ItsTheMap", "newMap.json", null, Phaser.Tilemap.TILED_JSON);
        var img = this.game.load.image("HF2_A2", "HF2_A2.png");
        this.game.load.image("Decepticon", "decepticonLarge.png");
    }
    update() {

        if (this.winZone.contains(this.player.x + this.player.width/2,this.player.y + this.player.height/2))
            alert("You Win!");

    }
    render() {
    }
    create() {
        this.map = this.game.add.tilemap("ItsTheMap", 32, 32, 64, 32);
        this.map.addTilesetImage("HF2_A2","HF2_A2");

        this.map.createLayer("Background").resizeWorld();

        this.player = new Phaser.Sprite(this.game, 0, 0, "Decepticon");
        this.player.width = 64;
        this.player.height = 64;
        this.game.world.addAt(this.player, 1);

        this.game.camera.follow(this.player);

        var something = this.map.objects["GameObjects"][0];
        var start = <ObjectEntity>this.map.objects["GameObjects"][0];
        var end = <ObjectEntity>this.map.objects["GameObjects"][1];


        this.winZone = new Phaser.Rectangle(end.x, end.y, end.width, end.height);

        this.player.position.set(start.x, start.y);

        this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT).onUp.add(() => {
            this.player.position.add(-32, 0);
        });

        this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT).onUp.add(() => {
            this.player.position.add(32, 0);
        });

        this.game.input.keyboard.addKey(Phaser.Keyboard.UP).onUp.add(() => {
            this.player.position.add(0,-32);
        });

        this.game.input.keyboard.addKey(Phaser.Keyboard.DOWN).onUp.add(() => {
            this.player.position.add(0, 32);
        });
    }
}

window.onload = () => {
    var game = new SimpleGame();
};

 

 

The Video

 

Art Design Programming


AppGameKit Studio

See More Tutorials on DevGa.me!

Month List