Advanced Flash 8 Game Programming : Pixel level collision detection Part III (or let's start a real game)

In Part 1 – Advanced Flash 8 Game Programming : Pixel level collision detection I discussed the very basics of doing Pixel level hit detection with the bitmapData object. In Advanced Flash 8 Game Programming : Pixel level collision detection Part II (or let’s add Bitmap animation caching) I added in a simplified version of animation loop caching. In part III, we will start to make a simple game. This is what we are going to tackle:

1. We will use a play screen, created in Fireworks (or any other graphics program), as the maze or room the player is in. It will be viewed from the top. It will be a little odd looking because the Ari Feldman’s Sprite Lib GPL sprites we are going to use are viewed from the side. In any case it doesn’t look much worse than many commercial early 80’s games. This screen will be used as our wall map and we will use bitmap hitTest on the entire bitMap. This is a alternative to “tile-based” detection that has been a staple of game development for years. This isn’t to say that tile-based detection is bad or wrong, this is just a different method to accomplish the same thing. In fact, a combination of the two will be discussed in a later lesson.

2. Next we will add in animations for moving the player in 4 distinct directions and cache the animations for each. We will also add in variables for the player’s speed and an animation delay to help the player look a little more realistic.

3. We will start to create a more proper game loop with code more organized. We will also add in a Frame Rate counter, and use temp variables to hold current player position info before rendering the screen.

I will be doing a lot more explaining this time around as much has changed.

[cc lang=”javascript” width=”550″]
//hitpixels_with_bitmap_animationloop3.fla
//Jeff Fulton 2007
//www.8bitrocket.com
//pixel level collision detection with bitmap data object

import flash.display.*;
import flash.geom.*;

var keyPressed:Boolean=false;
var timeOfLastFPS:Number = 0;
var FPSCOUNT:Number = 0;
//pixel level collision detection with bitmap data object

//1. load in spriteMap from library
var spriteMapBitmap:BitmapData = BitmapData.loadBitmap(“actionMap”);
//mc.attachBitmap(spriteMapBitmap, this.getNextHighestDepth());

[/cc]

***** *****
The above section of code imports the in the internal Flash classes needed for manipulating bitmaps and the math classes needed for creating a rectangle of screen data needed from a bitmap. We are also creating variables to hold if a key has been pressed and to calculate the current frame rate.
*****
*****

[cc lang=”javascript” width=”550″]//2 create an array of bitmaps for the player sprite
//in this example, the player has two frames of animation
//this is a simple example, so we won’t do 2 frames for every direction of movement, we’ll just use these two

[cc lang=”javascript” width=”550″]
// copy two sprite images for left movement
var aPlayerLeftSpriteArray:Array=new Array();
var tempSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite.copyPixels(spriteMapBitmap, new Rectangle(0, 72, 32, 32), new Point(0, 0));
aPlayerLeftSpriteArray.push(tempSprite);
var tempSprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite2.copyPixels(spriteMapBitmap, new Rectangle(0, 102, 32, 32), new Point(0, 0));
aPlayerLeftSpriteArray.push(tempSprite2);

[/cc]

***** *****
Here we have created an array to hold two animation frames for the left movement of our player. We are copying these frames from our imported spritemap. Below we will do the same thing for right, up, and down movement.
*****
*****

[cc lang=”javascript” width=”550″]
// copy two sprite images for left movement
var aPlayerRightSpriteArray:Array=new Array();
var tempSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite.copyPixels(spriteMapBitmap, new Rectangle(36, 72, 32, 32), new Point(0, 0));
aPlayerRightSpriteArray.push(tempSprite);
var tempSprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite2.copyPixels(spriteMapBitmap, new Rectangle(36, 102, 32, 32), new Point(0, 0));
aPlayerRightSpriteArray.push(tempSprite2);

// copy two sprite images for up movement
var aPlayerUpSpriteArray:Array=new Array();
var tempSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite.copyPixels(spriteMapBitmap, new Rectangle(72, 72, 32, 32), new Point(0, 0));
aPlayerUpSpriteArray.push(tempSprite);
var tempSprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite2.copyPixels(spriteMapBitmap, new Rectangle(72, 102, 32, 32), new Point(0, 0));
aPlayerUpSpriteArray.push(tempSprite2);

// copy two sprite images for down movement
var aPlayerDownSpriteArray:Array=new Array();
var tempSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite.copyPixels(spriteMapBitmap, new Rectangle(180, 72, 32, 32), new Point(0, 0));
aPlayerDownSpriteArray.push(tempSprite);
var tempSprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite2.copyPixels(spriteMapBitmap, new Rectangle(180, 102, 32, 32), new Point(0, 0));
aPlayerDownSpriteArray.push(tempSprite2);
[/cc]***** *****
Notice above we have created single dimensional arrays to hold each position. We easily could add all of these to another array to create one multi-dimensional array to hold all movement animation for our player. That is exactly what we will do on a later lesson.
*****
*****

//3. put player on screen, copy pixels from sprite to mc1

[cc lang="javascript" width="550"]
var playerSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
//playerSprite.copyPixels(spriteMapBitmap, new Rectangle(0, 72, 32, 32), new Point(0, 0));
this.createEmptyMovieClip("player_mc",this.getNextHighestDepth());
var aPlayerSpriteArray:Array=aPlayerLeftSpriteArray;
var playerSpriteIndex:Number=0;
player_mc.attachBitmap(aPlayerSpriteArray[0],100);
playerSprite=aPlayerSpriteArray[playerSpriteIndex];
player_mc._x=32;
player_mc._y=32;
player_mc.tempx=32;
player_mc.tempy=32;
player_mc.speed=3; //how many pixels to move with each key press
player_mc.delay=5; //how many keypresses to wait until moviing to the next animation frame
player_mc.delayCount=0;
[/cc]

***** *****
Now, here is where we start to add some meat. We create a bitmap object (playerSprite) that will hold a reference to the current bitmap data object that is attached to put player movieClip. We do this because once we have attached a bitmap to a clip, there is no way to access it directly. We need to access it for hit detection. Also we add in some new variables called tempx, tempy, speed, delay, and delayCount. Tempx and tempy will be used to hold the position our player WILL be at in the next interval. We will test this position in our hitTest rather than moving the player then testing. This is the start of our more organized game loop design. The speed variable is the number of pixels the player will move with each key press. The delay variable is the number of key presses that need to pass before we jump to the next animation frame for our player. The combination of these two will let you refine the player animation and allow things like speed power ups or traps where the player's speed is slowed. The delayCount is used to keep a count of the number of key presses that have passed since the last animation frame.
*****
*****

[cc lang="javascript" width="550"]//4. create a walls sprite
var screen2:BitmapData = BitmapData.loadBitmap("screen2");
var sprite2:BitmapData=new BitmapData(400,400,true,0x00000000);
sprite2.copyPixels(screen2, new Rectangle(0, 0, 400, 400), new Point(0, 0));
this.createEmptyMovieClip("sprite2_mc",this.getNextHighestDepth());
sprite2_mc.attachBitmap(sprite2,100);
sprite2_mc._x=0;
sprite2_mc._y=0;
[/cc]

***** *****
In the above code snippet, we load a 400 x 400 bitmap into a holder clip and then place the clip on the screen. This bitmap contains the walls for our game room. The bitmap has a transparent background and we will use pixel level hit detection to determine a hit on any wall.
*****
*****

[cc lang="javascript" width="550"]

this.onEnterFrame=function() {

getKeys();
checkCurrentFrameRate();
if (keyPressed) {
checkCollisions();
render();
keyPressed=false;

}

}
[/cc]

***** < Code Explanation> *****
The onEnterFrame is now our simplified game loop. We new are separating our loop into very distinct functions. First we check for key presses. Next we calculate and display the current frame Rate. If a key was pressed, then we check for collisions between the player and the walls and render the player back to the screen. If we were to have other objects on the screen such as collectibles and enemy sprites, our game loop would need to be organized differently. We'll get to that in a later lesson.
***** *****

[cc lang="javascript" width="550"]
function render() {

player_mc.delayCount++;

if (player_mc.delayCount > player_mc.delay) {
player_mc.delayCount=0;
playerSpriteIndex++;
if (playerSpriteIndex > aPlayerSpriteArray.length-1) playerSpriteIndex=0;
player_mc.attachBitmap(aPlayerSpriteArray[playerSpriteIndex],100);
playerSprite=aPlayerSpriteArray[playerSpriteIndex];
sprite_txt.text=playerSpriteIndex;
}
//trace("player_mc.tempx=" + player_mc.tempx);
//trace("player_mc.tempy=" + player_mc.tempy);
player_mc._x=player_mc.tempx;
player_mc._y=player_mc.tempy;

}

[/cc]
***** < Code Explanation> *****
The render function role is to update the player on the screen. It first checks to see if it needs to update the player animation loop (based on the delayCount varbaible), and then it changes the player's position to represent the next calculated position.
***** *****

[cc lang="javascript" width="550"]function checkCurrentFrameRate():Void {
if (timeOfLastFPS+1000 *****
The checkCurrentFrameRate function uses a getTimer call to check for the number of milliseconds that have passed since the last frame. If it has been 1000 or more (1 second = 1000 milliseconds) then we reset the number of frames counted. If not, it adds 1 to the frame rate counter. This is a pretty accurate way to calculate the frame rate and it will be within 1 or 2 frames of being correct.
***** *****
[cc lang="javascript" width="550"
]function getKeys() {
if (Key.isDown(Key.UP)) {
player_mc.tempy-=player_mc.speed;
aPlayerSpriteArray=aPlayerUpSpriteArray
keyPressed=true;
}
if (Key.isDown(Key.DOWN)) {
player_mc.tempy+=player_mc.speed;
aPlayerSpriteArray=aPlayerDownSpriteArray;
keyPressed=true;
}
if (Key.isDown(Key.LEFT)) {
player_mc.tempx-=player_mc.speed;
aPlayerSpriteArray=aPlayerLeftSpriteArray;
keyPressed=true;
}
if (Key.isDown(Key.RIGHT)) {
player_mc.tempx+=player_mc.speed;
aPlayerSpriteArray=aPlayerRightSpriteArray;
keyPressed=true;
}

}
[/cc]
***** *****
The getKeys function has been modified from the previous 2 versions. First, instead of automatically changing the player's _x and _y right away, we store the next values to temp variables. Also, we make sure to change to aPlayerSpriteArray to reference the array for the direction the player if headed. This code is very simple but works well here because each direction contains only two animation frames.
*****
*****

[cc lang="javascript" width="550"]

function checkCollisions() {

var myPoint:Point = new Point (sprite2_mc._x, sprite2_mc._y);
if (playerSprite.hitTest (new Point (player_mc.tempx , player_mc.tempy), 255, sprite2, myPoint, 255)){
bitmap_txt.text="true";
//trace("bitMap hit detected");
player_mc.tempx=player_mc._x;
player_mc.tempy=player_mc._y;
}else{
bitmap_txt.text="false";
}

}

[/cc]

***** *****
Our collision detection function has been modified to look almost nothing like the previous two. We have done away with the movieClip hitTest from before because the player is ALWAYS on the room bitMap (sprite2). Because of this, the hitTest would ways be true and there is no reason to waste time doing it. Also, we have changed the point we check in the bitmapData.hitTest call to reference the NEXT point for the player. If a hit is detected, we resent tempX and tempY to be the original values before the render function is called. This stops the player from moving into an area that he/she is not supposed to occupy.
*****
*****

That's it for this time. Check out the .fla and example below for more info.

hitpixels_with_bitmap_anmationloop.swf (2007)
A demo of using bitmapData to do pixel level collision detection and bitmap animation caching.

Use the arrow keys to move the spaceman around the room.

The bitmap hit will become true only if the spaceman collides with a walls (green), even through he is actually colliding with the wall bitmap all the time.

The Player Sprite number in the text box represents the current sprite in the array (bitmapData object).

The frame rate tells the current frame rate.

download the fla file

Ari Feldman's Sprite Lib used via GPL

Wii Opera Browser: A Storm In A Tea Cup?

I’ve been creating a few demos of Flash games designed for the Nintendo Wii Opera browser, and writing a few blog entries about the process for the past few months. I even convinced the people at my Day Job to create a section highlighting all the games we currently offer that can be played reasonably well with a Wii-mote. I jumped on the Wii Opera Browser very early. The day it was released to beta on Dec. 24th I pushed this demo live for my first test with my Wii. Most of developer friends, the ones lucky enough to own a Wii, have all connected to the internet through WiiConnect24, shared Miis, used Opera, etc.

However, a thought struck me today that I cannot shake. It was spawned over the weekend when I talked to my brother-in-law, another happy Wii owner. My brother-in-law is a construction contractor. He spends his days building actual houses for people, and is as far from spending his days with his ass planted in chair looking at computer screen as I am close to it. He bought the Wii to play Wii Sports with his wife and kids. That’s it. They have not bought any more Wii games (I have eight), nor Virtual Console games (I have five), they have not bought any GameCube games (I have six), they have not connected to WiiConnect24 (I have Wireless G with WPA encryption enabled), and they have certainly not downloaded Opera, or used the Wii Browser (my favorites list scrolls through 2 pages). It suddenly occurred to me today that, while I am plugged into every nuance of Wii news and Wii releases, my brother-in-law and his family could not care less.  They are not connected to the internet through their Wii, they don’t know they can connect, and will probably never try to connect to the internet. If they typify the casual, game players that are flocking to the Wii, then is it really a waste of time (at this instant) to try to create Flash-based games that appeal to Wii users and utilize the Wii-mote?  Is it worth spending the time to dumbed-down Flash 7 games when hardly anyone will ever see them? I simply don’t know the answer.

However, maybe you can help. If you own a Wii, or know anyone who does own one, have you/they connected it to the internet? Have they downloaded the browser? Have they played any games on the internet through the Wii Opera Browser with a Wii-mote?

Email any information you have us. We’ll compile it and reveal the results next week.

We here at 8bitrocket.com love the Wii. We think the the Wii Browser with a Wii-mote is the best internet experience that any game console has been able to create to date. However, what we don’t know is if the Wii Opera Browser is just a “storm in a tea cup” that few people will ever experience, or if it will really amount to something worth talking about.

Advanced Flash 8 Game Programming : Pixel level collision detection Part II (or let's add Bitmap animation caching)

In Part 1 – Advanced Flash 8 Game Programming : Pixel level collision detection I discussed the very basics of doing Pixel level hit detection with the bitmapData object. In this second part, I am going to add one more small feature that hopefully will improve the performance of your games. This technique will work in CS3 as well as Flash 8, but I have not used CS3 yet, so I can’t yet explain any differences in syntax or usage.

Action games need SPEED. Flash is actually very slow when rendering the screen, and the biggest culprit are the math calculations that are needed when using the timeline to run through a key frame vector animation. If your movie clip contains no animation, and just needs to move from point x1,y1 to point x2,y2, you can use bitmap surface caching (movieClip.cacheAsBitmap=true) to see a noticeable increase in performance. But, what do you do if the movieClip actually needs to run through a timeline animation? My theory is to eliminate as many timeline and vector animations as possible by caching them all before they are needed. If you play my game Retroblaster , you will notice that I spend a inordinate amount of time at the beginning doing something called “Preparing System Warps”. What I am actually doing is pre-caching all of the game animations to be used later. This allows me to have many more explosions, enemy ships, etc on the screen than if I tried to render vector timeline based animations in real-time.

I have taken the Part 1 code and modified it to add in this feature. Again, I am using Ari Feldman’s Sprite Lib GPL for my quick and dirty animation. I have changed the player and enemy objects to be a spaceman (player) and scorpion (enemy). I have pre-cached two frames of animation for the spaceman, and when you press the arrows keys in any direction the animation will run through one iteration of the loop. It looks a little weird because I haven’t spent any time adding frames of animation for the various directions, but rest assured, the sprite library contains then. (thanks Ari) They are not necessary for this demo though.

 

[cc lang=”javascript” width=”550″]//hitpixels.fla
//Jeff Fulton 2007
//www.8bitrocket.com
//pixel level collision detection with bitmap data object and animation caching
import flash.display.*;
import flash.geom.*;

//1. load in spriteMap from library
var spriteMapBitmap:BitmapData = BitmapData.loadBitmap(“actionMap”);
//mc.attachBitmap(spriteMapBitmap, this.getNextHighestDepth());

//2 create an array of bitmaps for the player sprite
//in this example, the player has two frames of animation
//this is a simple example, so we won’t do 2 frames for every direction of movement, we’ll just use these two
var aPlayerSpriteArray:Array=new Array();
var tempSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite.copyPixels(spriteMapBitmap, new Rectangle(0, 72, 32, 32), new Point(0, 0));
aPlayerSpriteArray.push(tempSprite);
var tempSprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
tempSprite2.copyPixels(spriteMapBitmap, new Rectangle(0, 102, 32, 32), new Point(0, 0));
aPlayerSpriteArray.push(tempSprite2);

//3. put player on screen, copy pixels from sprite to mc1
var playerSprite:BitmapData=new BitmapData(32,32,true,0x00000000);
//playerSprite.copyPixels(spriteMapBitmap, new Rectangle(0, 72, 32, 32), new Point(0, 0));
this.createEmptyMovieClip(“player_mc”,this.getNextHighestDepth());
player_mc.attachBitmap(aPlayerSpriteArray[0],100);
playerSprite=aPlayerSpriteArray[0];
player_mc._x=100;
player_mc._y=100;
var playerSpriteIndex:Number=0;

//4. copy pixels from spriteMap to enemy
var sprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
sprite2.copyPixels(spriteMapBitmap, new Rectangle(409, 72, 32, 32), new Point(0, 0));
this.createEmptyMovieClip(“sprite2_mc”,this.getNextHighestDepth());
sprite2_mc.attachBitmap(sprite2,100);
sprite2_mc._x=200;
sprite2_mc._y=200;

function updatePlayerAnimation() {
playerSpriteIndex++;
if (playerSpriteIndex > aPlayerSpriteArray.length-1) playerSpriteIndex=0;
player_mc.attachBitmap(aPlayerSpriteArray[playerSpriteIndex],100);
playerSprite=aPlayerSpriteArray[playerSpriteIndex];
sprite_txt.text=playerSpriteIndex;
}

this.onEnterFrame=function() {

if (Key.isDown(Key.UP)) {
player_mc._y ;
updatePlayerAnimation();
}
if (Key.isDown(Key.DOWN)) {
player_mc._y++;
updatePlayerAnimation();
}
if (Key.isDown(Key.LEFT)) {
player_mc._x ;
updatePlayerAnimation();
}
if (Key.isDown(Key.RIGHT)) {
player_mc._x++;
updatePlayerAnimation();
}

if (player_mc.hitTest(sprite2_mc)) {
normal_txt.text=”true”;
//trace(“basic hit detected”);
//test for pixel level hit
var myPoint:Point = new Point (sprite2_mc._x, sprite2_mc._y);
if (playerSprite.hitTest (new Point (player_mc._x , player_mc._y), 255, sprite2, myPoint, 255)){
bitmap_txt.text=”true”;
//trace(“bitMap hit detected”);
}else{
bitmap_txt.text=”false”;
}
}else{
normal_txt.text=”false”;
bitmap_txt.text=”false”;

}

}

[/cc]

hitpixels_with_bitmap_anmationloop.swf (2007)
A demo of using bitmapData to do pixel level collision detection and bitmap animation caching.

Use the arrow keys to move the spaceman to the scorpion sprite.

When the spaceman enters the 32×32 area for the scorpion, the normal hit becomes true.

The bitmap hit will become true only if the spaceman collides with a non-trnasprant pixel in the scorpion.

The Player Sprite number in the text box represents the current sprite in the array (bitmapData object).

download the fla file

Ari Feldman’s Sprite Lib used via GPL

1. First we create a spriteMap in memory from a bitmap (png with transparency) that I have in the library.
2. Next, I use some very very rudimentary code to pull two 32×32 images from the spriteMap and place them in an array called “aPlayerSpriteArray”. This can be done with loops, etc, but I just wanted to demonstrate it as clearly as possible here.
3. I put the player on the screen by creating a holder clip for the player and attaching the first bitmap in the array to the clip. I also make sure to place a reference to the attached bitmap in the variable “playerSprite”. This is necessary to make sure hit detection can be performed on the bitmap.
4. I copy some more pixels from the spriteMap to a bitmap data object named “sprite2” and then attach it to a movieClip. This will represent our enemy (scorpion) sprite.
5. Next I have a basic function for updating the player sprite. This is called when ever a key is pressed, notice that I have to re-reference the playerSprite on each change to make sure hit detection is done properly.
6. The onEnterFrame is the main loop. It checks for key input. I don’t use a key Listener object here because key repeats are difficult to detect with that object.
7. The hitTesting is the final part of the code. I first look for a basic hit. This can be done with hitTest, or one of a number of math based detections (circle – circle, rect – rect, etc). If that hit is true, then I check for the pixel level hit. Hopefully this will save cycles in your game.

Good luck, I’m off to use this code in a new game I am making based on the Atari classic called Gravitar (or OIDS if you had an Amiga or Atari ST back when that was the cool thing to do).

 

Advanced Flash 8 Game Programming : Pixel level collision detection

I had to take a little break after finishing Retroblaster to unwind before I started making games again. I plan to re-write my game loop and much of my game code in this public forum for a couple reasons. One is the selfish need of a cathartic outlet, and the other is to help aide other fledgling Flash game programmers. You will be learning as I learn. I will post my examples here, complete with code explanations and .fla files to download. The first lesson will be in collision detection. If you have tried the many popular methods of collision detection (hitTest, circle to circle, hitTest with a shape flag, etc) you will find none of them as accurate as pixel level detection. The downside is that pixel level detection will probably slow down a game with many objects all interacting at once. I have not done any frame rate tests, but a future post will compare the methods and see.

The bitmapData object, introduced in Flash 8, makes this possible. There are other methods to do pixel level collision detection, but they are either very math intensive (matrix math scares me), or use something like Grant Skinner Does here.

My version will be much easier for novices to understand. Basically it will be done in these steps

1. Create 2 sprites using a sprite map and the bitmapData object.
2. Attach those sprites to movieClips
3. Provide a reference to the attached sprite
4. While the user moves one of the clips with the keyboard, first check for a basic hitTest collision.
5. After a basic collision is detected, then and only then, do a pixel level hitTest with the bitMapdata.hitTest() function.

That’s it. The code is below. I have added comments where needed. After the code there is a link to the example swf page and a .fla to download and try for yourself. I am using as sprite map from Ari Feldman’s Sprite Lib GPL . Ari made this library and lets anyone use it for free as long as the abide by the GPL license.

 

[cc lang=”javascript” width=”550″]//hitpixels.fla
//Jeff Fulton 2007
//www.8bitrocket.com
//pixel level collision detection with bitmap data object

import flash.display.*;
import flash.geom.*;

//1. load in spriteMap from library
var spriteMapBitmap:BitmapData = BitmapData.loadBitmap(“spriteMap”);
var mc:MovieClip = this.createEmptyMovieClip(“mc”, this.getNextHighestDepth());
//mc.attachBitmap(spriteMapBitmap, this.getNextHighestDepth());

//2. copy pixels from spriteMap to mc1
var sprite1:BitmapData=new BitmapData(32,32,true,0x00000000);
sprite1.copyPixels(spriteMapBitmap, new Rectangle(495, 33, 32, 32), new Point(0, 0));
this.createEmptyMovieClip(“sprite1_mc”,this.getNextHighestDepth());
sprite1_mc.attachBitmap(sprite1,sprite1_mc.getNextHighestDepth);
sprite1_mc._x=100;
sprite1_mc._y=100;

//2. copy pixels from spriteMap to mc2
var sprite2:BitmapData=new BitmapData(32,32,true,0x00000000);
sprite2.copyPixels(spriteMapBitmap, new Rectangle(33, 33, 32, 32), new Point(0, 0));
this.createEmptyMovieClip(“sprite2_mc”,this.getNextHighestDepth());
var sprite2_bitmap:BitmapData=sprite2_mc.attachBitmap(sprite2,sprite2_mc.getNextHighestDepth);
sprite2_mc._x=200;
sprite2_mc._y=200;

this.onEnterFrame=function() {

if (Key.isDown(Key.UP)) {
sprite1_mc._y ;
}
if (Key.isDown(Key.DOWN)) {
sprite1_mc._y++;
}
if (Key.isDown(Key.LEFT)) {
sprite1_mc._x ;
}
if (Key.isDown(Key.RIGHT)) {
sprite1_mc._x++;
}

if (sprite1_mc.hitTest(sprite2_mc)) {
normal_txt.text=”true”;
//trace(“basic hit detected”);
//test for pixel level hit
var myPoint:Point = new Point (sprite2_mc._x, sprite2_mc._y);
if (sprite1.hitTest (new Point (sprite1_mc._x , sprite1_mc._y), 255, sprite2, myPoint, 255)){
bitmap_txt.text=”true”;
//trace(“bitMap hit detected”);
}else{
bitmap_txt.text=”false”;
}
}else{
normal_txt.text=”false”;
bitmap_txt.text=”false”;

}

}
[/cc]

hitpixels.swf – demo of using bitmapData to do pixel level collision detection(2007).

Use the arrow keys to move the tank to the orange splotch sprite.

When the tank enters the 32×32 area for the splotch, the normal hit becomes true.

The bitmap hit will become true only if the tank collides with a non-trnasprant pixel in the splotch.

download the fla file

Ari Feldman’s Sprite Lib used via GPL

1. When you attach a bitmapData object to a movieClip, a reference to the bitmapData object is passed, not the actual object. For hit testing purposes, you must use the original bitmapData object.
2. Here I have just used an object named sprite1, copied pixels from a png (with transparency) from the library to it, and have attached it to a movieClip.
3. if (sprite1.hitTest (new Point (sprite1_mc._x , sprite1_mc._y), 255, sprite2, myPoint, 255) is the function invoked. You must specify a point in both movieClip holders for the sprites tested, and the value (255) for the transparency threshold of each bitmap object.. This number represents the alpha threshold for the transparent areas. You can increase the :”sensitivity” of the collision test by lowering the number below 255. 255 means that ALL transparent areas, no matter the actual alpha value will be ignored in the hitTest. This gives you the best overall pixel level control.
4. To make a real game with this code (where multiple enemy sprites are needed) you would need to make sure to store a reference to to actual bitmapData object that makes up each enemy sprite and replace that with the sprite2 value as you loop through all of the enemy sprites.

The next lesson will be a simple way to add cached animation from the sprite map to this engine and you will see how a game will start to take shape.

 

Final Wii Browser: Thoughts Redux

Last week I complained that the final version of the Wii Opera Browser did not support anything greater than Flash 7.0    Now it, it turns out, that this was neither Nintendo or Opera’s fault. 

This information was brought to my attention earlier this week by fellow deveoper Chris Cutler (the programmer for the immensely popular game Pixel Chix Hamster Jam ) and confirmed today by nintendowiifanboy.com.   It turns out, that Adobe is really at fault here.  They have not released a dev kit for either Flash 8 or Flash 9, and until they do this, it will be impossible for vendors such as Opera to add Flash 8 or Flash 9 functionality into their software.

I was worried about issues like this when Adobe bought Macromedia (just after Flash 8 was released).   At the time I heard chilling rumors that they were going to create a Frankenstein’s monster hybrid platform of Flash and Acrobat (not yet confirmed) and they would not be supporting ASP.NET 2.0 with the next version of Flash Remoting (still true).   The decisions are made because (IMHO) Adobe thinks of themselves as an “Enterprise” software vendor, when really they are vendor of excellent tools.   Enterprise vendors strive to make huge corporate deals, sometimes at the expense of their loyal, more individualize customer base.

Adobe has their own agenda and it not necessarily developer friendly.  Let’s hope they can come to their senses and realize that Flash is popular because it has been such and open, developer friendly, platform, and any attempts they make to “reign it in” will only lead to developers jumping to the next platform that gives them the creative freedom and flexibility that is now, and has always been part of Macromedia Flash.

Final Wii Browser: Thoughts

The “final” Opera browser was released for the Wii yesterday, and after using it I have mixed feelings. They added and fixed a few things that must be noted:

  • better interface
  • more responsive button clicks
  • better performance

However, one glaring omission is support for Flash 8.   With tons of Flash 9/Actionscript 3 content already being developed, it is very disappointing that Nintendo decided to not add support for, at least, Flash 8.   One of the main features of Flash 8 that would really improve Wii/Browser games is “External Interface” which would allow calls to JavaScript from Flash to support more buttons on the Wii-mote than just (A).   There have been some kludgy work-arounds for this involving two Flash movies and “Local Connection“, but the performance is not good enough to make usable games that require quick access to the controller buttons.

As it stands right now, the improved performance of Flash 7 content, as well as the much more responsive (A) button will add greatly to already existing Games and content, but without support for Flash 8, it looks like Wii/Browser games will remain a curious and interesting area of development, but not the ideal playground that it could have been.

 

Atari Nerd Chronicles: The Apple Adventure

Sometime around 1981 a wonderful event took place in the lives of two lower-middle class twin boys. Eric Barth, a cool little kid down the street from our house, was given an Apple IIe. Steve and I spent almost every waking minute with Eric exploring the machine and all it had to offer. Without Eric and his Apple, this site would not exist in its current form. There definitely would be a site made by Steve and I, but it would have a named pertaining to some other exciting first time programming or computer game experiment. It could have been the Price Is Right game, random sentence generator, or some other Atari 800 programming adventure.

It might have been called PERTEC-Rocket.com in reference to the VMS (or CPM) based machines our Junior High was given in the 7th grade. Steve and I made a historical adventure game in the modest Junior High computer lab and were featured in Forbes magazine because of it. It might have been named after one of the all time great gaming experiences on the Atari ST : Phantasie I, Dungeon Master, Kick Off II, or Megaroids. It might have been named after a great VCS, 7800, Master System or Lynx game.

It might have been named after one of the Genesis or Nintendo games we played with Ian Legler, one of the Coleco Vision games with Played with Brandon Crist, or one of the Atari 400 games with typed in with Kenny Brown. It might have been an early PC or Fairchild game we played at Wesley Crew’s house. All of those times were defining moments in our computer and game creation education. None of them though can hold a candle to that first year with Eric’s Apple IIe.

The three of us almost went blind staring at that beautiful green screen monitor. We played great games like Apple Panic and Ceiling Zero. We cobbled together pieces of random basic code to make the namesake 8bitrocket programs. We made all kinds of games. We had pretend phone dialers and our own early versions of the a hacker simulator well before the Hacker games were released. We spent countless hours creating machines in Pinball Construction set. I remember that Eric was an exceptional math student and started to create awesome graphical games well before Steve and I could. Anyway, I mention all of this as a thanks to Eric. In the funny world we live in where anyone can Google themselves for fun, Eric found us last week. After almost 20 years with no contact, Eric sent an email to the info@8bitrocket.com box over the weekend. I want to publicly thank him and his father for letting Steve and I ride their Apple IIe coat tails until we got our Atari 800 in 1983. Without Eric, there would be no 8bitrocket. Thanks Eric, and let’s not make it another 20 years before we talk again. You know where to find us.

PC Games are Dead!

That seems a little sensational doesn’t it? Well it is exactly how I feel right now. Even if you don’t take into account the abject failure of Vista or the re-emergence of Nintendo, there are reasons why I feel the PC games are dead. I am even one of those people that hate the term “PC Games” because it has come to mean only Windows/Dos compatible games when the term PC used to mean Personal Computer and referred to many different types of machines. I remember way back in the early 80’s, before I had my own home computer, PC meant Apple, Tandy, Atari, Commodore, and Timex in the USA, and BBC Micro, Sinclair, and Amstrad in the UK.

When the actual sea-change happened I don’t recall. I remember IBM being used to refer to IBM PC software for many many years. I remember seeing it on boxes at the local shops and super stores. It probably happened when the Color MAC failed to take on the IBM compatible machines, and the Atari ST and Amiga when the way of the DoDo. So, rest assured, if you have problems with my use of the word PC to refer to only Windows based machines, I am in agreement. I just don’t know what other term to use right now.

Anyway, as to why PC games are dead? I bought a new HP PC about a year ago. It’s a 2 GIG, Dual Core monster with a mid-range PCI-express video card. It can play a pretty good game of Half-life 2 episode 1, and generally has not had too much difficulty with Direct X 9.0 games. In fact, it plays them very well. So, I was surprised to install the game based on CARS (movie) and find that it wouldn’t run on my machine. I bought it for my son two weeks ago and started down a slippery slope of frustration. I did get it to run two times (which is even stranger) but then it stopped working. I called up the THQ web site and looked for a FAQ. I patched my entire system (video card, sound card, latest XP updates) (as it recommended), put Zone Alarm in “Game Mode”, and even went  as far as flashing the bios of my machine. Still the game would not run. The “helpful” FAQ basically said that my machine was not powerful enough to play this game.  Why then did it play twice and then stop?!?! There is no utility to check for compatibility, no game patches, no help files, just a simple, infuriating FAQ. The major problem with a situation like this is returning PC software is near impossible. I could have brought it back to Target and demanded a fresh copy, but what would that have solved? Yes, if the customer service personnel had given me a shrink wrapped box, I could have used the gift receipt to take it back to a different Target, but what a fucking hassle. A policy like this works with console games because 99.99999999% of the time a console game will be compatible with most (if not all) of the existing versions of that console.

I finally bit the bullet and bought the PS2 version for my son. Now, remember, this is a 5 year old console. Even with the age difference, the game is pretty much the same, and it plays perfectly. On top of that, the visuals look pretty the same as the PC version.  I am sure the Wii and 360 versions look even closer to the PC version. Why would a parent go through all the hassle of trying to play PC games with their children when the same titles can be had on a cheap console? Plus, my wife can play the console version with my son, freeing up the PC for important tasks like checking thesuperficial.com and writing blog entries.

Anyway, I do love computer games, but feel that this is the last PC I will purchase. OK, not the last “PC”, but the last purely Windows based machine I will purchase. A MAC with both boot camp and Parallels will do me fine next time. Since games like CARS come on hybrid PC/MAC media (both version on one disc) I bet I’ll have no trouble getting the game to work on a MAC. So why are PC games dead? Because I know a lot about computers and have been using and programming them as a hobby/profession  for the last 25 years .  When even I have trouble getting a shitty licensed game (although CARS is a good shitty licensed game) to work on a pretty much state of the art machine, how can the soccer/hockey mom down the street be expected to? Soon the the Wii-MAC entertainment combo will take over all of our living room. When it does, I’ll look back to this incident and remember when PC started to mean piece of crap and not personal computer.

 

Dear John (err, I mean Final Fantasy)

Dear Final Fantasy ,

Final Fantasy , do you believe in love?  I hope you do, because I think then you can understand just what I have found. I have found true love and its’ name is Paper Mario. It is the perfect game. We’ve had some good times Final Fantasy, but do to recall those little things that always bothered me about you: your over-serious stories,  tired fantasy setting, and  all that spikey hair?  I overlooked them because I just wanted us to work out, you know? However, I can’t overlook them any longer. I have found the perfect game for me. What’s more, you know how you only ever really tolerated my kids, Final Fantasy.? How they liked you, but you did not always like them back? Paper Mario is not like you at all. It embraces my kids, and it loves them as much as they love it. Soon I will embrace my new true love, just like I did with you. . I will  try to discover its’ history, its’ present, its’ future, and just what it is thinking right now.  Please, no hard feeling Final Fantasy, I wish you the best.  Remember Final Fantasy , I do still care about you, and I hope we can still be friends.  Please remember Final Fantasy , it’s not you, it’s me.

Love always,
Steve

Ode To An Unreleased Game: Atari 5200 Asteroids

Ode To An Unreleased Game: Atari 5200 Asteroids

Prototype lifestyle
Sitting on a shelf somewhere
Waiting to have life

They programmed me to
Launch the 5200
Into hearts and minds

My graphics are great
As if you were in the arcade
But with no vectors

I am unwieldly
I cannot be controlled
I’m a maverick

I am still just code
A burned eprom demo
A shadow, a ghost

I sit in the dark
Longing for a shipping date
Not my destiny

 

This site is protected by Comment SPAM Wiper.