Awesome destructible terrain demo using Box2d on Emanuele Feronato’s site!!

Check out this awesome demo, making destructible terrain in Box2s on Emanuele’s site! Does anyone remember “Scorched Earth”? It was a freeware game from the 90’s that pre-dated worms, with similar gameplay, that allowed multiplayer, same screen battles that I used to play with my sister for hours.

I’d love to make a Android version of this, if for nothing else but the nostalgic, awesome gameplay!

Box2D for Flash Games demos in LibGDX with Projects for Desktop, Android, and HTML5

banner

I recently reviewed Emanuele Feronato’s new book “Box2D for Flash Games”, and created all the demos from the book in FlashDevelop.
In this post, I wanted to bring them all into LibGDX, so that everyone could also see how to work in Box2D using LibGDX, to develop Android, Desktop, and HTML5 Box2D games.

I would recommend picking up his book if you are interested in Box2D, and want to understand these demos from his book better. His site is also one of the best for tutorials an examples for beginner and intermediate game developers. (http://www.emanueleferonato.com/2012/11/28/box2d-for-flash-games-book-is-on-the-shelves/)

Obviously the syntax between AS3 and Java are a little different, but most of the lines of code worked pretty well, only having to change variable declarations, of function capitalization.

The only large problem I ran into was the implementation of JBox2d on LibGDX for the HTML5 version of the project. Everything still built correctly, and works, but blocks begin randomly shifting and falling over, and I wasn’t able to discover a solution to this problem yet.

In Example 2.1, we build on chapter one by adding objects to our world, making them dynamic, and changing the material properties, to allow the objects to interact differently.


Download the source code for the eclipse projects for Desktop, Android, and HTML5

And so you can see how easy it is to setup a basic Box2D world in LibGDX, that compiles for Desktop, Android and HTML5:
(The main difference is that OpenGL/LibGDX use the bottom-left corner as 0,0 (normal Cartesian) , whereas Flash uses the top left as 0,0, with down increasing in y-value, so for any y-coordinates from AS3, you have to do SCREEN_HEIGHT-y_coord. Also, I keep track of screen scaling, to scale everything relative to screen size, since obviously most Android devices can’t display 640×480 resolution, and should be full screen, regardless)

package com.chrismweb.box2dforflashgames;


import java.util.Iterator;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;


/**
 * ...
 * #Chp2.1 - Ball drop with bounce
 * @book by Emanuele Feronato
 * http://www.emanueleferonato.com/
 * Get it now @ http://www.packtpub.com/box2d-for-flash-games/book
 */

public class MyGdxGame implements ApplicationListener
{
	//for drawing
	private OrthographicCamera camera;
	private SpriteBatch batch;
	
	//
	Vector3 touchPoint;
	
	

	public static float SCREEN_WIDTH_ORIGINAL=640;
	public static float SCREEN_HEIGHT_ORIGINAL=480;
	
	public static float SCREEN_WIDTH=640;
	public static float SCREEN_HEIGHT=480;
	
	//for testing other screen resolutions quickly in the desktop version
//	public static float SCREEN_WIDTH=1280;
//	public static float SCREEN_HEIGHT=800;
	
	public static float BOX2D_WIDTH_SCALE=1;
	public static float BOX2D_HEIGHT_SCALE=1;
	
	//box2d variables
	private World world;
	private Box2DDebugRenderer debugRenderer;
	public static float PIXELS_PER_METER = 30.0f;
	
	//reset variables
	BitmapFont font;
	Rectangle rect_reset;
	private ShapeRenderer renderer;
	
	

	@Override
	public void create()
	{
		SCREEN_WIDTH= Gdx.graphics.getWidth();
		SCREEN_HEIGHT= Gdx.graphics.getHeight();
		
		//NOTE: with different screen sizes (on android for instance) the world will be setup as different sizes, so the mass of objects won't be the same.
		//you need to create the world the same size, and scale the camera, so that it behaves the same regardless of screen resolution
		BOX2D_WIDTH_SCALE=SCREEN_WIDTH_ORIGINAL/SCREEN_WIDTH;
		BOX2D_HEIGHT_SCALE=SCREEN_HEIGHT_ORIGINAL/SCREEN_HEIGHT;
		
		
		// setup the camera. In Box2D we operate on a
		// meter scale, pixels won't do it. So we use
		// an orthographic camera with a viewport of
		// 48 meters in width and 32 meters in height.
		// We also position the camera so that it
		// looks at (0,16) (that's where the middle of the
		// screen will be located).
		camera = new OrthographicCamera(PixToMeter(SCREEN_WIDTH)*BOX2D_WIDTH_SCALE, PixToMeter(SCREEN_HEIGHT)*BOX2D_HEIGHT_SCALE);
		camera.position.set(PixToMeter(SCREEN_WIDTH)/2*BOX2D_WIDTH_SCALE, PixToMeter(SCREEN_HEIGHT)/2*BOX2D_HEIGHT_SCALE, 0);
				
		batch = new SpriteBatch();
		
		touchPoint = new Vector3(0,0,0);

		Vector2 gravity=new Vector2(0.0f, -9.81f); //we have to flip ALL y values- AS3 uses down int he y duirection as increasing, whereas OpenGL uses UP in the y direction as positive
		Boolean sleep = true;
		world = new World(gravity, sleep);
		debugRenderer = new Box2DDebugRenderer();
		
		Setup();
		
		font = new BitmapFont(Gdx.files.internal("resources/fonts/arial-15.fnt"), false);
		font.setScale(1/BOX2D_HEIGHT_SCALE);
		
		rect_reset = new Rectangle(0, SCREEN_HEIGHT-30/BOX2D_HEIGHT_SCALE, 100/BOX2D_WIDTH_SCALE, 30/BOX2D_HEIGHT_SCALE);
		renderer = new ShapeRenderer();
		
		Gdx.app.log("MyGdxGame", "GAME STARTED");
		
	}
	
	private void ResetWorld()
	{
		Gdx.app.log("MyGdxGame", "Resetting world");
		Iterator iterator = world.getBodies();
		while(iterator.hasNext()) 
		{
	         Body body = iterator.next();
	         world.destroyBody(body);
		}
		Setup();
	}
	
	public void Setup()
	{
		//for creating a circle
		//first create a bodydef
		BodyDef bodyDef = new BodyDef();
		bodyDef.position.set(PixToMeter(SCREEN_WIDTH_ORIGINAL/2), PixToMeter(SCREEN_HEIGHT_ORIGINAL-30));
		bodyDef.type = BodyType.DynamicBody;
		
		CircleShape circleShape = new CircleShape();
		circleShape.setRadius(PixToMeter(25));
		
		FixtureDef fixtureDef = new FixtureDef();
		fixtureDef.shape=circleShape;
		fixtureDef.density=1;
		fixtureDef.restitution=0.6f;
		fixtureDef.friction=0.1f;
		Body theBall = world.createBody(bodyDef);
		theBall.createFixture(fixtureDef);
		
		//for creating the "floor" bottom rectangle
		bodyDef.type=BodyType.StaticBody;
		bodyDef.position.set(PixToMeter(SCREEN_WIDTH_ORIGINAL/2), PixToMeter(SCREEN_HEIGHT_ORIGINAL-470));//center location of the box- 320 to the right (640/2), and 10px from the bottom(480)
		PolygonShape polygonShape=new PolygonShape();
		polygonShape.setAsBox(PixToMeter(SCREEN_WIDTH_ORIGINAL/2), PixToMeter(10));//1/2 width and height, so 640x20 px box
		fixtureDef.shape=polygonShape;
		Body theFloor=world.createBody(bodyDef);
		theFloor.createFixture(fixtureDef);
	}
	
	private float PixToMeter(float pixels)
	{
		return pixels / PIXELS_PER_METER;
	}
	private float MeterToPix(float meters)
	{
		return meters * PIXELS_PER_METER;
	}

	@Override
	public void dispose()
	{
		batch.dispose();

	}

	@Override
	public void render()
	{
		world.step(Gdx.app.getGraphics().getDeltaTime(), 3, 3);
		
		Gdx.gl.glClearColor(.2f, .2f, .2f, 1); //0->1 = 0->255
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		camera.update();

		
		
		debugRenderer.render(world, camera.combined);
		
		
		
//		renderer.begin(type)
		renderer.setColor(.05f, .2f, .31f, 1.0f);
		renderer.begin(ShapeType.FilledRectangle);
		renderer.filledRect(rect_reset.x, rect_reset.y, rect_reset.width, rect_reset.height);
		renderer.end();
		
		batch.begin();
		font.drawMultiLine(batch, "Reset", rect_reset.x, rect_reset.y+font.getLineHeight(), rect_reset.width, HAlignment.CENTER);
		batch.end();
		
		Update();
	}
	public void Update()
	{
		// translate the mouse coordinates to world coordinates
		if (Gdx.input.justTouched()) 
		{
			camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
			Vector2 touchPointPixels =new Vector2(MeterToPix(touchPoint.x)/BOX2D_WIDTH_SCALE, MeterToPix(touchPoint.y)/BOX2D_HEIGHT_SCALE);
			
			Gdx.app.log("MyGdxGame", "GAME touchPointPixels: "+touchPointPixels);
			if(rect_reset.contains(touchPointPixels.x, touchPointPixels.y))
				ResetWorld();
		}
	}

	@Override
	public void resize(int width, int height)
	{
	}

	@Override
	public void pause()
	{
	}

	@Override
	public void resume()
	{
	}
}

After that, in Example 2.2 we also create a “Totem” game level, and create the totem object using compound objects to make a complex object from simple shapes.
We also create the head of the totem as a generic polygon, by specifying individual vertices to create the shape. (Blocks for some reason behave somewhat like jelly in the HTML5 with LibGDX and JBox2d)


Download the source code for the eclipse projects for Desktop, Android, and HTML5

In Example 3.1, we then learn how to convert mouse input to box2D meters, how to delete a body, and how to selectively get physical information about certain bodies that we are interested in.
(click on certain bodies to destroy them)


Download the source code for the eclipse projects for Desktop, Android, and HTML5

I will upload the rest of the demos and source code for each in the near future.

Review of Box2D for Flash Games (Author: Emanuele Feronato)

banner

Emanuele has come out with a new book, which is a great overview of using Box2D with real-world examples.

He had announced it back in the end of November on his blog ( http://www.emanueleferonato.com/2012/11/28/box2d-for-flash-games-book-is-on-the-shelves/ ), and I couldn’t wait to get my hands on it.

(Example of one of the “Totem” like game you create, with my “Crysis-like” graphics.)

(Click on certain bodies to destroy them)

Box2d is the most well known 2d physics engines, used by many mobile, flash, and indie games. This book starts with taking you through the very basics of setting up a Box2d world, to creating “Angry Birds”, and “Totem” like levels with gameplay. On top of that, it guides you through the different available abilities of Box2D, and demonstrates how to use them as you would when creating your own games.

You’ll learn different mechanisms you have for handling problems and when and how they should be used, so you can imagine applying them to your own game concepts.

I would definitely recommend this book to anyone who has been interested in Box2D, or using physics in their games, as well as people who have used Box2d before, but haven’t discovered much more than the basics of creating bodies. You should be comfortable working with Box2D by the end of the book, and you’ll learn how to skin Box2D with your own graphics.

The book covers pretty much everything you would need to learn about Box2D to make any kind of game involving 2d physics, and even better, shows you how to use them in real world examples.

You can pick up the book here:
http://www.packtpub.com/box2d-for-flash-games/book

Included Project Files for FlashDevelop

I decided to test all the examples in FlashDevelop, and I will show off each demo with a description, and have ALL the FlashDevelop project files attached after each demo in this review.
Most of the examples I simply copied into the basic FlashDevelop AS3 project, with only the custom graphics chapter requiring me to use a different method for rendering the Bitmaps.

Also Useful For Other Programming Languages/Platforms

I will also be creating the examples for Android using LibGDX in Java, to also demonstrate that the book can be useful to you, regardless of whether you work primarily in Flash/As3, Java, or C++.

Continue reading

Working on NetBook game (SpellBinder) for the Intel Level Up 2010!

I’ve been working on a game for the Intel Level Up 2010 Competition. I had posted an idea, but hadn’t had time to work on it much, but got selected as a finalist for the Netbook section!

It’s a side scroller / platformer game using box2d for interesting game play additions.

Due in the end of September, so I have a little over a month. Have finished a lot of the basic gameplay interactions (2/3rds) but still have a ton of work to do. Level design, game play design, artwork, bug testing, and converting to c++ for a major boost in speed.

The demo is at:
http://chrismweb.com/games/SpellBinder/