Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

1. November 2012

 

You can go ahead and download it right here.  Rather impressively, I am getting 2mb download speeds, so their servers haven’t melted down like on previous releases.

 

It doesn’t yet appear to be available for MacOS X.  The beta also doesn’t include the ability to trial pro for 30 days.

 

You can read the release notes right here.

 

 

Key features of the beta:

 

  • humanoid animation system, reuse same animations on different sized characters,  map bones of models to human muscles with a single click.  Animation editing directly in Unity
  • DirectX11 rendering
  • Geometry and hull shaders added
  • Linux publishing
  • Normal maps and custom shader support for terrain
  • Shadows on mobile devices
  • 3D volume texture support
  • Dynamic font rendering that looks the same on all platforms
  • New project browser
  • GUI system re-written
  • New cursor api, supporting hardware cursors on certain platforms
  • New licensing options and abilities
  • Many other improvements, changes and fixes ( and most likely, bugs Smile )

News

1. November 2012

 

In the last couple days a few very useful tutorials have shown up on the Moai forums, I thought I would bring to your attention.

 

Resource Manager with Multi-Res support

This is an intermediate level tutorial, as the author suggested, there aren’t actually all that many tutorials serving this skill level.  He has a couple more tutorials in the works, hopefully at the same link.  In the author’s words, this tutorial:

The resource manager that we will be creating will actually be divided into several parts, each adding specific functionality and some really handy features. As far as the application (your game logic) is concerned, there is a namespace called 'ResMan' that provides functions for retrieving any type of data that it needs. This tutorial will start with a simple interface in the ResMan namespace for retrieving images and fonts, as the tutorial progresses the interface will be expanded to include more resource types as well as implement some very handy functionality.

 

 

Extending MOAI Lua host with additional 3rd party libraries

Another slightly shorter tutorial, this one is also at the intermediate level.  In the authors own words:

This is a brief how to which I'm posting here because it might save you 5 minutes (or me 5 minutes if I do this again). Recently I added lua 'bit ops' to the MOAI host so I could have bit flags. It was completely painless and here's a little recipe:

 

Basically it illustrates how to add another lua module to the Moai host, in this case bit ops, very handy.

 

Nice work guys, keep ‘em coming.  I really have to start a new Moai tutorial soon…

Programming , ,

31. October 2012

 

Microsoft have just release their Windows Phone 8 SDK, you can read the announcement right here.  They have also launched a new Windows Phone 8 Dev Center, that you can access here.

 

And apparently, Microsoft don’t want anyone to use it…

System requirements

Supported operating systems: Windows 8, Windows 8 Pro

    • Windows 8 64-bit (x64) client versions
  • Hardware:
    • 4 GB of free hard disk space
    • 4 GB RAM
    • 64-bit (x64) CPU
  • Windows Phone 8 Emulator:
    • Windows 8 Pro edition or greater
    • Requires a processor that supports Second Level Address Translation (SLAT)

 

Windows 8 only?  Really Microsoft, really?  Your platform isn’t exactly the most popular these days, you can’t seriously be trying to push Windows 8 adoption with your developer tools?  This hopefully is just a mistake, I’d like to think Microsoft isn’t really run by idiots.

Anyways… assuming you are one of the 12 people running Windows 8, you can download the SDK right here.  You can still download and install it on non-Windows 8 versions, but apparently the emulator is disabled, pretty much leaving you dead in the water.

 

As for new technical features, those are highlighted here.  A quick summary of some of the most relevant options are:

  • Direct3D XAML interop, allowing you to build D3D apps that work with XAML.
  • Multitargeting, allowing you to target Win Phone 7 and 8 with one project
  • XAML and native code profilers

 

Microsoft also released this video on Native C++ game development with Windows Phone 8

Native C++ game development with Windows Phone 8



 

 

If you are interested in developing for Windows Phone 8, you may want to sign up now, as:

Windows Phone 8 is out, the tools are available, and devices are about to be released—it’s time to get coding. As an added incentive, for the next 8 days individual developers can register for a Dev Center account for just $8 (a 92 percent savings). Please note because this is a very limited time offer. You’ll be charged $99 USD or equivalent in your local currency, and we’ll refund the difference in the next 30 to 45 days. Watch for more details on Dev Center soon.

 

Why 8$?  Anyways, any interest in developing for Windows 8 Phone?  I personally love Microsoft’s platforms and development tools, by far the best in the industry.  That said, I just dont believe in … well, anything they are doing lately.  I expect Windows 8 to be a gigantic flop and a senior executive house cleaning to occur.  For the record, I owned Microsoft stock up until about 2 months ago.  Shows what faith I have in their current strategy.

News

30. October 2012

 The following is a guest tutorial post written by Michael Habalcik on using the freely available Moscrif game development suite to create a simple mobile game.  I hope you find it informative.

 

 


 

Balloons game demo in Moscrif SDK

 

We are proud to present one of very first tutorials about “a new kid on the block”. Moscrif is the new member of cross-platform development tools suited for a modern mobile game developer.

 

Moscrif overview

Moscrif SDK is a development suite solving the problem of supporting an increasing number of mobile platforms. The number of these platforms is increasing making it almost impossible to go native for every one of these. With Moscrif, only one development cycle is needed allowing you to publish the game to the most popular platforms. With the current support of iOS, Android, Nook or Kindle you can reach up to 80% of the mobile market audience. New Windows Phone should be supported in the near future reaching even more mobile users.

 

The key advantage is the need of just one code base. Because Moscrif uses JavaScript, it is extremely easy to adopt for experienced developers as well as for beginners because JavaScript is one of the easiest languages to learn with a countless number of tutorials all over the net.

 

Other benefits:

 

      Graphics performance - Moscrif applications are able to achieve 50 frames per seconds (one of the bests in the industry)

      Hardware acceleration – the amazing graphics performance is achieved with the contribution of fully OpenGL hardware acceleration

      Code one, run anywhere – the only one code of application can run on almost 90% of devices

      Reuse your knowledge – Moscrif uses JavaScript language which makes no problem for everybody who has ever developed web application or desktop applications in C, C++, Java etc.

      Publish on your own computer in few seconds – some other cross platform tools requires sending the source codes to theirs servers and publishing process sends some hours. Moscrif makes it on your own computer in few seconds.

      Free license - Moscrif is one of only few similar tools offering a free license

      IDE - Moscrif comes with its own IDE which is a part of the SDK

 

The Moscrif is available for free download on its homepage http://moscrif.com/download.

 

The balloon game demo

 

To present the capabilities of Moscrif, we have created a simple game demo based on shooting down the balloons. This game contains only one level and simple game menu, but with only few additional lines of code it can be transferred into a full game ready to hit the app stores.

NewImage NewImage

 

Starting a new project

 

To create the project the Project wizard (click File -> New -> New project) will be used. We have selected the new 2D Game option as it is exactly what we are looking for.

 

New Project

In the next step we set few of the most basic project’s properties like the landscape orientation. We have also checked the box2d library to be added into the project. As we are interested in some basic game menu as well, the option called Screens select Game with Menu is checked as well.

 

NewImage

In the next step we set few of the most basic project’s properties like the landscape orientation. We have also checked the box2d library to be added into the project. As we are interested in some basic game menu as well, the option called Screens select The wizard will create a new project with three precreated scenes: menu, single and multiPlayer.

 

In this sample we are only going to use a single player mode. Therefore, we need only 2 scenes - one for the menu and one for the game itself. So you can delete the multi player scene (remove also the include command in main.ms file). Game with Menu is checked as well.The wizard will create a new project with three precreated scenes: menu, single and multiPlayer. In this sample we are only going to use a single player mode. Therefore, we need only 2 scenes - one for the menu and one for the game itself. So you can delete the multi player scene (remove also the include command in main.ms file).

 

The whole game code will be in singlePlayerScene file, so we open it for editing. As seen on the example below, our scene class is extended from the PhysicsScene base class. The Scene base class creates a basic scene without the support of physical engine. Because Scene class is not sufficient for use as we need the support of physics engine, we use PhysicsScene class instead.

 

Following, a new instance of b2World object is created in the init method taking 4 parameters:

 

1      gravity on the x axis

2      gravity on the y axis

3      true/false doSleep parameter. We use True to improve the performance

4      true/false allowing the collisions between the objects within the scene

 

We set the gravity on the y axis to -9.81 what is equivalent of real earth’s gravity.

 

Example: applying physical engine in the scene

 

class SinglePlayerScene : PhysicsScene

{

    // constants

    const maxForce = 2000;

    const forceStep = 0.1;

    const maxDistance = 3*System.height / 5;


    function init()
    {
        super.init();

        this.start = System.tick;

        this.world = new b2World(0.0, -9.81, true, true);

….

 

Physical engine

 

To simulate the real world’s behavior Moscrif relies on powerful box2d physical engine. This engine is used by many platforms and many well known games rely on it like: Crayon Physics Deluxe, Limbo, Rolando, Fantastic Contraption, Incredibots, Angry Birds etc.

 

The main part of the physical engine is the world which consists of the bodies and the joints. It manages all aspects of the simulation and contacts between the bodies. Bodies interact together according to theirs properties which specify the density, friction and/or bounce.

 

The engine supports three different types of the bodies, which behaves differently. Static bodies do not move under the simulation and collide with dynamic bodies. The dynamic bodies are fully simulated and collide with all other bodies. The last, kinematic bodies do not move under the forces, only according to its velocity. They interact only with dynamic bodies. In Moscrif, bodies are created as an instance of PhysicsSprite class or class extended from the PhysicsSprite class. The position of bodies and collisions are recalculated in small time intervals.

 

Example: making a time step in physics simulation

 

function process()

{

    // timestep in physics simulation

    var timeStep = 1.0 / 40.0;

    // recalculate physics world. All objects are moved about timeStep

    this.step(timeStep, 4, 8);

….

}

 

The Balloons

 

Balloons are managed by their own class extended from the PhysicsSprite class. Every balloon is made of several frames that are changed every 100 milliseconds creating a simple and realistic animation. When a balloon reaches the top of the screen an end event is raised.

 

Image: balloons frames

NewImage

 

 

 

Example: creating the balloon class

 

class Balloon : PhysicsSprite

{

    function init()

    {

        super.init();

 

        // set image with frames

        this.image = GFX.ballon;

        // set frame dimension

        this.frameWidth = GFX.ballon.width / 5;

        this.frameHeight = GFX.ballon.height;

 

        // start timer

        this.timer = new Timer(100, true);

        this.timer.onTick = function()

        {

            // move to next frame

            if (this super.frame == 4/*number of frmes*/)

                this super.frame = 0;

            else

                this super.frame+=1;

 

            // check if the balloon does not passed the top of the screen

            var (x, y) = this super.getPosition();

            if (y < 0)

                this super._endHandler(this super);

            // speedup

            this super.setLinearVelocity(0, this super.getLinearVelocity() + 0.07);

        }

        this.timer.start(100);

    }

 

    // end level event

    property end(v)

    {

        get return this._endHandler;

        set this._endHandler = v;

    }

}

 

Balloons start from the random position at the bottom of the screen in time intervals.

 

function _setTimer(i = 1)

{

    this._timer = new Timer(1, 1);

    this._timer.onTick = function()

    {

        // create ballon

        this super._createBallon(i);

        // decrease the time between two ballons

        if (this super._time > 200)

            this super._time -= 3;

        i += 0.1;

        this super._setTimer(i);

 

    }

    this._timer.start(this._time);

}

 

The Ball

 

The ball is fired from the bottom of the screen. The angle and force of the fire are controlled by the user touches on the screen. When user taps the screen the first angle and force is calculated. The force is calculated as a rate of distance of user’s touch from the ball’s start position and its max distance which is equal to the max force. The angle is calculated using the trigonometric function tangents as a rate of distance on y and x axis.

 

Example: calculating the force and angle

 

function pointerPressed(x, y)

{

    super.pointerPressed(x, y);

 

    if(this._ended) {

        this._goBack();

        return;

    }

 

    // calculate distance on both axis

    var distanceX = x - System.width / 2;

    var distanceY = y - 9*System.height / 10;

    // calculate angle

    this._angle = Math.atan2(distanceY, distanceX);

    // total distance

    var distance = Math.sqrt(distanceX*distanceX + distanceY*distanceY);

    // max distance (max distance is distance which equal the max force)

    if (distance > maxDistance)

        distance = maxDistance;

    // calculate force

    this._force = (1.0*distance / maxDistance)*maxForce;

}

 

When user drags his finger the angle and force are recalculated in the same way as when he presses it. Finally, when user releases his finger the ball is fired.

 

Example: firing the ball

 

function _fire()

{

    // if can not fire do nothing

    if (!this._canFire)

        return;

 

    // add new ball

    this._ball = this.addCircleBody(GFX.ball, #dynamic, 1.0, 0.0, 0.0, GFX.ball.width / 2);

    this._ball.setPosition(System.width / 2, 9*System.height / 10);

    this._ball.id = #ball;

    this._ball.bullet = true;

 

    // start veloity of the ball acording to angle and force

    var velox = this._force*Math.cos(this._angle)/this.scale;

    var veloy =-this._force*Math.sin(this._angle)/this.scale;

 

    //apply velocity

    this._ball.setLinearVelocity(velox, veloy);

 

    // diable next fire

    this._canFire = false;

    // allow fire after 500ms

    var t = new Timer(1, 1);

    t.onTick = function ()

    {

        this super._canFire = true;

    }

    t.start(500);

}

 

Contacts

 

When two bodies collide together a beginContact and endContact events are raised. The events have only one parameter – a list of all contacts in the world. Every record in the list contains information about both bodies of the contact (accessible by getBodyA and getBodyB methods).

 

Example: managing contacts

 

function beginContact(contact)

{

    var current = contact;

    while (current) {

        // get both bodies in contact

        var bodyA = current.getBodyA();

        var bodyB = current.getBodyB();

        // check if a ballon was hit

        if (bodyA.id == #ball && bodyB.id == #ballon) {

            // destoy ballon

            this._bodiesToDestroy.push(bodyB);

        // check if a ballon was hit

        } else if(bodyB.id == #ball && bodyA.id == #ballon) {

            // destoy ballon

            this._bodiesToDestroy.push(bodyA);

        // check if something hit the border (only ball can)

        } else if(bodyB.id == #border) {

            this._bodiesToDestroy.push(bodyA);

        } else if(bodyA.id == #border) {

            this._bodiesToDestroy.push(bodyB);

        }

        // get next body

        current = current.getNext();

    }

}

 

Summary

 

As you can see, creating mobile games using Moscrif SDK is straightforward and even the beginners should be able to create a killer game. So are you going the make the new Angry Birds? It’s free, so why not to try it …

 

The source code of this sample can be found at https://github.com/moscrif/samples/tree/master/sampleBallons

Programming

29. October 2012

 

Since I've been working on a Mac more and more often these days, I've been looking for an alternative to the wonderful Windows Live Writer for Windows.  I started with a trial of MarsEdit, which I really liked, except it's inability to display formatted source code ( a big deal for me ), its lack of tagging ( not a really big deal, but a nuisance ) and the lack of image formatting options.

 

Then I found and discovered Adobe Contribute, which has a 100$ price tag.  It started off strong but quickly took a jump off a cliff into the land of truly awful.  It seems to be poorly supported by Adobe, has documented features that don't appear to exist anymore, has some gigantic bugs ( such as the Paste menu never being enabled! ).  It did however have incredible table formatting tools!  I know in the age of CSS, table is a bit of a swear word, but damned if a lot of your data isn't in a tabular format.  The image formatting options were easily the best of all packages I've used, including Live Writer.  But good tables and good image positioning tools don't even come close to making up for the brutal flaws, especially at a 100$ price point.

 

I then tried out Qumana, a completely free option:

Qumana screenshot

At first glance, it pushes all the buttons.  It doesn't support tags ( only Live Writer seems to ), but image formatting is decent, and you can directly edit the HTML of your post, so if you know HTML, the sky is the limit.  I attempted to write the previous post with Qumana and ran in to a gigantic deal breaker attempting to insert an IFrame… you can't.  I pasted the HTML code for a Youtube video, then when I switch back to WYSIWG view, poof gone.  Game over.

 

So then, back to MarsEdit, which I went ahead and purchased.  In the end, MarsEdit was easily the best option of what is available for Mac.  The biggest sellable point was the ability to drop to and edit HTML, which is nicely preserved when switching back to rich text mode.

 

Now, Red Sweater, if you are listening, please add the ability to create plugins, or failing that, the ability to post formatted source code.  Also, tag support would be nice!

 

If you are a MarsEdit user, and currently post code samples on your blog, how are you doing it?

General

Month List

Popular Comments

LibGDX Tutorial 11: Tiled Maps Part 3: Using Properties and Tile Map animations
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


Home > >

18. June 2014

 

In this part we are going to look at how to add animations to a TileMap in LibGDX.  Along the way we are going to look at using Properties a very important part of using Tile maps, as properties contain your games “data”.  First let’s take a look at setting properties in Tiled.  I am adding a second Tileset to my existing map called “Water” using the following graphic I download from Google Images.  Tiled doesn’t support animations, so we are going to hack support in using properties.

 

WaterTiles

 

You can get more details on working with Tiled here.

 

Properties are set in the Tile, not the Cell in TileEd.  Load the above image as a new Tileset in Tiled named Water.  We are working with just 3 of the water tiles:

Te1

 

Right click on a tile and select Tile Properties...

Te2

Now we want to set a property “Water Frame” and give it the value of 1.

Te3

 

Now repeat for the next two water tiles, with the values 2 and 3 respectively.

 

In addition to Tile properties, you can also set properties at the Layer and Map level.  Properties are just a name value pair of strings when imported into LibGDX.  Let’s take a look at that process now.

 

Save your tiled map and add it to the assets folder of your project.  Also add all the various texture maps used for tiles.  Let’s look at some ( heavily commented ) code that builds on our earlier tile map example:

package com.gamefromscratch;

 

import com.badlogic.gdx.ApplicationAdapter;

import com.badlogic.gdx.Gdx;

import com.badlogic.gdx.Input;

import com.badlogic.gdx.InputProcessor;

import com.badlogic.gdx.graphics.GL20;

import com.badlogic.gdx.graphics.OrthographicCamera;

import com.badlogic.gdx.graphics.Texture;

import com.badlogic.gdx.graphics.g2d.Sprite;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import com.badlogic.gdx.maps.tiled.*;

import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;

import java.util.*;

 

public class TiledTest extends ApplicationAdapter implements InputProcessor {

    Texture img;

    TiledMap tiledMap;

    OrthographicCamera camera;

    TiledMapRenderer tiledMapRenderer;

    SpriteBatch sb;

    Texture texture;

    Sprite sprite;

    ArrayList<TiledMapTileLayer.Cell> waterCellsInScene;

    Map<String,TiledMapTile> waterTiles;

    floatelapsedSinceAnimation = 0.0f;

 

    @Override public void create () {

        float w = Gdx.graphics.getWidth();

        float h = Gdx.graphics.getHeight();

 

        camera = new OrthographicCamera();

        camera.setToOrtho(false,w,h);

        // Position the camera over 100pixels and up 400 to capture more interesting part of map

        camera.translate(100,400);

        camera.update();

        //Load our tile map

        tiledMap = new TmxMapLoader().load("MyCrappyMap.tmx");

 

        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);

        Gdx.input.setInputProcessor(this);

 

        // We created a second set of tiles for Water animations

        // For the record, this is bad for performance, use a single tileset if you can help it

        // Get a reference to the tileset named "Water"

        TiledMapTileSet tileset =  tiledMap.getTileSets().getTileSet("Water");

 

 

        // Now we are going to loop through all of the tiles in the Water tileset

        // and get any TiledMapTile with the property "WaterFrame" set

        // We then store it in a map with the frame as the key and the Tile as the value

        waterTiles = new HashMap<String,TiledMapTile>();

        for(TiledMapTile tile:tileset){

             Object property = tile.getProperties().get("WaterFrame");

            if(property != null)

                waterTiles.put((String)property,tile);

        }

 

        // Now we want to get a reference to every single cell ( Tile instance ) in the map

        // that refers to a water cell.  Loop through the entire world, checking if a cell's tile

        // contains the WaterFrame property.  If it does, add to the waterCellsInScene array

        // Note, this only pays attention to the very first layer of tiles.

        // If you want to support animation across multiple layers you will have to loop through each

        waterCellsInScene = new ArrayList<TiledMapTileLayer.Cell>();

        TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.getLayers().get(0);

        for(int x = 0; x < layer.getWidth();x++){

            for(int y = 0; y < layer.getHeight();y++){

                TiledMapTileLayer.Cell cell = layer.getCell(x,y);

                Object property = cell.getTile().getProperties().get("WaterFrame");

                if(property != null){

                    waterCellsInScene.add(cell);

                }

            }

        }

    }

 

    @Override public void render () {

        Gdx.gl.glClearColor(1, 0, 0, 1);

        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();

        tiledMapRenderer.setView(camera);

        tiledMapRenderer.render();

 

        // Wait for half a second to elapse then call updateWaterAnimations

        // This could certainly be handled using an Action if you are using Scene2D

        elapsedSinceAnimation += Gdx.graphics.getDeltaTime();

        if(elapsedSinceAnimation > 0.5f){

            updateWaterAnimations();

            elapsedSinceAnimation = 0.0f;

        }

    }

 

    // This is the function called every half a second to update the animated water tiles

    // Loop through all of the cells containing water.  Find the current frame and increment it

    // then update the cell's tile accordingly

    // NOTE!  This code depends on WaterFrame values being sequential in Tiled

    private void updateWaterAnimations(){

        for(TiledMapTileLayer.Cell cell : waterCellsInScene){

            String property = (String) cell.getTile().getProperties().get("WaterFrame");

            Integer currentAnimationFrame = Integer.parseInt(property);

 

            currentAnimationFrame++;

            if(currentAnimationFrame > waterTiles.size())

                currentAnimationFrame = 1;

 

            TiledMapTile newTile = waterTiles.get(currentAnimationFrame.toString());

            cell.setTile(newTile);

        }

    }

 

    @Override public boolean keyDown(int keycode) {

        return false;

    }

 

    @Override public boolean keyUp(int keycode) {

        if(keycode == Input.Keys.LEFT)

            camera.translate(-32,0);

        if(keycode == Input.Keys.RIGHT)

            camera.translate(32,0);

        if(keycode == Input.Keys.UP)

            camera.translate(0,-32);

        if(keycode == Input.Keys.DOWN)

            camera.translate(0,32);

        if(keycode == Input.Keys.NUM_1)

            tiledMap.getLayers().get(0).setVisible(!tiledMap.getLayers().get(0).isVisible());

        if(keycode == Input.Keys.NUM_2)

            tiledMap.getLayers().get(1).setVisible(!tiledMap.getLayers().get(1).isVisible());

        return false;

    }

 

    @Override public boolean keyTyped(char character) {

 

        return false;

    }

 

    @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) {

        return false;

    }

 

    @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) {

        return false;

    }

 

    @Override public boolean touchDragged(int screenX, int screenY, int pointer) {

        return false;

    }

 

    @Override public boolean mouseMoved(int screenX, int screenY) {

        return false;

    }

 

    @Override public boolean scrolled(int amount) {

        return false;

    }

}

Basically what we do is load our map, then we loop through the “Water” tile set and grab a reference to any tile marked as a Waterframe.  We then perform the same action, looping through all of the cells in our map ( on the first layer! ) and if the cells tile has a reference to a tile that has the Waterframe property defined.  Then every half a second we update each cell to the next available frame of animation, or loop back to the first frame if none are available.

 

Now if you run this code, voila!  Animated water:

Te4

 

In this case we manually updated tiles in the map.  LibGDX does however present another option.  They have recently added an Animated tile class.  That said, this functionality is very new so warning ,there be dragons.  In fact, I didn’t find a single implementation online, so this may in fact be the first!

 

Here is a code example using AnimatedTiledMapTile to achieve the same effect:

 

package com.gamefromscratch;

 

import com.badlogic.gdx.ApplicationAdapter;

import com.badlogic.gdx.Gdx;

import com.badlogic.gdx.graphics.GL20;

import com.badlogic.gdx.graphics.OrthographicCamera;

import com.badlogic.gdx.graphics.Texture;

import com.badlogic.gdx.graphics.g2d.Sprite;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import com.badlogic.gdx.maps.tiled.*;

import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;

import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile;

import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile;

import com.badlogic.gdx.utils.Array;

 

public class TiledTest extends ApplicationAdapter{

    Texture img;

    TiledMap tiledMap;

    OrthographicCamera camera;

    TiledMapRenderer tiledMapRenderer;

    SpriteBatch sb;

    Texture texture;

    Sprite sprite;

    Array<AnimatedTiledMapTile> waterTilesInScene;

    Array<StaticTiledMapTile> waterTiles;

    floatelapsedSinceAnimation = 0.0f;

 

    @Override public void create () {

        float w = Gdx.graphics.getWidth();

        float h = Gdx.graphics.getHeight();

 

        camera = new OrthographicCamera();

        camera.setToOrtho(false,w,h);

        camera.translate(100,400);

        camera.update();

        tiledMap = new TmxMapLoader().load("MyCrappyMap.tmx");

 

        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);

 

        TiledMapTileSet tileset =  tiledMap.getTileSets().getTileSet("Water");

 

        waterTiles = new Array<StaticTiledMapTile>();

        for(TiledMapTile tile:tileset){

            Object property = tile.getProperties().get("WaterFrame");

            if(property != null) {

                waterTiles.add(new StaticTiledMapTile(tile.getTextureRegion()));

            }

        }

 

        waterTilesInScene = new Array<AnimatedTiledMapTile>();

 

        TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.getLayers().get(0);

        for(int x = 0; x < layer.getWidth();x++){

            for(int y = 0; y < layer.getHeight();y++){

                TiledMapTileLayer.Cell cell = layer.getCell(x,y);

                Object property = cell.getTile().getProperties().get("WaterFrame");

                if(property != null){

                    cell.setTile(new AnimatedTiledMapTile(0.5f,waterTiles));

                }

            }

        }

 

    }

 

    @Override public void render () {

        Gdx.gl.glClearColor(1, 0, 0, 1);

        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();

        tiledMapRenderer.setView(camera);

        tiledMapRenderer.render();

    }

}

 

Ultimately the logic is very similar.  Here however we actually replace the tile type of for each water instance we find in our map with a AnimatedTiledMapTile.  It is passed an interval to update ( 0.5 second again ) as well as an array of tiles to use as part of the animation.  The logic is basically identical, you just have slightly less control and no longer have to handle the updating on your own!

blog comments powered by Disqus

Month List

Popular Comments

Substance Painter 2 Released
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


16. March 2016

 

Substance Painter, the PBR (Physically Based Rendering) texture painting tool, just released version 2.0.  If you want more information on Substance I featured it in this video.  It’s an excellent texture creation tool that is growing in popularity every day ( just yesterday Unity announce Substance support for example ).  This release includes several new features, including:

- Iray Path Tracer integration for advanced rendering and screenshot capability
- New Smart Masks for creating and using your own mesh-adaptive mask presets
- New Clone tool, non destructive, for copying and pasting parts of texture
- New Smudge tool, non destructive, for blending and spreading colors
- Ability to chain and composite substances
- New content in the shelf: alphas, tools, materials, smart materials, and more
- New interface with reworked colors, icons, and parameter organization
- New Orthographic view mode and Perspective Field of View control
- New Fullscreen mode with interface toggling
- Full support for the Specular/Glossiness PBR workflow
- Scripting I/O
- Non-PBR shader and template
- Full support of height & normal workflow

There is also a release trailer for Substance Painter 2

For more details, click here.

GameDev News

blog comments powered by Disqus

Month List

Popular Comments