Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


Home > >

6. May 2015

 

Title kinda says it all.  Version 1.6 of the popular, cross platform Java based game library LibGDX was just released.  The changelog from the release:

[1.6.0]
- API Change: GlyphLayout xAdvances now have an additional entry at the beginning. This was required to implement tighter text bounds. #3034
- API Change: Label#getTextBounds changed to getGlyphLayout. This exposes all the runs, not just the width and height.
- In the 2D ParticleEditor, all chart points can be dragged at once by holding ctrl. They can be dragged proportionally by holding ctrl-shift.
- Added Merge button to the 2D ParticleEditor, for merging a loaded particle effect file with the currently open particle effect.
- Added ability to retrieve method annotations to reflection api
- Added PixmapPacker.updateTextureRegions() method.
- Added ability to pack "anonymous" pixmaps into PixmapPacker, which will appear in the generated texture but not a generated or updated TextureAtlas
- Added PixmapPacker.packDirectToTexture() methods.
- API Change: PixmapPacker.generateTextureAtlas(...) now returns an atlas which can be updated with subsequent calls to PixmapPacker.updateTextureAtlas(...)
- API Change: FreeTypeFontGenerator.generateFont(...) now works with a user-provided PixmapPacker.
- Added DirectionalLightsAttribute, PointLightsAttribute and SpotLightsAttribute, removed Environment#directionalLights/pointLights/spotLights, added Environment#remove, lights are now just like any other attribute. See also https://github.com/libgdx/libgdx/wiki/Material-and-environment#lights
- API Change: BitmapFont metrics now respect padding. #3074
- Update bullet wrapper to v2.83
- Added AnimatedTiledMapTile.getFrameTiles() method


For the full release details check here.

 

If you want to help support LibGDX consider purchasing a RoboVM license while they are on sale for 50% off!

 

Of course don’t forget that GameFromScratch has a complete set of text based and video based LibGDX tutorials to get you started.  Oh and if you want to help support GameFromScratch making more tutorials like these, that would be cool too!  

 

In terms of changes in this update, only the text API changes should have any effect on the tutorials available on this site.  For details about upgrading your libGDX project, click here.

blog comments powered by Disqus

Month List

Popular Comments

Paradox Game Engine Tutorial Part 5: Controlling Scenes Programmatically
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


24. August 2015

 

In this tutorial in our ongoing Paradox3d Game Engine tutorial series  we are going to look at controlling a Paradox game engine scene programmatically.  This includes accessing entities created in the editor, creating new entities, loading assets and more.  It should give you a better idea of the relationship between the scene and your code.

 

As always there is an HD video available here.

 

Creating a Simple Script

 

As part of this process we are going to be attaching a script to a scene entity programmatically.  First we need that script to be created.  We covered this process back in this tutorial if you need a brush up.  We are going to create an extremely simple script named BackAndForth.cs, which simply moves the entity back and forth along the x-axis in our scene.  Here is the contents of the script:

using System;
using SiliconStudio.Paradox.Engine;

namespace SceneSelect
{
    public class BackAndForth : SyncScript
    {
        private float currentX = 0f;
        private const float MAX_X = 5f;
        bool goRight = false;
        public override void Update()
        {
            if (Game.IsRunning)
            {
                if (goRight)
                {
                    currentX += 0.1f; 
                }
                else
                {
                    currentX -= 0.1f;
                }

                if (Math.Abs(currentX) > MAX_X)
                    goRight = !goRight;

                Entity.Transform.Position.X = currentX;
            }
        }
    }
}

 

If you've gone through the previous tutorials, this script should require no explanation.  We simply needed an example script that we can use later on.  This one merely moves the attached entity back and forth across the X axis until it reaches + or – MAX_X.

 

Now what we want to do is attach this script to the Sphere entity created in the default scene.  This means we are going to need to be able to locate an entity in code, and perhaps more importantly, we need some code to run.  We could create our own custom Game class like we did last tutorial, but this time we are going to do things a bit different.  Instead we are going to create a StartupScript.

 

First we new to create a new empty Entity in our scene to attach the script component to.  I called mine Config:

image


Next we create the Script we are going to attach.  Start with the following extremely simple script, Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SiliconStudio.Paradox.Engine;
using SiliconStudio.Paradox.Rendering;

namespace SceneSelect
{
    public class Startup : StartupScript
    {
        public override void Start()
        {
            base.Start();
        }
    }
}

 

A StartupScript is a type of script that is loaded, as you may guess, on start. Unlike the Sync/AsyncScript classes we used earlier, there is no per frame update callback occurring.  This makes StartupScripts very useful for exactly this type of configuration tasks.

 

Now that we have our script, let’s attach it to our entity:

image

 

Finding an Entity using Code

 

First we are going to look at the process of locating an entity creating in Paradox Studio using code.  The following code will select the Sphere from the default scene using LINQ.

    var sphere = (from entities in this.SceneSystem.SceneInstance
                    where entities.Components.ContainsKey(ModelComponent.Key)
                    select entities).FirstOrDefault();

You can get the currently active scene using SceneSystem.SceneInstance, which contains a simple collection of Entity objects.  We then filter by entities with Components of type ModelComponent.  There are many ways we could have accomplished the same thing.  This query actually returns all entities in the scene that have a ModelComponent attached, which is overkill.  We could also select by the entities Name attribute:

image

Using the code:

    var sphere = (from entities in this.SceneSystem.SceneInstance
                    where entities.Name == "Sphere" select entities).
                                         FirstOrDefault();
    if (sphere == null) return;

 

Attaching a Script Component Programmatically

 

    ScriptComponent scriptComponent = new ScriptComponent();
    scriptComponent.Scripts.Add(new BackAndForth());
    sphere.Components.Add<ScriptComponent>(ScriptComponent.Key, scriptComponent);

 

Now that we have a reference to our sphere Entity, adding a new component is pretty simple.  Remember that the ScriptComponent is a collection of Script objects.  Simply Add() an instance of our newly created BackAndForth script.  Finally attach a ScriptComponent to our Sphere’s Components collection. 

 

When we run this code we will see:

BackAndForth

 

Creating a new Entity

 

We can also create another entity programmatically.

    Entity entity = new Entity(position: new SiliconStudio.Core.Mathematics.
                    Vector3(0, 0, 1), name: "MyEntity");
    var model = (SiliconStudio.Paradox.Rendering.Model)Asset.Get(typeof(
                SiliconStudio.Paradox.Rendering.Model), "Sphere");
    ModelComponent modelComponent = new ModelComponent(model);
    entity.Add<ModelComponent>(ModelComponent.Key, modelComponent);

 

Here we create a new entity with the name “MyEntity” and set it’s location to (0,0,1).  Next we get a reference to the ProceduralModel created in Paradox Studio, with a call to Asset.Get() specifying the type and URL ( you can see the Url value by mouse overing the asset in the Asset Viewer panel in Studio).  Now we create a new ModelComponent using this Model.  (Keep in mind, changes to it the Model will affect all instances, as I will show momentarily).  Finally we add the ModelComponent to the entity.

Finally we add our newly created entity to the scene using:

    SceneSystem.SceneInstance.Scene.AddChild(entity);

Now when we run the code:

BackAndForth2

 

As I mentioned earlier, changes to the Model will affect all instances.  For example, let’s say we create a new Material in the editor and apply it to the model.

image

Now the code:

    Entity entity = new Entity(position: new SiliconStudio.Core.Mathematics.
                    Vector3(0, 0, 1), name: "MyEntity");
    var model = (SiliconStudio.Paradox.Rendering.Model)Asset.Get(typeof(
                SiliconStudio.Paradox.Rendering.Model), "Sphere");
    var material = Asset.Load<Material>("MyMaterial");
    model.Materials.Clear();
    model.Materials.Add(new MaterialInstance(material));
    ModelComponent modelComponent = new ModelComponent(model);
    entity.Add<ModelComponent>(ModelComponent.Key, modelComponent);

And the (non-animated) result:

image

As you can see, the material on all of the Spheres has been replaced.  If you do not want this behaviour, you will have to create a new Model, either in Studio or programmatically.

 

New Entity using Clone

 

We could have also created our entity using the Clone() method of our existing Entity.

    var anotherSphere = sphere.Clone();
    sphere.Transform.Position.Z = 1f;
    SceneSystem.SceneInstance.Scene.AddChild(anotherSphere);

Keep in mind, the close will get all of the components of the cloned Entity, so if we clone after we add the ScriptComponent, it will also have the script attached.

 

 

Our complete source example:

using System.Linq;
using SiliconStudio.Paradox.Engine;
using SiliconStudio.Paradox.Rendering;

namespace SceneSelect
{
    public class Startup : StartupScript
    {
        public override void Start()
        {
            base.Start();

            var sphere = (from entities in this.SceneSystem.SceneInstance
                         where entities.Components.ContainsKey(ModelComponent.
                                                               Key)
                         select entities).FirstOrDefault();
            //var sphere = (from entities in this.scenesystem.sceneinstance
            //              where entities.name == "sphere" select entities).
                                                 firstordefault();
            //if (sphere == null) return;

            ScriptComponent scriptComponent = new ScriptComponent();
            scriptComponent.Scripts.Add(new BackAndForth());
            sphere.Components.Add<ScriptComponent>(ScriptComponent.Key, 
                                                   scriptComponent);


            Entity entity = new Entity(position: new SiliconStudio.Core.
                            Mathematics.Vector3(0, 0, 1), name: "MyEntity");
            var model = (SiliconStudio.Paradox.Rendering.Model)Asset.Get(typeof(
                        SiliconStudio.Paradox.Rendering.Model), "Sphere");
            var material = Asset.Load<Material>("MyMaterial");
            model.Materials.Clear();
            model.Materials.Add(new MaterialInstance(material));
            ModelComponent modelComponent = new ModelComponent(model);
            entity.Add<ModelComponent>(ModelComponent.Key, modelComponent);

            SceneSystem.SceneInstance.Scene.AddChild(entity);

            var anotherSphere = sphere.Clone();
            sphere.Transform.Position.Z = 1f;
            SceneSystem.SceneInstance.Scene.AddChild(anotherSphere);
        }
    }
}

And, running:

BackAndForth3

 

The Video

 

Programming , , ,

blog comments powered by Disqus

Month List

Popular Comments