Recent posts by Aesica on Kongregate

Flag Post

Topic: Game Programming / [Solved I think] How to _copy_ semi-transparent pixels?

@player_03: I mainly need draw for things like colortransforms (enemy flashing on-damage), rotation (use once, cache, then copyPixels), and the occasional, sparingly-used blendmode. As someone who’s become something of a performance nut, I’d never use it to replace copyPixels.

Anyway, I think I solved my issue, too (Sorry ErlendHL for accidentally hijacking your thread!) so I’ll post my solution:

SWF

The important stuff is in the FrameHandler function.

package
{
	import aesica.display.SpriteSheet;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	
	/**
	 * ...
	 * @author
	 */
	public class BlitBlendTest extends Sprite
	{
		[Embed(source="../lib/gradient-orbs.png")]
		private static const ColorOrbs:Class;
		
		private static const ORB_COUNT:int = 200;
		private static const ORB_TOP_SPEED:Number = 1;
		
		private static const MODE_COPYPIXELS:int = 0;
		private static const MODE_DRAW_NORMAL:int = 1;
		private static const MODE_DRAW_BLEND_MULTIPLY:int = 2;
		private static const MODE_DRAW_BLEND_DARKEN:int = 3;
		private static const MODE_DRAW_BLEND_LIGHTEN:int = 4;
		private static const MODE_DRAW_BLEND_OVERLAY:int = 5;
		private static const MODE_DRAW_BLEND_SCREEN:int = 6;
		private static const MODE_DRAW_BLEND_DIFFERENCE:int = 7;
		private static const MODES:Vector.<String> = new <String>["CopyPixels/Control Group", "Draw:Normal", "Draw:BlendModeMultiply", "Draw:BlendModeDarken", "Draw:BlendModeLighten", "Draw:BlendModeOverlay", "Draw:BlendModeScreen", "Draw:BlendModeDifference"];
		
		private var ssOrbs:SpriteSheet;
		private var bmpCanvas:BitmapData;
		private var aOrbBitmapDataIDs:Vector.<int>;
		private var aOrbPoints:Vector.<Point>;
		private var aOrbVelocities:Vector.<Point>;
		private var aDrawRects:Vector.<Rectangle>;
		private var bmpBackground:BitmapData;
		private var lZeroPoint:Point;
		private var iMode:int = 1;
		private var lblMode:TextField;
		private var mModeSwitch:Sprite;
		private var mBackgroundSwitch:Sprite;
		
		public function BlitBlendTest()
		{
			ssOrbs = new SpriteSheet(new ColorOrbs() as Bitmap);
			bmpCanvas = new BitmapData(800, 600, true, 0xffffffff);
			bmpBackground = new BitmapData(800, 600, true, 0xffffffff);
			RandomizeBackground();
			lZeroPoint = new Point();
			
			var i:int;
			var iSpriteSheetSize:int = ssOrbs.aSpriteRect.length;
			aOrbBitmapDataIDs = new Vector.<int>(ORB_COUNT);
			aOrbPoints = new Vector.<Point>(ORB_COUNT);
			aOrbVelocities = new Vector.<Point>(ORB_COUNT);
			aDrawRects = new Vector.<Rectangle>(ORB_COUNT);
			for (i = 0; i < ORB_COUNT; i++)
			{
				aOrbBitmapDataIDs[i] = Math.floor(Math.random() * iSpriteSheetSize);
				aOrbPoints[i] = new Point();
				aOrbVelocities[i] = new Point(Math.random() * ORB_TOP_SPEED, Math.random() * ORB_TOP_SPEED);
				aDrawRects[i] = new Rectangle(0, 0, ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].width, ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].height);
			}
			
			var mCanvas:Bitmap = new Bitmap(bmpCanvas);
			addChild(mCanvas);
			
			mModeSwitch = new Sprite();
			lblMode = QuickTextField("[Change Mode (Currently " + MODES[iMode] + ")]");
			mModeSwitch.addChild(lblMode);
			
			mBackgroundSwitch = new Sprite();
			mBackgroundSwitch.addChild(QuickTextField("[Randomize Background]"));
			
			mBackgroundSwitch.buttonMode = mBackgroundSwitch.useHandCursor = mModeSwitch.buttonMode = mModeSwitch.useHandCursor = true;
			mBackgroundSwitch.x = 800 - mBackgroundSwitch.width;
			
			addChild(mModeSwitch);
			addChild(mBackgroundSwitch);
			
			addEventListener(Event.ADDED_TO_STAGE, Init, false, 0, true);
		}
		
		private function QuickTextField(sMessage:String):TextField
		{
			var lblReturn:TextField = new TextField();
			lblReturn.selectable = lblReturn.mouseEnabled = false;
			lblReturn.autoSize = "left";
			lblReturn.defaultTextFormat = new TextFormat("Arial", 16, 0xffffff);
			lblReturn.filters = [new GlowFilter(0, 1, 2, 2, 10)];
			lblReturn.text = sMessage;
			
			return lblReturn;
		}
		
		private function RandomizeBackground(e:MouseEvent = null):void
		{
			bmpBackground.perlinNoise(Math.random() * 250 + 1, Math.random() * 250 + 1, Math.floor(Math.random() * 10) + 1, Math.floor(Math.random() * 9000), ((Math.floor(Math.random()) < 0.5) ? true : false), ((Math.floor(Math.random()) < 0.5) ? true : false), Math.floor(Math.random() * 15));
		}
		
		private function Init(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, Init);
			addEventListener(Event.REMOVED_FROM_STAGE, Dispose, false, 0, true);
			addEventListener(Event.ENTER_FRAME, FrameHandler, false, 0, true);
			mModeSwitch.addEventListener(MouseEvent.CLICK, Clicked, false, 0, true);
			mBackgroundSwitch.addEventListener(MouseEvent.CLICK, RandomizeBackground, false, 0, true);
		}
		
		private function Dispose(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, Init);
			removeEventListener(Event.REMOVED_FROM_STAGE, Dispose);
			removeEventListener(Event.ENTER_FRAME, FrameHandler);
			mModeSwitch.removeEventListener(MouseEvent.CLICK, Clicked);
			mBackgroundSwitch.removeEventListener(MouseEvent.CLICK, RandomizeBackground);
		}
		
		private function FrameHandler(e:Event):void
		{
			bmpCanvas.lock();
			var i:int;
			var oMatrix:Matrix;
			bmpCanvas.fillRect(bmpCanvas.rect, 0xff000000);
			bmpCanvas.copyPixels(bmpBackground, bmpBackground.rect, lZeroPoint, null, null, true);
			for (i = 0; i < ORB_COUNT; i++)
			{
				if (aOrbPoints[i].x < 0 || aOrbPoints[i].x > bmpCanvas.width - ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].width)
				{
					aOrbVelocities[i].x *= -1;
				}
				if (aOrbPoints[i].y < 0 || aOrbPoints[i].y > bmpCanvas.height - ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].height)
				{
					aOrbVelocities[i].y *= -1;
				}
				
				aOrbPoints[i].x += aOrbVelocities[i].x;
				aOrbPoints[i].y += aOrbVelocities[i].y;
				
				if (iMode == MODE_COPYPIXELS)
				{
					bmpCanvas.copyPixels(ssOrbs.bmpSpriteSheet, ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]], aOrbPoints[i], null, null, true);
				}
				else
				{
					oMatrix = new Matrix();
					oMatrix.translate(aOrbPoints[i].x - ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].x, aOrbPoints[i].y - ssOrbs.aSpriteRect[aOrbBitmapDataIDs[i]].y);
					aDrawRects[i].x = aOrbPoints[i].x;
					aDrawRects[i].y = aOrbPoints[i].y;
					
					if (iMode == MODE_DRAW_NORMAL)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, null, aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_MULTIPLY)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.MULTIPLY, aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_DARKEN)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.DARKEN, aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_LIGHTEN)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.LIGHTEN , aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_SCREEN)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.SCREEN, aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_OVERLAY)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.OVERLAY, aDrawRects[i]);
					}
					else if (iMode == MODE_DRAW_BLEND_DIFFERENCE)
					{
						bmpCanvas.draw(ssOrbs.bmpSpriteSheet, oMatrix, null, BlendMode.DIFFERENCE, aDrawRects[i]);
					}
				}
				
			}
			bmpCanvas.unlock();
		}
		
		private function Clicked(e:MouseEvent):void
		{
			iMode++;
			if (iMode >= MODES.length)
			{
				iMode = 0;
			}
			
			lblMode.text = "[Change Mode (Currently " + MODES[iMode] + ")]";
		}
	
	}

}

PS: Sorry for the ridiculous lack of comments, and hopefully my variable prefixes aren’t too annoying to look at.

 
Flag Post

Topic: Game Programming / [Solved I think] How to _copy_ semi-transparent pixels?

There is no sourceRect for draw — the closest thing is clipRect but that does something entirely different. I’m starting to think that the only way to draw a single sprite from a sprite sheet via draw involves making a temporary bitmapdata, copypixeling the sprite in question to it, and then in turn using draw to place that temporary bitmapdata onto the canvas. Eww.

 
Flag Post

Topic: Game Programming / [Solved I think] How to _copy_ semi-transparent pixels?

The main limitations (which I really need to find a way around) are no rotation, scaling, blendmodes, color transforms, etc. And in my case, I can’t figure out how to use draw to place a single sprite instead of the entire sheet. Probably involves something with matrices which hurt my head enough as it is. :)

 
Flag Post

Topic: Game Programming / [Solved I think] How to _copy_ semi-transparent pixels?

Originally posted by Draco18s:

It will copy, but it won’t blend. It’ll overwrite the destination color value rather than multiplying.

They don’t entirely overwrite, unless you’re specifically referring to the multiple blendmode or something else entirely.

Click the stage to cycle render modes, and excuse the weirdness that happens with draw because I have no idea how to select a single sprite from a spritesheet with draw because I never really use it. (It’s drawing the whole sprite sheet instead of just one of the colored bubbles) Oh, and excuse the loading time. Because of laziness, I made this on top of an existing project instead of just making a new one. Trying out things like this in such a way is one of my shamefully bad habits. :(

 
Flag Post

Topic: Game Programming / GiTD #42 - *Pirates*

Originally posted by Draco18s:

God, you have no idea how much I want someone to remix those lyrics with the theme from Pirates of the Caribbean.

The best part is that it’s a cover of this song.

Originally posted by Shalmezad:

If I get a song stuck in my head because of this theme, I’m picking llamas next time so I can return the favor.

Not if I beat you to it: http://youtu.be/ZeCm793CFZo

 
Flag Post

Topic: Game Programming / [Solved I think] How to _copy_ semi-transparent pixels?

Originally posted by Draco18s:

Copy Pixels can’t do transparency. You have to use Draw()

I hope I’m just misinterpreting something here, because copyPixels most certainly will copy partially-transparent BMDs. I suspect what’s going on is what Amibtious said, and the only workaround I can think of involves either drawing the circle with more opacity or using lines thicker than 1 pixel.

 
Flag Post

Topic: Game Programming / GiTD #42 - *Pirates*

Originally posted by Shalmezad:

(of course, some of you may want to consider that piracy means something completely different now that what it used to)

NO! All games MUST be about looting, plundering and sailing the seven seas, matey! I just hope I can come up with something worthy of the theme. In the meantime, this should help set the mood a bit: http://youtu.be/xDVdo2-JGtg

 
Flag Post

Topic: Game Programming / Sprite Sheet Animation Demo 1.1

Nice. Anything that exposes more people to blitting instead of clunky sprites or movieclips is good in my book. I was about to crack down on the use of magic numbers, but it looks like that’s already been addressed. My only other thoughts could just be the result of doing things differently, why did you use ex and why? Does the monster class use x and y for something else? Also, tracking the movement direction by 0-3 instead of 0-359 could be problematic in situations where you want to utilize omni-directional movement.

 
Flag Post

Topic: Game Programming / Need Help

Was it that bad? Oops… sorry :(

 

Topic: Game Programming / Need Help

This post has been removed by an administrator or moderator
 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

One thing I noticed: If I select a hex, then click the buttons to go back or forward a level, the selected location remains selected. It doesn’t seem exploitable though.

 
Flag Post

Topic: Game Programming / as3 what is the most efficient way to use enterframes

What I did for the game of mine that used displayobjects (sprites in particular) instead of blitting was that the container class (I called it “GameContainer”) I added all the sprites to also held the arrays. So, when I needed to add something to the stage, I’d also add it to the array. When it was time to remove something from the stage, it would get removed from the array in the line right after. Basically, whenever you intend to remove something from the stage, remove it from the array at the same time.

// any time you might do this:
removeChild(arrayOrVectorOfStuff[i]);
// do this right afterward:
arrayOrVecorOfStuff.splice(i, 1); // edit:  I can't remember the last time I used splice, so I hope this is correct

Once you get that down, note that there’s an even faster way to remove things from an array:

arrayOrVectorOfStuff[i] = arrayOrVectorOfStuff[arrayOrVectorOfStuff.length - 1];
arrayOrVectorOfStuff.length--;
i--;

In both cases, the variable “i” is of course implying a for loop. I’m just too lazy to open FD and deal with proper tabbing this time. :)

 
Flag Post

Topic: Game Programming / as3 what is the most efficient way to use enterframes

Well I kind of did give an example. Let’s say you have a coin class, an enemy turtle class, and a player class. With several coins, turtles, and the player on the screen, that could either be a bunch of different enter-frame events (one for each object) or you could have just one class with one enter-frame function that loops through an array of coins, turtles, and players and calls what would’ve been their enter-frame function, all without the excess overhead of a dozen+ different enterframes firing off 30-60 times a second.

 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

This just goes to show how important instructions and an intuitive interface can be. Now that I actually understand how this game works, I feel like I sold it short in the contest because it’s rather clever. In addition to what was already suggested (particularly, highlighting viable paths when a hex is selected) allowing a move to trigger when ANY space along the movement path is clicked would make the concept easier to grasp.

 
Flag Post

Topic: Game Programming / as3 what is the most efficient way to use enterframes

@chachon2: Go for it. :D

@a3lex33: My entry in the most recent gitd thread uses this method, as does the first game I made. If you have the patience to reach the final boss, you’ll find there’s a LOT of things flying around on the screen and a surprisingly small amount of lag despite that. While neither of these games are all that great overall, they do perform exceptionally compared to games that use multiple enterframe events. There’s also this thing I made when I first explored the concept of blitting over using standard displayobjects. As you can see, even with normal displayobjects, using a single enter frame function over several hundred allows thousands of things to fly around the screen before performance hits start to kick in.

 
Flag Post

Topic: Game Programming / as3 what is the most efficient way to use enterframes

Kind of like this:

	public class GameContainer 
	{
		// vector (or array, if you must) that you will populate with objects that need to execute something every frame
		private var aBunchOfGameObjects:Vector.<GameObject>;
		
		public function GameContainer() 
		{
		}
		
		// this is a single enter frame function
		private function FrameHandler(e:Event):void
		{
			var i:int;
			var iLength:int = aBunchOfGameObjects.length;
			
			// cycle through all of your game objects, or whatever, and do stuff with them
			for (i = 0; i < iLength; i++)
			{
				aBunchOfGameObjects[i].StuffToDoEveryFrame();
			}
		}
		
	}

Also don’t forget to remove any event listeners for objects you no longer have references to. Excessive enter frame events will lag you, not removing event listeners will lag you too, because they (annoyingly enough) don’t clean up on their own.

Also, about weak references: It’s my understanding that weak references are NOT self cleaning either. What they do is allow an object to be collected if no other references to it remain. The listener itself still remains though.

 
Flag Post

Topic: Game Programming / People are losting gave save

Just trying to cover all bases, but do they have their flash storage set to unlimited? If not, newer saves from other games on that site will overwrite older ones. Also, right after the last line in the saveGame function: myLSO.data.myObj = myObj;, you’ll want to add myLSO.flush(); to force everything to be written. If you don’t, you’re at the mercy of flash to flush() at its discretion, which may not happen under various circumstances. (such as if flash crashes)

 
Flag Post

Topic: Game Programming / Feedback to my new game (critics are very welcome)

Here’s some things that will help:

1) Upgrade to AS3. I can’t remember the exact number, but AS3 is anywhere from 10x to 100x faster than AS2. At this point in Flash’s lifespan, learning AS2 instead of AS3 is a complete and total mistake.

2) Only have a single enter frame function in a single class. That enter frame function should be cycling through an array of any other objects that need to do something every frame. Just remember to remove those objects from the array when you remove them from the game field.

3) Use bitmaps instead of vector art. Vector art is horribly slow compared to bitmaps. I know vector art is a feature thing with flash, but it’s really not very efficient…at least I’ve never found it to be.

4) 7000×4000? I’m assuming you mean the entire level, right? Try not to place (or animate) any objects on the gamefield that are offscreen.

You shouldn’t need to downgrade your fps to 24 if you optimize the other things. Some people (like me) think 30 fps looks pretty choppy. 24 will look even worse.

 
Flag Post

Topic: Game Programming / Feedback to my new game (critics are very welcome)

Just tried it out and…holy crap, the lag is indescribably bad and makes it pretty much unplayable. Plus, all I can make the guy do is jump. Have you implemented other movement controls yet? Well no matter, it’s okay to do a ripoff game for your first, even if it isn’t as advanced as what you’re ripping off, because the primary goal is to learn how to make a game rather than to make an award-winner.

Anyway, before doing anything else with it, you need to do some serious optimizations. Like, critically so.

PS: If you plan on uploading it for feedback from a small group of people rather than an entire website such as kong where the average player will say “it’s bad” unless it’s perfectly polished and publish-ready, consider uploading to fastswf.com instead of…whatever that other site was.

 
Flag Post

Topic: Game Programming / Array elements

In short, no. Vectors might be closer to what you’re looking for. They’re the array’s faster cousin, although it’s important to note that they only accept the object type (and any subclasses of that type) they are originally defined for.

// creates a vector with 5 null elements that will accept sprite objects
var someVector:Vector<Sprite> = new Vector<Sprite>(5);
someVector[1] = new Sprite(); // allowed
someVector[3] = new Point(); // throws a type error because a Point isn't related to a Sprite
someVector[21] = new Sprite(); // throws an out-of-range error

// vs the array created with 5 elements initially
var someArray:Array = new Array(5);
someArray[1] = new Sprite(); // allowed
someArray[3] = new Point(); // allowed, even though it's not related to sprites at all
someArray[21] = new Sprite(); // allowed, the array simply grows to accommodate for some sick reason
// I don't really use arrays in AS3 because I think they suck balls, so if I'm wrong about any of it, someone say so.
 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

The turnout for these just isn’t what it used to be. :(

 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

Oh, I meant to say this yesterday when it was more relevant, but I forgot. Yesterday’s (July 1st) badge of the day was for a game with randomly generated levels. Fitting, wouldn’t you guys say?

but I wish they could have had a bigger/better area to showcase those behaviors. The hero appears to be quite overpowered at the moment with his massive health and wall piercing shots, might just be so noobies like me get to actually see the boss.

The player was overpowered because I never got around to properly tuning difficulties. Time constraints and all. :D As for there not being enough room for the enemies to do their little turns on the catwalk, scrolling is the main thing I wanted to add, but didn’t have time for. (I’m not too fond of the single-screen levels myself) Not only is it less interesting for the players, but makes it difficult to come up with interesting and varied levels after awhile.



Originally, there was going to be twice as many areas as this.

 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

^ Yup, that's the right version!

Lunar Hex: I'm not exactly sure what I'm supposed to do. Sometimes, I can get a piece to move one hex, but that's really about it. Also, during one "generate new" attempt, my browser stalled for some reason. I haven't been able to reproduce it, so maybe it was just something else in another tab, as I tend to have 4 tabs at the very least open at any given time.

Pixel Wars: "xxx" seems to generate a fairly powerful pixel-thing. Hurray for porn! Anyway the concept reminds me some old "game" (you didn't really get to do much in it) called My Brute, or something like that, which also generated stats and other things based on the player's choice of name. I just wish there was more variation in enemy behavior than what was currently offered.

Alright, votes:

1st - Shalmezad: Pixel Wars
2nd - Shake_N_Baker: Lunar Hex

Controls are good, except for flying, which is just weird (I know it wasn’t really flying… So why did you keep it in?). Regular enemies were more difficult than the boss, who was really slow and predictable.
I left the flying in because, well because I never got around to removing it or limiting it with a flight bar or something. The boss doesn't really have much in terms of AI that the random enemies don't, other than the switch to home in on a target (the player) and pass through walls. He's harder if you don't fly the whole time. :)
 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

Originally posted by Shalmezad:

Fixed per Aesica’s note.

That’s definitely the wrong one. The version that made it in just before the deadline is the last one I posted in the other thread. This version.

 
Flag Post

Topic: Game Programming / GiTD #41 - *Congratulations Aesica*

My link broke because I goofed up. When I uploaded the version with the boss lair proximity detector, I deleted the other one because at the time, I saw no reason to keep an outdated version in one of my fastswf account slots. Then I realized, "9 EST, not 9 PST. Oops. Anyway I’ll do all the voting/etc stuff later when I have more time.

Thus, people should be voting on the version without the boss lair proximity detector, since that’s the last version that made it in before the deadline.