Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

19. May 2016

 

At Google.io, along with the announcement of VR Mode in Android N, Google announces a preview release of Android Studio 2.2.  Android Studio is a free IDE for Android development based off the popular IntelliJ Java IDE.

 

Details of the new release:

Android Studio is the quickest way to get up and running with Android N and all our new platform features. Today at Google I/O, we previewed Android Studio 2.2 - another big update to the IDE designed to help you code faster with smart new tooling features built in. One of the headline features is our rewritten layout designer with the new constraint layout. In addition to helping you get out of XML to do your layouts visually, the new tools help you easily design for Android’s many great devices. Once you’re happy with a layout, we do all the hard work to automatically calculate constraints for you, so your UIs will resize automatically on different screen sizes . Here’s an overview of more of what’s new in 2.2 Preview (we’ll be diving into more detail this update at 10AM PT tomorrow in “What’s new in Android Development Tools”, livestreamed from Google I/O):

  • Speed: New layout designer and constraint layout, Espresso test recording and even faster builds
  • Smarts: APK analyzer, Layout inspector, expanded Android code analysis and IntelliJ 2016.1
  • Platform Support: Enhanced Jack compiler / Java 8 support, Expanded C++ support with CMake and NDK-Build, Firebase support and enhanced accessibility

GameDev News

18. November 2015

 

As part of Google’s ongoing developer conference Fun Propulsion Labs, a Google team dedicated to gaming, released the open source game Zooshi to showcase a number of just announced or updated game technologies.  Zooshy is a 3D game that runs on Android, Android TV, Windows, OSX and Linux and is currently available for free on the Google Play Store.  The source code is available on github under the Apache v2 open source license.

The technologies showcased by Zooshi include:

  • Motive – animation system
  • CORGI – an entity/component system
  • FlatUI – immediate mode lightweight GUI
  • Scene Lab – in game level editing
  • Breadboard – node based scripting
  • FPLBase – cross platform API for low level access

 

Now that’s a number of new technologies I currently know nothing about and will have to jump into in more detail shortly.

 

More details about the release are available here.

GameDev News ,

20. July 2015

 

In this “A Closer Look at”, we will be taking an in-depth look at the Stencyl game engine.  The Closer Look At series is a cross between a preview, review and getting started guide and should help you determine if a game engine is right for you.  Stencyl is a cross platform 2D game engine with tools that run on Windows, Mac and Linux and capable of targeting all of those, plus Flash, Android and iOS.  Stencyl is free to use for the Flash target with additional platforms coming with a fee.  Stencyl provides a high level Lego block type programming experience but coders need not fear, you can drop into code easily if you want.  Amazingly enough, you may find you do not actually want to!

 

There is an HD video version of this guide available here.

 image

 

The Editor

 

Stencyl is a relatively self contained providing almost all of the tooling you need in a single editor.  When you first launch Stencyl this is your initial view of the editor:

image

 

It comes with a sample game included and one nice feature of Stencyl is the ability to seamlessly download additional assets from their website including additional examples and editor extensions.  Once you’ve actually created a project you’ve got even better integration with their online store ( misnomer, as everything currently is free ).

 

The Dashboard is the home page of your game.  The game itself is broken up into Scenes and scenes are composed of Actors, Backgrounds, Fonts, Sounds and Tilesets.  Created resources are available across all scenes. 

 

image

 

Scene/Level Editor

Loading  a Scene brings up the scene editor

image

 

The editor has several modes available across the top (Scene, Behaviors, Events, Physics, Atlases and Properties).  The Scene editor (shown above) enables you to paint scenes using tiles for a tileset, or to place your various actors within the world.  The editor supports multiple layers of tiles with various blending modes available.  The tile placement experience is very smooth with functionality you would expect like snapping, flood filling (painting an entire region with a single tile) and grids. There is also support for defining regions, placing physics joints, adding rows and columns of tiles all at once and more.  The ability to paint with multiple textures is also present:

s1

 

The Tilesets themselves are created as a Tileset resource at the dashboard:

image

image

image

 

You can then edit each tile in the tileset:

image

Three things can be set for each tile, a custom piece of metadata that can be access by code (perhaps a text description of the tile), the collision shape for the bounds of the triangle, using either a default shape or defining your own, and finally the frames of animation for animated tiles.  Should you require more precise collisions than the default shapes, you can define your own Collision Bounds:

image

 

The Create A Polygon tool is a bit clunky but gets the job done:

image

 

Back to the Scene editor, you will notice the next two tabs after Scene are Behaviors and Events:

image

These are basically the way you “program” your Stencyl game and we will revisit both shortly.  Just remember them for now.  Physics enables you to configure some global level physics properties for you scene:

image

 

Atlases are akin to spritesheets in other game engines.  It enables you to bundle like minded resources into a single file to improve performance.  This is more of an implementation detail, so we wont cover it in depth.

image

 

Finally Properties enables you to set some critical details of the scene that you otherwise set during creation.

image

 

Basically Scene is your game level and Stencyl provides a complete and comprehensive level editor with most of the required tools for placement, physics, etc.  You will notice at this point that Stencyl is highly configured for creation of 2D tile based games and if your game doesn’t fit this description, Stencyl becomes less and less useful.

 

Actors

 

Next let’s take a look at the Actors interface.  An Actor is basically any game entity that isn’t a tile.  So your main character, your main menu, a high score widget and enemy sprites may all be actors.  As you will see, the interface for actors is remarkably similar to Scenes:

image

 

An actor can contain multiple animations, each of which is composed of frames of animation.  You can define as many animations as you desire and each animation you can control the order of frames and the duration that each one lasts.  Animation frames use the same interface as loading a tileset.

 

You may notice across the top there are several editor options for Actors available as well.

image

 

Appearance is the editor you see in the above screenshot were you specify the animations of your Actor.  Behaviors and Events are the programming interface and once again, we will cover those shortly.  Collision enables you to define the collision properties of your Actor:

image

One unfortunately missing feature is the ability to define a collision shape per frame of your animation.  This means if the collision volume changes massively as your Actor is animated you will either need to split it into separate animation groups or settle for less than accurate collisions.  Hopefully this functionality is added in the future.

 

The Physics tab enables you to set the Physics properties of your actor:

image

 

Note the various sub settings you can set:

image

 

This is perhaps the most accessible and least confusing physics integration I have ever seen in a 2D game engine.  Physics properties are often cryptic and simply figuring out what a particular setting does is an exercise in frustration, especially for new game developers.  So bravo for making a complicated subject dead simple.

 

Finally there is the properties section:

image

 

Which contains the button for launching the Collision Group interface:

image

 

Collision groups are handy for determining how various groups interface with each other.  For example, a Bullet may collide with Actors, but not other bullets.  One nice feature with Stencyl is the link to help on each topic:

image

 

If the purpose of an editor isn’t obvious to you, you can click the How do ____ work button and be brought to a well written help web page.  This should keep newer developers from getting overly lost and encourages exploration.

 

Programming in Stencyl

 

As I mentioned earlier in both the Scene and Actor sections, programming is done via Behaviors and Events in Stencyl.  Behaviors can be added to both scenes and actors and each is a distinct thing.  The same is true for events.  If you are coming from another game engine or programming language, Behaviors are analogous to methods or functions and can be re-used ( a scene behavior can be used on several scenes, while an actor behavior can be used across multiple actors ).  There is also a variable type named an Attribute, which can be though of the same way you would consider a property.  If that made no sense think of it this way… a Behavior makes a scene or actor do stuff, while an Event tells a scene or actor that stuff happened while an attribute stores information about stuff.

 

Programming itself can be accomplished either by using predefined behaviors or by defining your own using a building block type programming interface.  Let’s take a look. 

 

We can create a simple actor like this one:

image

 

We can easily add an instance to our Scene using the Add to Scene button, or by going to the Actors panel in the Scene editor:

image

 

Now let’s add some logic to our Actor.  In the Dashboard, select your Actor and choose edit.  Now select Behaviors and you will be greeted with:

 

image

 

Clicking it allows you to select a pre-created Behavior or one you have already defined for your game:

image

 

There are several pre-defined behaviors and more you can download from StencylForge.  Let’s add a simple behavior to our Actor.  We simply want to move left and right automatically.  Select Motion->Back and Forth Horizontally

image

 

You can then set configurable attributes of that behavior:

image

 

Now run your game by hitting Test Game and your actor will move left and right 100 pixels:

s2

 

So you can add functionality to an Actor as simply as adding a behavior to it and an instance of that actor in your Scene.  Obviously in this case our animation isn’t ideal as it only makes sense when traveling to the left.

 

Let’s now flip the character if he’s going right.  This means our first programming experience.  We can do this either in the scene or in the character itself, in this case we do it in the Scene.  Edit the Scene, select Events then add a new Event.

image

 

First click Add Event, then Basics->When Updating.  These are the three lifecycle stages.  This will create a brick named always that we can then drop other bricks in to program the behavior of our game.  Create the following structure:

image

 

This brick will be called every frame.  We check to see if the user is going left (negative) or right(positive), in the case of positive, we scale –100% in width, which is the same as flipping.  Now running the code we see:

s3

 

You can also bundle together functionality it re-usable components using virtually the same manner with Behaviors

image

 

Now one of the coolest features of Stencyl, all this visual programming you’ve been doing… it’s ultimately just a code generator using the Haxe programming language.  Click Preview Code and you can see the code generated behind the scenes:

image

You can even edit the code using an external editor like Flash Develop or IntelliJ, the process of which I describe here.  This turns Stencyl into a rapid development Haxe/OpenFL code generator and you can define the remaining game logic using a traditional programming interface if you prefer.  You can also extend the Stencyl editor itself (using Java), as well as create new blocks completely, using Haxe.    It’s a good thing this functionality exists too, as it helps make up for one of Stencyl’s biggest flaws… there is no debugger.  You can do Print style output to the log which can be viewed in the Log Viewer, but there is very little debugging functionality (breakpoints, watches, etc ) built in.  You can however debug your code in an external IDE if you are comfortable working in the Haxe language.

 

Documentation and Community

 

One of the impressive features of Stencyl is it’s documentation.  Almost none of it is local however, so if you do not have an internet connection you are in trouble.  The Stencylpedia is your starting point for help.

image

 

There is also a class reference for Haxe programmers, as well as guides for programming extensions and more.  The quality of the documentation is quite solid, especially the more entry level materials. 

 

In addition to the Stencylpedia there is StencylForge, a built-in (free) store for downloading behaviors, actors, scenes, sounds and even complete games.

image 

 

There are a few existing books on Stencyl including Stencyl Essentials and Learning Stencyl 3.1.

 

There is also an active community forum available here.

 

 

The Flaws

image

Of course no tool is perfect and there are a few negatives to Stencyl.  The first and biggest limitation is it is limited mostly to 2D games with a tileset approach to level design.  If you aren’t creating this style of game Stencyl is probably not the right tool for you.  Perhaps the most glaring flaw with Stencyl is a memory leak that seems to be present.  I often received a message “You have reached 90% of memory usage, please restart”, sometimes quite almost right after loading Stencyl, other times after several hours had passed (it can be fixed though).  There have been a few other times where I wasn’t getting the behavior I expected and had to restart to fix things.  Saving changes is also quite slow and seems to be an all or nothing prospect.  Finally the debugging support is extremely weak.

 

The Verdict

I came into Stencyl expecting one thing and discovered something much different.  I had fairly low expectations, a simple click and build type experience that while accessible and easy to use, it would ultimately prove to be quite limited.  I was wrong.  Stencyl is certainly accessible, and provides a simple drag and drop visual style of programming experience.  What I was shocked at was the flexibility, wealth of tools included and advanced coding options.  Stencyl is not for everyone; if your game isn’t 2D tile/scene based for example.  However if you are just starting out or even if you are an experienced developer creating a relatively simple game, Stencyl might be the perfect tool for you.

 

In fact, Stencyl maybe just maybe became my primary recommendation for new developers looking to get started in game development.  It’s an approachable well documented game engine that has a long runway to explore as your skills improve.

 

The Video

Programming , , ,

14. December 2014

 

So I recently did a complete nuke of my primary daily use Android phone, it’s just one of those things you have to do over time as it gets slower, hotter and your battery life gets worse.  However, the next time I went to debug on Android, ADB couldn’t find it.

 

This is nothing new of course, on Windows you need to do a bit of a device driver dance sometime to get your phone to work with ADB.  This time however it was different.

 

Plugged in my device, waited a few seconds and:

image

 

Hmmm, that’s not good.  USB device not recognized is certainly a common enough answer, let’s just go install the Google Android USB driver.

image

 

Device Descriptor Request Failed… that’s a new one…

 

Ok, lets Update the driver and point to the Google driver…

 

image

 

image

 

Well sh…. er, that didn’t work.  Well it previously worked, maybe I have an old driver kicking around that needs to be purged.  I download the utility USBDeview from here.

 

image

 

I certainly have some old or questionable drivers kicking around.  I am going to clean house in that regard, the nice thing about USB is you can just install the driver again next time you plug the device in, so very little risk here.  Purged the old drivers, scan for hardware changes… nothing.

 

 

Hmmmm…  Google indicates it might be a Windows 8.1 problem due to a driver change they made…

 

Ok, over to my MacBook, let’s see what happens.

 

Plug in the USB cable… BOOM, instant shutdown.

 

WTF?

 

Ok, this is weird.  Let me try a different USB cable.

 

Instant shutdown.

 

Hmmmm…  I’m basically getting the Mac equivalent of a blue screen of death each time I even plug this device in.  Let’s try a different port…

 

Hey, that worked.  Cool.  Try out “./adb devices”  Nothing.

 

Hmmmm, this is confusing as hell.  Doesn’t find the device on Windows 8.1 at all, even worse Crashes if I plug in to the right port of my MacBook Air, it “works” if I plug it into the Left USB port, but for charging only.  The device simply isn’t found.

 

So, at this point I borrow my wife’s identical HTC One phone and plug it in… HTC Manager works, either port, adb devices shows the device.

 

At this point I can only assume something is wrong with my device…  perhaps the connector is broken, but then I can’t explain why it charges successfully, but data doesn’t work.  Generally that is a cable or driver situation, but when I can get an identical phone to work and detect just fine, I am absolutely puzzled at this point.  The two phones have exactly the same versions… I just did a fresh factory install so I am frankly at wits end.

 

If any of you have experienced this before or have ideas, please let me know!  Otherwise I think I’m going to be on the market for a new phone soon.

Totally Off Topic

30. October 2013

 

In the previous tutorial we looked at handling touch and gesture events.  These days, most mobile devices have very accurate motion detection capabilities, which LibGDX fully supports.  In this example we will look at how to handle motion as well as detect if a device supports certain functionality and to detect which way the device is oriented.

 

This project revolves around a single code example, but there are some configuration steps you need to be aware of.

 

First off, in order to tell LibGDX that you want to use the compass and accelerometer, you need to pass that as part of the configuration in your Android MainActivity.  In the android project locate MainActivity.java and edit it accordingly:

package com.gamefromscratch;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;

import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;

public class MainActivity extends AndroidApplication {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

       

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

        cfg.useGL20 = true;

        cfg.useAccelerometer = true;

        cfg.useCompass = true;

       

        initialize(new MotionDemo(), cfg);

    }

}

 

The meaningful lines are

cfg.useAccelerometer = true;

and

cfg.useCompass = true;

 

These lines tell LibGDX to enable both.

Next we need to make a couple of changes to your Android manifest.  This is a configuration file of sorts that tells the Android operating system how your application performs and what permissions it requires to run.  You could literally write an entire book about dealing with Android manifests, so if you want more information read here.  The manifest is located at the root of your Android project and is called AndroidManifest.xml.  There are a couple ways you can edit it.  Simply right click AndroidManifest.xml and select Open With->.

ManifestEditAs

 

I personally prefer to simply edit using the Text Editor, but if you want a more guided experience, you can select Android Manifest Editor, which brings up this window:

Java motion android AndroidManifest xml Eclipse Users Mike Dropbox Workspace

This is basically a GUI layer over top of the Android manifest.  Using the tabs across the bottom you can switch between the different categories and a corresponding form will appear.  If you click AndroidManifest.xml it will bring up a text view of the manifest.  Use whichever interface you prefer, it makes no difference in the end.

There are two changes we want to make to the manifest.  First we want the device to support rotation, so if the user rotates their device, the application rotates accordingly.  This is done by setting the property android:screenOrientation to fullsensor.  Next we want to grant the permission android.permission.VIBRATE.  If you do not add this permission calling a vibrate call will cause your application to crash!

 

Here is how my manifest looks with changes made:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.gamefromscratch"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.VIBRATE"/>

    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name" >

        <activity

            android:name=".MainActivity"

            android:label="@string/app_name"

            android:screenOrientation="fullSensor"

            android:configChanges="keyboard|keyboardHidden|orientation|screenSize">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

</manifest>

The changes have been bolded above.  You want to be careful when you request additional permissions as they will be shown when the user installs your application.  Too many permissions and people start getting scared of your application.  Of course, if you need to do something that requires a permission there isn’t much you can do!  As to the screenOrientation value, this tells Android which direction to create your application as.  There are a number of options, Landscape and Portrait being two of the most common.  fullSensor basically means all directions supported.  This means you can rotate the device 360 degrees and it will be rotated accordingly.  On the other hand, if you select “user”, you cannot rotate the device 180 degrees, meaning you cannot use it upside down.  You can read more about the available properties in the link I provided earlier.

There is one last important thing to be aware of before moving on.  Your android project will actually have two AndroidManifest.xml files, one in the root directory another in the bin subfolder.  Be certain to use the one in the root directory, as the other one will be copied over!

 

Ok, now that we are fully configured, let’s jump into the code sample:

package com.gamefromscratch;

import com.badlogic.gdx.ApplicationListener;

import com.badlogic.gdx.Gdx;

import com.badlogic.gdx.Input.Orientation;

import com.badlogic.gdx.Input.Peripheral;

import com.badlogic.gdx.graphics.Color;

import com.badlogic.gdx.graphics.GL10;

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

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

public class MotionDemo implements ApplicationListener {

private SpriteBatch batch;

private BitmapFont font;

private String message = "Do something already!";

private float highestY = 0.0f;

@Override

public void create() {

   batch = new SpriteBatch();

   font = new BitmapFont(Gdx.files.internal("data/arial-15.fnt"),false);

   font.setColor(Color.RED);

}

@Override

public void dispose() {

   batch.dispose();

   font.dispose();

}

@Override

public void render() {

   int w = Gdx.graphics.getWidth();

   int h = Gdx.graphics.getHeight();

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

   Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

   batch.begin();

   int deviceAngle = Gdx.input.getRotation();

   Orientation orientation = Gdx.input.getNativeOrientation();

   float accelY = Gdx.input.getAccelerometerY();

   if(accelY > highestY)

      highestY = accelY;

   message = "Device rotated to:" + Integer.toString(deviceAngle) + " degrees\n";

   message += "Device orientation is ";

   switch(orientation){

      case Landscape:

         message += " landscape.\n";

         break;

      case Portrait:

         message += " portrait. \n";

         break;

      default:

         message += " complete crap!\n";

         break;

   }

 

   message += "Device Resolution: " + Integer.toString(w) + "," + Integer.toString(h) + "\n";

   message += "Y axis accel: " + Float.toString(accelY) + " \n";

   message += "Highest Y value: " + Float.toString(highestY) + " \n";

   if(Gdx.input.isPeripheralAvailable(Peripheral.Vibrator)){

      if(accelY > 7){

         Gdx.input.vibrate(100);

      }

   }

   if(Gdx.input.isPeripheralAvailable(Peripheral.Compass)){

      message += "Azmuth:" + Float.toString(Gdx.input.getAzimuth()) + "\n";

      message += "Pitch:" + Float.toString(Gdx.input.getPitch()) + "\n";

      message += "Roll:" + Float.toString(Gdx.input.getRoll()) + "\n";

   }

   else{

      message += "No compass available\n";

   }

   font.drawMultiLine(batch, message, 0, h);

   batch.end();

}

@Override

public void resize(int width, int height) {

   batch.dispose();

   batch = new SpriteBatch();

   String resolution = Integer.toString(width) + "," + Integer.toString(height);

   Gdx.app.log("MJF", "Resolution changed " + resolution);

}

@Override

public void pause() {

}

@Override

public void resume() {

}

 

}

 

When you run this program on a device, you should see:

Appresults

 

As you move the device, the various values will update.  If you raise your phone to be within about 30 degrees of completely upright it will vibrate.  Of course, this assumes that your device supports all these sensors that is!

 

The code itself is actually remarkably straight forward, LibGDX makes working with motion sensors remarkably easy, its just actually understanding the returned values that things get a bit more complicated.  The vast majority of the logic is in the render() method.  First we get the angle the device is rotated in.  This value is in degrees with 0 being straight in front of you parallel to your face.  One important thing to realize is this value will always have 0 as up, regardless to if you are in portrait or landscape mode.  This is something LibGDX does to make things easier for you, but is different behaviour than the Android norm.

Next we get the orientation of the device.  Orientation can be either landscape or portrait (wide screen vs tall screen).  Next we check the value of the accelerometer along the Y access using getAccelerometerY().  You can also check the accelerometer for movement in the X and Z axis using getAcceleromterX() and getAcceleromterZ() respectively.  Once again, LibGDX standardizes the axis directions, regardless to the devices orientation.  Speaking of which, Y is up.  The means if you hold your phone straight in front of you parallel to your face, the Y axis is what you would traditionally think of as up and down.  The Z axis would be in front of you, so if you made a push or pulling motion, this would be along the Z axis.  The X axis would track movements to the left and right.

So then, what exactly are the values returned by the accelerometer?  Well this part gets a bit confusing, as it measures both speed and position in a way.  If you hold your phone straight out in front of you, with the screen parallel to your face, it will return a value of 9.8.  That number should look familiar to you, it’s the speed a body falls due to gravity in meters per second.  Therefore if your phone is stationary and upright, its 9.8.  If you move the phone up parallel to your body, the value will rise above 9.8, the amount depends on how fast your are moving the phone.  Moving down on the other hand will return a value below 9.8.  If you put the phone down flat on a desk it will instead return 0. Flipping the phone upside down will instead return -9.8 if held stationary.  Obviously the same occurs along the X and Z axis, but instead that would indication motion left and right or in and out instead of up and down.

Ok, back to our code.  We check to see if the current accelY value is the highest and if it is, we record it to display.  Next we check what value the orientation returned and display the appropriate message.  We dump some information we’ve gathered out to be displayed on screen.  Next we make the very important call Gdx.input.isPeripheralAvailable().  This will return true if the users device supports the requested functionality.  First we check to see if the phone supports vibrating and if it does, we check if the phone is over 7.  Remember the value 9.8 represents straight up and down, so if its 7 or higher its within about 35 degrees of vertical.  If it is, we vibrate by calling vibrate(), the value passed is the number of milliseconds to vibrate for.

Next we check to see if the device has a compass.  If it does, you can check the position of the device relative to polar north.  Here are the descriptions of each value from Google’s documentation:

Azimuth, rotation around the Z axis (0<=azimuth<360). 0 = North, 90 = East, 180 = South, 270 = West
Pitch, rotation around X axis (-180<=pitch<=180), with positive values when the z-axis moves toward the y-axis.
Roll, rotation around Y axis (-90<=roll<=90), with positive values when the z-axis moves toward the x-axis.

You can read more about it here.

Finally we draw the message we have been composing on screen.

There is only one other very important thing to notice in this example:

public void resize(int width, int height) {

   batch.dispose();

   batch = new SpriteBatch();

   String resolution = Integer.toString(width) + "," + Integer.toString(height);

   Gdx.app.log("MJF", "Resolution changed " + resolution);

}

 

In the resize() method we dispose of and recreate our SpriteBatch().  This is because when you change the orientation of the devices from landscape to portrait or vice versa you invalidate the sprite batch, it is now the wrong size for your device.  Therefore in the resize() call, we recreate the SpriteBatch structure.

Programming , , ,

Month List

Popular Comments