I have been working on a prototype for a new Flash game, codenamed “Word Attack”. The finished game will eventually be submitted to Word Play- A Flash Game Contest, that is being hosted by Dictionary.com and Mochi Media. Check out the prototype below…
Note: There is no gameplay mechanic revolving around the blocks turning red after they stop moving, this is just something that the Box2D API does to let the developer know that objects are “sleeping” (not being simulated anymore).
As you can see, the player’s goal is to clear every level by creating words with the letters provided (for the prototype I created nine levels). One thing that is worth pointing out is that the player has the choice of completing a level in whatever fashion the player chooses, as long as the player clears out all the letters in the level by typing in valid words. For example, in level seven the letters falling down consist of “c”, “o”, “m”, “p”, “u”, “t”, “e”, and “r”. So the player can complete the level by either typing in “computer”, or by typing in “mop” and then typing in “cuter”.
I plan to expand more on the gameplay by working with a game designer, since it feels like it needs a bit more “fun” in order for it to not just be Scrabble with physics. This is also the first time I have used the Box2D API to develop a Flash game, and I must say, it’s turning out quite well so far .
Feel free to comment on the game, I’m also open to suggestions on gameplay or anything in general related to the game.
Ian Schreiber’s (http://gamedesignconcepts.wordpress.com/) summer game design course (*cough* free *cough*) just started this past Monday. For each lesson (which he refers to as a level) he will make a post on his blog and assign homeplay (homework) to be completed before the next lesson. For the first lesson he went over as to what exactly is a game, and what it takes to make a basic game. Though none of the assignments stated to create a game, he did provide a small exercise half way through the lesson entitled “15 Minute Board Game Challenge”.
The basic premise of the exercise was to design a board game in which you are either “running towards something or running away from something” in 15 minutes. I chose to create my game in the “running towards” category, though I’m sure it could be easily changed to be a “running away from” game, and this is what I came up with.
Title: Ice Mountain
Goal: Be the first to climb to the top of the icy mountain.
Player representation: Mountain climbers
Number of players: 2 to 4
Game bits: Board, 6-sided die, mountain climber tokens
Board:
Rules: All players start by being positioned on the starting square (S). All players will roll a 6-sided die once to determine turn order, with the highest roll being first, second highest second, and so on. After order is determine, players take turns rolling a 6-sided die and moving that many squares forward. The game is over when one player lands exactly on the final square (F).
Game mechanics
Get out of my way! (Getting knocked down by other players): If a player’s turn ends by landing on the same square as another opposing player(s) , have the player whose turn just ended roll again and move the opposing player(s) that many squares back.
You went too far! (Falling off the top of the mountain): As stated in the rules, a player must land exactly on the final square (F) in order to win. If a player rolls the die and goes past the final square (F), have the player go back the number of squares he went over, using the final square (F) as the starting position.
Avalanche! (Being in the wrong place at the wrong time): When ever there are three consecutive rolls of the die with the same result (e.g. player one rolls 5, then player two rolls 5, then player three rolls 5) an avalanche occurs. If the number that is rolled consecutively is 1, 2, or 3 the avalanche will happen on the left side of the mountain, if the number is 4,5, or 6 the avalanche will happen on the right side of the mountain. If a player is on the side of the mountain were the avalanche occurred, that player must move SOUTH exactly one square. If there is no square south of the player’s location, the player is moved to the starting square (S).
That’s it! It felt pretty good sitting down and designing a game withouth having to think about how it was going to be programmed . Looking forward to level 2 on Thursday!
About a year ago, a friend of mine recommended I watch a video consisting of Joe Liemandt (Bio) giving a talk at Stanford about how he started his company during his undergrad at Stanford. I found the video very inspirational and motivating. He had just one more semester left in order to graduate, and he tossed all in the back burner to go with something he wanted to do then and now, and it was NOT an easy path starting up Trilogy (his company).
In the clip below he’s talking about how everyone should experience some level entrepreneurship. Through out his talk he really pushes the idea of dropping out of college to start your own company.
I highly recommend anyone who has any sort of passion for what they do to check out his full talk, it’s inspirational, funny, and one of the most motivating talks I ever listened to.
Another great talk that is also a must watch, and has the same take away message as Joe Liemandt’s talk, is Steve Job’s 2005 Stanford commencement address.
I mention in my last post that Todd Kerpelman created a set of Box2D video tutorials (http://www.kerp.net/box2d/), I just finished up the first chapter and here is what I came up with…
As you can see it isn’t a whole lot, just a bunch of boxes falling down, but damn does it look good .
Here is the source code for the project
package
{
import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import fl.controls.Button;
import flash.events.MouseEvent;
/**
* Final result of Todd Kerpelman's chapter 1 box2d video tutorial
* (http://www.kerp.net/box2d/).
* The code here is pretty much line for line from Kerpelman's tutorial
* I added a small modification so the simulation may be restarted when
* the user clicks the restart button in the top left of the screen.
* @author Edgar Miranda
*/
public class HelloBoxWorld extends MovieClip
{
protected var _world:b2World;
// Ratio of pixels to meters
public static const RATIO:Number = 40;
// Number of frames until we launch another crate
private var _nextCrateIn: int;
// Button to restart simulation
public var restartButton: Button;
public function HelloBoxWorld()
{
// 1. Set up the world
setupWorld();
// 2. Creating walls and floor
createWallsAndFloor();
setupDebugDraw();
_nextCrateIn = 0;
addEventListener(Event.ENTER_FRAME, newFrameEvent);
// Put the restart button on the top most index
// so it isn't covered by the falling crates
addChild(restartButton);
// Event listener in order to restart
// simulation when the restart button is pressed
restartButton.addEventListener(MouseEvent.CLICK, onRestartButtonClick)
}
private function onRestartButtonClick(e: MouseEvent): void {
// Remember that the world counts as one body so you
// want to remove bodies until there is only one body left
while (_world.GetBodyCount() > 1) {
_world.DestroyBody(_world.GetBodyList());
}
// recreate the walls again
createWallsAndFloor();
// set to default value
_nextCrateIn = 0;
}
private function setupDebugDraw():void
{
var spriteToDrawOn:Sprite = new Sprite();
addChild(spriteToDrawOn);
var artistForHire:b2DebugDraw = new b2DebugDraw();
artistForHire.m_sprite = spriteToDrawOn;
artistForHire.m_drawScale = RATIO;
artistForHire.SetFlags(b2DebugDraw.e_shapeBit);
artistForHire.m_lineThickness = 2.0;
artistForHire.m_fillAlpha = 0.6;
_world.SetDebugDraw(artistForHire);
}
private function newFrameEvent(e:Event):void
{
_world.Step( 1.0 / 30, 10);
// Every few frames, until a certain numer of crates have been added
if (_nextCrateIn-- <= 0 && _world.m_bodyCount < 80) {
// add a random create to the world
addARandomCrate();
_nextCrateIn = 1;
}
//trace("Falling crate is at", _fallingCrate.GetPosition().x, ",", _fallingCrate.GetPosition().y);
}
private function addARandomCrate():void
{
// Add a falling block to the world.
var fallingCrateDef:b2PolygonDef = new b2PolygonDef();
fallingCrateDef.SetAsBox(randomInt(5, 40) / RATIO, randomInt(5, 40) / RATIO);
fallingCrateDef.friction = 0.8;
fallingCrateDef.restitution = 0.3;
fallingCrateDef.density = 0.7;
// Set it to, 250, -30
var fallingBodyDef:b2BodyDef = new b2BodyDef();
fallingBodyDef.position.Set(randomInt(15, 530) / RATIO, randomInt(-100, -10) / RATIO);
fallingBodyDef.angle = randomInt(0,360) * Math.PI / 180;
var fallingCrate:b2Body = _world.CreateBody(fallingBodyDef);
fallingCrate.CreateShape(fallingCrateDef);
fallingCrate.SetMassFromShapes();
}
// Return a random number between lowVal and highVal, INCLUSIVE
private function randomInt(lowVal:int, highVal:int): int
{
if (lowVal <= highVal) {
return (lowVal + Math.floor(Math.random() * (highVal - lowVal + 1)));
}else
{
throw(new Error("OMG! Wrong values passed to randomInt!!"));
}
}
private function createWallsAndFloor():void
{
// Create the shape (polygon) definition
var bigLongShapeDef: b2PolygonDef = new b2PolygonDef();
bigLongShapeDef.vertexCount = 4;
b2Vec2(bigLongShapeDef.vertices[0]).Set(0 / RATIO, 0 / RATIO);
b2Vec2(bigLongShapeDef.vertices[1]).Set(550 / RATIO, 0 / RATIO);
b2Vec2(bigLongShapeDef.vertices[2]).Set(550 / RATIO, 10 / RATIO);
b2Vec2(bigLongShapeDef.vertices[3]).Set(0 / RATIO, 10 / RATIO);
bigLongShapeDef.friction = 0.5;
bigLongShapeDef.restitution = 0.3;
bigLongShapeDef.density = 0.0;
// Create the body definition
var floorBodyDef:b2BodyDef = new b2BodyDef();
floorBodyDef.position.Set(0 / RATIO, 390 / RATIO);
// Create the body
var floorBody:b2Body = _world.CreateBody(floorBodyDef);
// Create the shape
floorBody.CreateShape(bigLongShapeDef);
floorBody.SetMassFromShapes();
var tallSkinnyShape:b2PolygonDef = new b2PolygonDef();
tallSkinnyShape.SetAsBox( 5 / RATIO, 195 / RATIO);
tallSkinnyShape.friction = .5;
tallSkinnyShape.restitution = 0.3;
tallSkinnyShape.density = 0.0;
var wallBodyDef:b2BodyDef = new b2BodyDef();
wallBodyDef.position.Set(5 / RATIO, 195 / RATIO);
var leftWall:b2Body = _world.CreateBody(wallBodyDef);
leftWall.CreateShape(tallSkinnyShape);
leftWall.SetMassFromShapes();
wallBodyDef.position.Set(545 / RATIO, 195 / RATIO);
var rightWall:b2Body = _world.CreateBody(wallBodyDef);
rightWall.CreateShape(tallSkinnyShape);
rightWall.SetMassFromShapes();
//trace("My world now has", _world.m_bodyCount, "bodies in it! Wow!");
}
private function setupWorld():void
{
// 1. Set up the size of the universe
var universeSize:b2AABB = new b2AABB();
universeSize.lowerBound.Set( -3000 / RATIO, -3000 / RATIO);
universeSize.upperBound.Set( 3000 / RATIO, 3000 / RATIO);
// 2. Define gravity
var gravity: b2Vec2 = new b2Vec2(0, 9.8);
// 3. Ignore sleeping objects
var ignoreSleeping:Boolean = true;
_world = new b2World(universeSize, gravity, ignoreSleeping);
//trace("My world has", _world.GetBodyCount(), "bodies in it!");
}
}
}
You can get the Zip file containing all the project resources (source code, FLA, FlashDevelop project file) by clicking the link below.
My next goal is to finish up chapter 2, which is a bit longer then chapter 1 (50 lessons instead of 22). I’m currently on chapter 2 lesson 4, and I’m aiming to do around 5-10 lessons a day. I find it it’s easier to learn if I do about an hour or so of lessons each day instead of doing the whole batch in a day or two, there is also so much I can take of just watching video tutorials all day .
So a while ago (almost a year ago) I got bored one night and decided to make a beginner video tutorial on using the Box2DFlashAS3 physics engine, you can find the tutorial at the following … http://shah-soft.com/~warhell/box2d/Box2DFlash%20HelloWorld.html. Since that time, Todd Kerpelman (kerp.net) has created an extensive set of video tutorials for Box2DFlashAS3. If you’re interested in learning how to use this great Flash physics engine I highly recommend checking out videos, you can find them at… http://www.kerp.net/box2d/. Be sure to check out chapter 1.2, he gives me a shout out for creating the original beginner video tutorial .