A simple Ip-TV viewer for iOS

Adding video streaming functionality within an App is becoming more and more important, health care organizations (telemedicine), hospitality (marketing), education (training)  are just a few industries that have adopted real time media to conduct their business.

There are several real time protocols to handle video streaming connections like RTMP, HLS, etc. Many popular “free” internet tv channels are delivered using protocols based on HLS through m3u8 playlists.

In this project I decided to create a sample App that shows how to play m3u8 playlists, the app is based on the ijkmedia framework which in turn is based on the ffmpeg project, which is a set of open source libraries that can handle all sort of media formats and protocols.

Video of the app.

 

The project consists of 3 main views:

  1. The Player view controler.
    • Contains the ijkmedia player
    • Provides also additional controls for tagging a favorite, set the thumbnail and description.
  2. A search panel.
    • Links are obtained by doing web scraping to a set of pages.
  3. A favorites container.
    • Presents the tagged favorite m3u8 links.
    • Favorites can be re-arranged by dragging them.

iacoplayer2

The UI part also makes use of core animation and  swipe gestures to activate the search, favorites and drawer views.

 

Main Components:

iacoplayer1

  • Video Manager.
    • Handles the user favorites and search requests.
    • The search results and favorites  data are stored using core data.
    • Thumbnails are stored as PNGs in the app sandbox.
  • Web scraper.
    • Searches for m3u8 playlists in the provided web page link using regexp.
  • ijkmedia/ffmpes.
    • Open source framework  for handling the streaming and playback session.

 

The app source code and build instructions are in the following github repository:

https://github.com/iaco79/IaCOPlayer.

 

 

 

 

 

 

 

 

 

 

 

 

 

Advertisements
Tagged , , ,

Implementing mixed reality with the Samsung Gear VR

The Gear VR as it stands now is one of the most affordable options to experience immersive Virtual Reality. If you own a compatible device then the  Gear VR is a must have.

In this blog I describe a Mixed Reality Android project that  I created to start learning AR/VR development for the Gear VR.

Video of the demo running in development mode.

 

Mixed reality is combining  AR + VR, in this project the AR part consist in displaying animated 3d models on top of tracked images. The VR part consist in proyecting the see-through camera + AR images so we can see the outside when wearing the Gear VR headset.

AR_IMG1

Project overview.

The following image shows the VR Scene setup.

AR_IMG3

In this project I’m working with the GearVR Framework (GearVRf), which is an Open Source framework to create apps for the Samsung Gear VR headset. I highly recommend have a look to the sample Apps, most of the questions regarding how to implement certain functionality with GearVRf are covered in the sample Apps code.

 

I took the vuforia-sample as a base for this project and then added the animated 3d models using .dae files that I exported with blender. As you can tell, the demo makes use of the Vuforia mobile sdk (vuforia-sdk-android-5-5-9) to implement the markerless AR functionality

There are several options to implement AR in mobile;for this project I wanted to track images and then display a 3d model on top of the tracked image. Vuforia already provides out of the box functionality to tag, detect images and track the generated homography; it also provides a free license for personal projects.

OpenCV is also an option, but perhaps  for another project since it will take more effort having to implement a bag-of-words model, and multi-class classification algorithm  and so on (something I’ve been learning from several Computer Vision courses in Coursera).

Required tools to build the project:

In order to build the source code you will need:

 

Loading the 3d models.

I got two animated 3d max models from turbosquid, before loading them using the GearVR framework I first had to import them to blender to align their orientations and then export them to collada format (.dae).

AR_IMG4

The GearVRf can load models from several 3d formats, internally GearVRf wraps the Assimp library, this makes loading 3d models and animations really easy.

Loading the t-rex model:


GVRModelSceneObject rexModel = gvrContext.loadModel("Tyrannosaurus.dae");

 Starting the animation:


List<GVRAnimation> animations = mModel.getAnimations();

if (animations.size() >= 1) {

mAnimation = animations.get(0); //get the first animation
mAnimation.setRepeatMode(GVRRepeatMode.REPEATED).setRepeatCount(-1); //loop the animation
mAnimation.start(mAnimationEngine); //start the animation

}

 

Tracking images with Vuforia.

 

The Vuforia Developer Portal allows you to upload the images you want to track, the online tool will generate a database which is a set of files that contain the feature descriptors of the images,  the Vuforia mobile SDK then utilizes the database file data to detect and classify the tracked  images.

AR_IMG5

The generated database files are located in the App assets folder.

AR_IMG6

Each 3D model must be associated with  the corresponding TrackedImage in the vuforia database, for this I created the class TrackedModel that holds the 3d model and the Image Id; then on each frame it updates the  3d model transform using the transformation matrix returned by Vuforia SDK during the tracking process.


public class TrackedModel extends GVRSceneObject {
...
...
private GVRModelSceneObject mModel; //the animated 3d model
private int mTrackingId; //the TrackedImage
 
//sets the vuforia transform matrix and scale
public void setTrackedPose(float[] matrix, float scale);
...
//updates the Model transform using the most recent vuforia transform and scale
private void updateTrackedPose( );

AR_IMG7

Rendering the camera see-through.

In order to render the camera frame we need to setup a RenderTexture (passThroughTexture), which is an OpenGL ES Frame Buffer Object linked to a OpenGL Texture. The passThroughTexture Id is then passed to the Vuforia Renderer Object to update the texture with the contents of the camera frame.

To render the camera frame in the Scene  a rectangle SceneObject (passThroughObject) is added to the scene and the passThroughTexture is set as the material texture.

AR_IMG8

Creating the passThroughTexture:

passThroughTexture = new GVRRenderTexture(gvrContext,
 VUFORIA_CAMERA_WIDTH, VUFORIA_CAMERA_HEIGHT);

 

Creating the see-through rectangle:

GVRSceneObject passThroughObject = new GVRSceneObject(gvrContext, 16.0f / 9.0f, 1.0f);
…
…
material.setMainTexture(passThroughTexture); //set the passThroughTexture

Assign the passThroughTexture to Vuforia renderer:

TextureData data = new GLTextureData( passThroughTexture.getId());

Renderer.getInstance().setVideoBackgroundTexture(data);

Here we invoke the vuforia Renderer object to update the passThroughTexture. The onStep method is called per-frame by  GearVr framework,

@Override
public void onStep() {
…
…
if (VuforiaSampleActivity.isVuforiaActive())

{

Renderer.getInstance().begin();

Renderer.getInstance().updateVideoBackgroundTexture(); //update passThroughTexture

Renderer.getInstance().end();

}

 

Running the demo.

AR_IMG2

To run the demo just build the Android Studio project, don’t forget to put your oculus osig file in the assets folder so you can test the sideloaded app in your device.

The tracked images are located in the images folder.

Code for this project in github:

Links:

Tagged , , , , ,

Dots kollide source code is now free.

Full source code of a game I developed a few years back.

Completely free at : https://github.com/iaco79/dotskollide .

  • The code compiles on both Android / win32.
  • The Game framework is based on some of the ideas presented in the book :”Game Code complete”.
  • Shows how to integrate popular open source libraries:
    • SDL / SDL Mixer / Vorbis  / Tremor
    • irrlicht
    • librocket
    • lua / oolua

Running game:

 

Scroll Parallax y Tile Maps con Fragment Shaders (spanish)

Tiles Maps y Scroll Parallax: los métodos mas usados en el desarrollo de juegos 2d, sobre todo los retro style que buscan emular la epoca de las consolas de 8/16 bits.

Existen varias alternativas para “renderear” tile maps, generalmente se pinta un quad por cada Tile o se genera un quad por cada objeto de fondo.

Para dar el efecto de scroll parallax algunos métodos que he visto, sobre todo en algunos “engines” es colocar los quads de cada objeto a diferentes niveles de profundidad y mover la cámara para hacer el scroll, o usar texturas gigantes (lo cual limita el tamaño del mapa) y hacer offset de los UV.

Screen Shot 2015-03-31 at 4.32.36 PMnobacks

Si tomamos el ejemplo de “renderear” un Tile Map de 256×256, implica generar 256×256 quads o un mesh, eso da 65,536 quads o  65,792 vertices (si se usa un mesh) que se mandan al GPU y si suponemos que cada vértice requiere UV ( 8 bytes), Posición (12 bytes), color ( 4 bytes) y normales (12 bytes), da un total aproximado de 3MB tan solo de los puros vertices e indices y aun falta considerar el tamaño de las texturas de los tiles.

Lo anterior es aceptable incluso para un dispositivo móvil, pero si además queremos múltiples planos para scroll parallax (unos 4) ,ahí ya se van 12 MB + lo que se ocupe de texturas, eso ya no es muy optimo que digamos para un dispositivo móvil, memoria y ancho de banda (del GPU) que bien se pueden utilizar para aspectos mas importantes del juego.

Existe un método mas eficiente que utiliza solo 2 texturas y 1 quad (si, solo un quad) por cada nivel de scroll y emular algo así como lo que se hacia el SNES de soportar múltiple planos.

Primeramente ocupamos la clásica textura con los Tiles (“Tile Texture”) y el Tile Map (Tiled es una excelente herramienta para generar Tile Maps).

sp1

Cada valor dentro del TileMap contiene el TileId que representa el número de Tile (dentro del TileTexture) que se debe pintar. En el demo el TileTexture es de 1024×1024 (contiene tiles de 64×64 pixeles), y el TileMap para cada plano es 32×32 tiles.

sp2

El truco es usar el Tile Map generado por Tiled en forma de textura (“TileMap Texture”) y con esto delegar la parte de pintar los Tiles sobre un plano al Fragment Shader.

sp3

Generamos el plano (quad de 4 vértices, en el que pintaremos el Tile Map ) y se lo pasamos al GPU, debemos definir también cual es la “resolución virtual” del quad, en el demo se asume el quad tiene una resolución de 1024×768 , por lo tanto en ese quad caben 16×12 tiles (cada uno de 64×64 pixeles).

El quad además tiene las UV normalizadas con origen [0, 0] y destino [1, 1] , durante la etapa de rendering de los Fragmentos (pixeles) el Fragment Shader recibe la información intermedia de estos valores que corresponden al pixel que se esta procesando dentro del quad.

Para hacer el efecto de scroll dentro del shader ocupamos además el parámetro “Scroll Offset” , que contiene el desfasamiento X,Y a partir de cual comenzar a pintar el Tile Map.

Con esta información: el “Scroll Offset”, “UV” , “TileMap Texture”, y “Tiles Texture” podemos proceder a pintar el plano en el fragment Shader (como se solía hacer en software antes de la llegada de los GPUs, la ventaja es que este código corre en el GPU que utiliza los fragment units en paralelo):

sp4

Los parámetros UV nos indican el fragmento dentro del quad que estamos pintando, recordemos que el quad tiene una resolución virtual de 1024×768, así que lo primero que ocupamos es saber la posición virtual del pixel.

  • PosicionPIxel = UV x [1024,768] + ScrollOffset .XY

Con este valor, podemos obtener la posición dentro del TileMap en que nos encontramos, cada tile mide 64×64 y el TileMap mide 32×32, por lo tanto:

  • PosicionTile.UV = (PosicionPixel.XY / 64) / 32

Y con esta posición podemos localizar el valor del TileId en la textura TileMap:

  • TileId = TileMap( PosicionTile.UV)

Ahora que tenemos el TileId podemos localizar el valor del pixel correspondiente dentro del Tile Texture:

  • TilesCoord .U = ((TileId mod 16) * 64 + PosicionPixel.X mod 64) / 1024
  • TilesCoord .V = ((TileId /   16) * 64 + PosicionPixel.Y mod 64) / 1024
  • ValorPixel = TileTexture( TilesCoord.UV)

(En el demo anexo se puede encontrar el código del Fragment shader.)

Para el efecto de Scroll Parallax, es solo cuestión de mandar al GPU tantos Planos como queramos, cada uno con su correspondiente TileTexture, TileMap y valores para el Offset .

sp5

La ventaja de este método es que es posible pintar N planos en un solo “Draw call” siempre que los planos compartan el mismo set de Tiles (Tile Texture) y se tenga una textura con los TileMaps para cada plano (una especie de TileTexture de Tile Maps).

sp6

Además se pueden programar efectos de deformación, pixeleado, ondulado, etc. , todo en el fragment shader y generar efectos al estilo Modo 7 del SNES.

Demo:

Link del demo con 8 niveles de scroll parallax: ParallaxScrollDemoWin32a.zip

Referencias:

Tilemap Tutorial: http://www.the2dgame.com/index?page=articles&ref=ART4

Fast tilemap shader: http://connorhollis.com/fast-tilemap-shader/

Tagged , , , ,

Lights and Shadows for 2d worlds

Real time lights and shadows can make a big impact on the presentation of your game if you know how to use them wisely; this is also expected in any modern game.

sc0

For 3D, two common methods for generating real-time shadows are Shadow Mapping and Shadow Volumes (check the documentation of your favorite engine), each with their respective advantages / disadvantages and higher processing if all what you want is a simple 2d game.

Real-time shadows do not have to be something exclusive to worlds with 3d geometry, there are several 2D games out there that make use of real time 2d shadows.

After reviewing several online articles that describe some techniques and some existing implementations (plugins for engines such as Game Maker) I decided to develop this tutorial I hope will be useful, in which I describe simple method for 2d shadows generation.


(Demo at the end of this post)

How to create 2d lights and shadows in real time?

For 2d we can use something similar to shadow volumes, either generate geometry for the light covered area or generate the geometry that is not covered by light, our lighting model is not going to be a real physics, but a fairly good approximation.

What is a shadow?

 sc1

(Spanish lesson: light = luz, shadow = sombra)

 The shadow is the area that is outside the scope of light, areas that are blocked by shadow casters. So to generate shadows we need a light source and the shadow casters.

We can start with a simple light source: an omnidirectional light that covers a finite NxN square area ,the foreground geometry that makes up the game level can be the shadow caster.

sc2

We have defined our source of light, now what remains is to generate the shadows.

 How to generate the shadows?

For this we have 2 options:

  1. Calculate the region (2d geometry) that is not illuminated by light.
  1. Calculate the region (2d geometry) illuminated by light.

 sc3

(Spanish lesson: option = opcion)

Any option is valid,but I decided to take option 2: calculate the geometry that represents the area illuminated by light.

 How to calculate the geometry illuminated by light?

 Our problem now is to detect the borders where shadow casters collide with the light rays emitted by our light source as seen in the image below:

 sc4

How many rays to cast? Is that efficient?

Actually we don’t need to trace that too many rays to determine if they collide with the shadow casters.

What we can do is take the vertices of the shadow casters and select those that generate lines going straight to the center of the light without anything in between. We must also take into account the points of shadow casters that intersect the light region borders.

  sc5

 To make the process more efficient we can use AABB queries to detect intersections with the AABB of the light region and thus reduce the selection of vertices near the light.

sc6

Now that we have the points selected is only a matter of connecting dots , create the polygon and draw the area covered by light. The advantage is that this polygon can easily be rendered using a triangle strip and reduce the vertex information sent to the GPU.

sc7

We have light but it does not look too well, that is because we are rendering using a  constant white color, instead we can use a texture with circular color gradient to create the light fading effect.

\sc9 sc8

Lets add some color: for this simply paint a quad with a color gradient (the color of the light).

sc11 sc10

And the trick to make it look as seen in the screenshot is as follows: to paint this quad use a blending function that is equivalent to a multiplication RGB 1 x RGB2. What this does is multiply the value of light color by the value of the pixel beneath.

In opengl this is achieved using glBlendFunc (GL_ZERO, GL_SRC_COLOR).

You can experiment with various effects (I always use GIMP to design and model rendering by layers before doing any coding).

How to do multiple lights?

To do multiple lights, it’s just a matter of using FBOs (“Frame Buffer Object” or “Render to Texture” or “Post processing” or whatever you call it).

  1. We draw the colors of each light in a FBO1 and let the colors blend together (ADD blending).

sc12

  1. Draw the geometry of each light in a FBO2 and let intensities to accumulate (ADD blending)

sc13

  1. We proceed to draw the floor (or background).
  1. Draw over the FBO2 (containing the light intensities in gray scale/alpha).
  1. Draw the geometry of our 2d world (shadow casters).
  1. Finally paint the FBO1: Light colors. (Using blending MULTIPLY).

sc14sc15

With this we have got a simple, low resource and Openg GL ES 2.0 compatible 2d lighting system.

sc16

3 simultaneous lights. (Demo screenshot)

This technique is useful if you are developing a 2d game and want to avoid 3D geometry for shadows. If you are using box2d you can actually reuse the body fixtures as shadow casters, and execute AABB queries to only process the geometry within the area of ​​light.

What else is missing?

+ The shadows penumbra (soft shadows): we may need to generate more geometry for the shadow edges, it’s not that complicated, just some analytic geometry. The other option is to make a kind of blur shader when rendering the light geometry.

+ Per-pixel lighting: the floor is very flat would be nice to add bump mapping.

+ Modeling other types of light (directional lamp): for this we can reshape the region of light (instead of a rectangle use a triangle), make some adjustments to the calculations (origin and angle of light) and use the appropriate textures.

Demo:

Link to win32 demo: Demo 2d Shadows

In future posts I will see another useful technique for 2d games (or perhaps continue a 2nd part of this article revisiting soft-shadows and per-pixel lighting 2d).

References:

http://archive.gamedev.net/archive/reference/programming/features/2dsoftshadow/

http://www.redblobgames.com/articles/visibility/

Luz y Sombra para mundos 2d. (spanish)

Los efectos de luz y sombra en tiempo real pueden causar un gran impacto en la presentación de tu juego si los sabes usar sabiamente y además se esperan formen parte de cualquier juego moderno.

sc0

En el caso de 3d, los métodos mas comunes para generar sombras en tiempo real son Shadow Mapping y Shadow Volumes (checa la documentación de tu engine favorito), cada uno con sus respectivas ventajas / desventajas y con costo de procesamiento alto si solo se esta haciendo un juego con apariencia 2d (pero con geometría 3d).

Las sombras en tiempo real no tienen por que ser algo exclusivo para mundos con geometría 3d, existen juegos 100% 2D que tienen efectos de luz y sombra en 2D .

Después de repasar varios artículos en internet que describen algunas técnicas y revisar algunas implementaciones existentes (plugins para engines como Game Maker) decidí desarrollar este tutorial que espero les sea útil, en el que describo una implementación (independiente del engine que utilices o si estas evaluando utilizar algún plugin) basada en generación de geometría y shaders simples.


(video del Demo al final del post)

¿Cómo hacemos luces y sombras 2d en tiempo real?

En el caso de 2d podemos usar algo similar a los shadow volumes, ya sea generar la geometría que cubre la luz o generar la geometría que no es cubierta por la luz, nuestro modelo de iluminación no será 100% fiel a los modelos físicos reales pero será una aproximación bastante aceptable.

¿Qué es una sombra?

sc1

La sombra es el área que esta fuera del alcance de la luz , áreas que son bloqueadas por shadow casters. Así que para generar sombras ocupamos primero una fuente de luz y los shadow casters que la bloquean.

Podemos empezar con una fuente de luz simple: una luz omnidireccional que cubre un área cuadrada finita NxN y los shadow casters serán la geometría que compone el nivel del juego.

sc2

Ya tenemos nuestra fuente de luz definida, ahora lo que sigue es generar las sombras.

¿Cómo generar las sombras?

Para esto tenemos 2 opciones:

1. Calcular la región (geometría 2d) que no es iluminada por la luz.

2. Calcular la región (geometría 2d) que es iluminada la luz.

sc3

Cualquiera de las 2 opciones es valida, yo he decidido tomar la opción 2: calcular la geometría que representa el área iluminada por la luz.

¿Cómo calcular la geometria iluminada por la luz?

Nuestro problema ahora consiste detectar los borders de los shadow casters con los cuales colisionan los rayos de luz emitidos por nuestra fuente de luz como se ve en el la siguiente imagen:

sc4

¿Cuántos rayos lanzamos, muchos?¿Que tan eficiente es eso?

Bueno en realidad no necesitamos lanzar rayos para determinar si colisionan con los shadow casters.

Lo que se puede hacer es tomar los vértices de los shadow casters y seleccionar aquellos que generen líneas que van directo al centro de la luz sin toparse con nada de por medio. También hay que tomar en cuenta los puntos de los shadow casters que se intercectan con los borders de la región de luz.

sc5

Para hacer mas eficiente el proceso podemos usar AABB queries para detectar intersecciones con el AABB de la region del luz, y de esta forma reducir la selección de vertices cercanos a la luz.

sc6

Listo, ya tenemos los puntos q conforman el area iluminada por la luz, ahora solo conectamos los puntos para generar el polígono y pintarlo sobre el piso . La ventaja de este polígono es que se puede renderear fácilmente con un triangle strip y reducir la información de vértices que se envía al GPU.

Los siguientes screenshots (tomados del demo anexo) muestran como quedaría con lo que llevamos de momento.

sc7

Ya tenemos luz pero no luce muy bien que digamos pues estamos rendereando el área de la luz con un color constante.Podemos usar una textura con degradado circular para hacer el efecto de desvanecimiento, listo :D.

sc8 sc9

Ahora un poco de color : para esto simplemente pintamos un quad con degradado circular del color de nuestra fuente de luz.

sc10 sc11

Y el truco para que luzca como se ve en el screenshot es el siguiente: al pintar este quad usamos una función de blending que sea equivalente a una multiplicación RGB1 x RGB2. (pixel por pixel). Esto lo que hace es multiplicar el valor de la luz que estamos pintando por el valor del pixel que se encuentra debajo.

En opengl esto se logra usando la funcion glBlendFunc( GL_ZERO, GL_SRC_COLOR).

Se puede experimentar con varios efectos (yo uso por ejemplo GIMP para diseñar y modelar el rendering por capas y posteriormente programar el shader).

Y ahora, ¿cómo hacer muchas luces?

Para pintar multiples luces, solo es cuestión de usar FBOs ( “Frame Buffer Object” o “Render to Texture” o “Post processing” o como quieras llamarlo).

1. Pintamos los colores de las luces en un FBO1 y dejamos que se mezclen los colores usando operaciones de color blending (ADD).

sc12

2. Pintamos la geometría de luz generada por cada una de las luces en un FBO2 y dejamos que se acumulen las intensidades usando alpha blending (ADD).

sc13

3. Procedemos a pintar el suelo (o fondo) del mundo 2d.

4. Pintamos encima el FBO2 (que contiene las regiones de luz en escala de gris / alpha).

5. Pintamos la geometría de nuestro mundo 2d (shadow casters).

6. Finalmente pintamos el FBO1: colores mezclados de cada luz. (usando blending MULTIPLY).

sc14

sc15

Listo! Ya tenemos un implementación de luces y sombras para geometría 2d, simple y de bajo uso de recursos y que funciona además en Openg GL ES 2.0 (que es lo que soportan la mayoría de los dispositivos mobiles actuales).

Screenshot final del demo (3 luces simultáneas).

sc16

Esta técnica es útil si estamos desarrollando un juego2d y queremos evitar generar geometría 3d para cálculos de luz y sombra. si usas box2d puedes reutilizar la geometría de los fixtures y utilizarla como shadow caster, y además se pueden “eficientizar” los cálculos usando AABB queries para solo procesar la geometría dentro del área de luz.

¿Qué mas falta?

+ Las penumbras (soft shadows): ocupamos generar mas geometría para degradar los bordes de las sombras, no es tan complicado, solo un poco de geometría analítica y listo. La otra opción es hacer una especie de blur shader durante el rendering de las sombras.

+ Per-pixel lighting : el piso se ve muy plano no estaría mal agregarle bump mapping.

+ Modelar otros tipos de luz (direccional , lámpara): para esto es solo cambiar la forma de la región de luz (en vez de un cuadro, usar un triángulo), hacer algunas adecuaciones en los cálculos (origen y ángulo de la luz) y usar texturas acordes.

Demo:

Link del demo para win32 : Demo 2d Shadows

(este demo fue desarrollado usando librerías open source multiplataforma irrlicht / sdl 2.0, mismas que he utilizado para varios juegos que he publicado en iOS , Android y Windows phone).

En próximos posts, publicaré otra técnica útil para engines 2d (o quizas continuar una 2ª parte de este articulo con los temas de soft-shadows y per-pixel lighting 2d).

Referencias:

http://archive.gamedev.net/archive/reference/programming/features/2dsoftshadow/

http://www.redblobgames.com/articles/visibility/

Tagged , , , ,

Addions: The free-moving numbers puzzle!

Hi All

Addions is the new game I’ve been working on, and it is now available in the Appstore and Google Play and it is free!

The concept is like 1024 / Threes but this is a new mechanic (not like other shameful clones).

You can find more about here.

Dots Kollide is now available on google play

Dots Kollide is the name of the game I have been working on and it is finally on google play.

http://dotskollide.wordpress.com/



Get it on Google Play

I’ll shortly post a postmortem, it took me around 6 months of my spare time to complete this game, the iOS version is comming soon..

 

 

 

My first game in progress.

It has been a while since the last post…

Anyway I have managed to put aside some time and continue working in my game, here are some updated videos showing the current game play concept.

Win32 demo:



Ouya demo:

I’ll be posting the  source code for the small engine behind  in C++ pretty soon…

Creating a simple shopping list android App

Hello, this week I decided to take a break of the game programming stuff so in this post I’m going to describe how to build a basic shopping list app that could help you get more familiar with the android API and make use of the following features that android provides:

  • Touch gestures
  • SQLite database
  • Customized ViewGroup

The idea of this app is that when I run out of something I will mark an item as “not available” and then after I go to the grocery store I will check it again as available. Whenever an item is marked as available or not the status is saved in the local db immediately.

Here is an screenshot of the app:

screenshot

  • The SlideToggle

I wanted to have a “switch toggle” like user control to indicate if an item is available or not using a swipe gesture so I created one using a Custom ViewGroup.

animateddemo

The viewgroup is composed of two imageviews at each side and in the middle 2 textviews to display the description of the item. In the next figure you can see the layout and the order at which the TouchEvents are called to achieve the swipe gesture.

customviewgroup

 

Since loading images can be quite slow it is better to use an AsyncTask in order to improve the scrolling response of the listview by not blocking the UI thread.

new AsyncTask<Object, Void, Drawable>() {
ImageView imv1 = null;
ImageView imv2 = null;


@Override
protected Drawable doInBackground(Object... params) {
String imageName = (String)params[0];
Drawable d= getImageFromAssets(imageName);

imv1 =  (ImageView)params[1];
imv2 =  (ImageView)params[2];

return d;
}

@Override
protected void onPostExecute(Drawable d) {
super.onPostExecute(d);
if (d!= null) {
imv1.setImageDrawable(d);
imv2.setImageDrawable(d);
}
}

}.execute(o.getPictureName(),cr.mImageLeft, cr.mImageRight);

  • The sqlite database

I’m using a simple table that contains the list of items


CREATE TABLE TABLE_ITEM_CATALOG (    

COLUMN_ITEMID  INTEGER PRIMARY KEY AUTOINCREMENT,

COLUMN_NAME  TEXT NOT NULL,

COLUMN_DESCRIPTION TEXT NOT NULL,

COLUMN_IMAGENAME TEXT NOT NULL,

COLUMN_STATUS  INTEGER NOT NULL )

To work with sqlite in android you need to create a class that extends the SQLLiteOpenHelper class. The very first time you request access to the database and it doesn’t exist yet the method DBHelper.onCreate will be called so you can create the database tables and provide initial data.


public void onCreate(SQLiteDatabase database) {
...
...
database.execSQL(DATABASE_CREATE);

  • Data access model

In order to update the database I setup a basic Data Access Object Model with generics. This data access object model operates over DTOs (Data Transfer Objects) and in this case there is just one dto class named “item”.

DaoStructure

When the switch toggle for an item is updated the OnChange callback is triggered and at this point I call the dao’s update method to update the item in the database.

DtoStructure

this.m_adapter = new ItemListAdapter(

  this.getActivity(), R.layout.row, m_dao.getList());

this.m_adapter.setOnItemViewChangeListener(

       new ItemListAdapter.OnItemViewChangeListener()

       { // Update the item status in the DB table

        @Override

        public void onChange(Item item) { m_dao.update(item);

        }

      });

That’s it you can download the source code from github.

Tagged