9

I work on a 2D shooter game with lots of moving objects on the screen (bullets etc).

I use BitmapData.copyPixels(...) to render entire screen to a buffer:BitmapData. Then I "copyPixels" from "buffer" to screen:BitmapData. The framerate is 60.

private var bitmap:Bitmap = new Bitmap();
private var buffer:Bitmap = new Bitmap();

private function start():void {
    addChild(bitmap);
}

private function onEnterFrame():void {
    // render into "buffer"
    // copy "buffer" -> "bitmap"
}

The problem is that the sprites are tearing apart: some part of a sprite got shifted horizontally.

It looks like a PC game with VSYNC turned off.

Did anyone solve this problem?

UPDATE: the question is not about performance, but about getting rid of screen tearing.

[!] UPDATE: I've created another question and here you may try both implementations: using Flash way or BitmapData+copyPixels()

Community
  • 1
  • 1
oshyshko
  • 2,008
  • 2
  • 21
  • 31
  • Screen tearing is related to performance. That's the only way to fix your tearing. – Kekoa Jun 16 '09 at 17:54
  • 3
    @Kekoa I can't agree. Performance has nothing to do with screen tearing, because I use double-buffer. In case of poor performance I would get lower FPS but not screen tearing. – oshyshko Jun 17 '09 at 17:44
  • the others are right, that this approach isn't very suitable for flash player ... still, i'm amazed, it doesn't work at all ... few questions: - did you try to lock the bitmapData you are drawing into? (if not, this may help a lot!) - are you using transparent bitmaps? (general performance killer) - dir you try `Stage::invalidate` and rendering on `Event.RENDER` instead of rendering? greetz back2dos – back2dos Jun 13 '09 at 10:03
  • - lock/unlock didn't help because copying "buffer" -> "bitmap" produces single event, so it is same single notification in both cases - I do use transparent bitmaps for projectiles - but, again, the problem is not in performance, the problem is in screen tearing - I tried to: * prepare "buffer" + stage.invalidate() in ENTER_EVENT and then * copy "buffer" -> "bitmap" in RENDER event Same result (screen tearing), but higher CPU consumption(I guess because it is because of events fired by stage.invalidate() ) – oshyshko Jun 13 '09 at 12:12

3 Answers3

7

I feel your pain as I'm currently in the trenches developing my own game. At default settings, the Flash renderer produces horrible screen tearing / v-sync issues, regardless of what code you produce.

This is why I was pleased to have found the most simple, elegant answer, that wasn't re-factoring code (which doesn't help a single bit, the problem is the Flash player, not code).

Just enable Hardware Acceleration in your Publish Settings. There's two different options:

Level 1: Direct; and Level 2: GPU.

Read more about it at the official documentation: Specify publish settings for SWF files, and decide what option is best for your game.

Target market does play a factor here, if it's a serious game for gamers, you don't need to worry about possible performance issues, as most gamers have GPU's.

This article did not provide me with the solution specifically, but lead me in the right direction. BUT, if your game is going to be in a browser window, you might have to use the same technique of setting wmode to direct or gpu as well.

Daniel Carvalho
  • 557
  • 2
  • 8
  • 20
  • Do you happen to know if there's a metadata tag attribute that can be specified for that? (For FlashDevelop AS-only games, without FLAs). Something along the lines: [SWF(hardwareAcc="gpu")] does that exists? – chamberlainpi Nov 05 '10 at 14:55
  • The only other parameter I know of is wmode, which can be set in the html file embedding your Flash file. I'm sure there must be something that can achieve this without the Flash IDE. – Daniel Carvalho Nov 16 '10 at 08:36
  • What's the conclusion? This is really a Flash player's problem and we can't do anything to improve it? – Huang F. Lei May 18 '11 at 17:50
  • Well, yes and no. Without enabling some kind of hardware acceleration in Flash, screen tearing will occur. If you enable it, Flash will render fine. – Daniel Carvalho May 19 '11 at 20:36
  • Even with some hardware rendering, tearing can still occur. I tried it using Context3D at 60fps with context.clear(random color). Tearing still occurs, albeit a little bit better than before where it was really obvious. – ansiart Oct 05 '11 at 02:56
  • http://active.tutsplus.com/tutorials/animation/quick-tip-fixing-v-sync-tearing-issues-in-flash/ really helped me. Tells you to set wmode to direct in your html. – Frank Aug 02 '12 at 02:06
-4

First thing you might want to do is stop treating the Flash Player like it is DOS. The Flash Player is a highly optimized 2D game engine as it is and I don't really understand why you are trying to reinvent the wheel by copying lots of bitmap slices around. Of course you will have performance issues.

The Flash Player doesn't let you sync to any vertical or horizontal blank because the Flash Player simply doesn't have any concept of this.

I personally think that you should rethink you approach if you want 'smoother' animation. The Flash Player is certainly capable of this, you're just trying the wrong approach.

Luke
  • 20,878
  • 35
  • 119
  • 178
  • 2
    Strange thing, copying chucks of bytes (bitmaps) in memory should be easier for computer rather than rendering it with math calculations. There should be a reason why "cacheAsBitmap" exist in Flash. Also, check this: http://aralbalkan.com/759 – oshyshko Jun 13 '09 at 00:21
  • Your Sprites (DisplayObject's) do not have to be vector at all. The Flash Player is optimized to deal with this. When you start to recreate in ActionScript with bitmaps what the Flash Player already does very well and is optimized for, then you're just missing the point. I think you should read more of Tinic Uro blog: http://www.kaourantin.net – Luke Jun 13 '09 at 00:29
  • 2
    @Luke: Your answer would be more useful if it suggested a practical alternative, rather than just saying the original approach is wrong. There are several sources online suggesting the use of bitmaps and copyToPixels in the context of making 2D games so it's not the original poster who's doing the reinventing. – Kylotan Jun 15 '09 at 09:30
-5

Don't save things to BitmapData, that will kill, absolutely kill your app. Bitmap Data is not very performant.

Make all your game elements in flash, as Sprites(or MovieClips if you must), and then work how flash was meant to work, as a vector animation platform. It was never optimized for 2d bitmap graphics. 2d vector graphics work well, and even if you import bitmaps they will work better moving around then they will rendered to a BitmapData object.

Kekoa
  • 27,892
  • 14
  • 72
  • 91
  • If I'll give up with buffering and add bitmaps as native Flash sprites (still bitmaps), then will it solve the VSYNC problem? – oshyshko Jun 13 '09 at 00:10
  • No it won't. But it will look far better than what you currently have. As I said in my answer to your question, the Flash Player has no concept of vsync. When you set the fps to 60 (which is absurd but that's beside the point) then the Flash Player will TRY to generate 60 fps. In reality it will almost never accomplish this. – Luke Jun 13 '09 at 00:32
  • 1
    I've found there are defininitely times you should use Bitmapdata for performance improvement. – Matt W Jun 16 '09 at 02:17
  • @Matt But your entire app, rendered in a BitmapData object every frame? This is seriously a bad idea. I'm not saying BitmapData is not useful. – Kekoa Jun 16 '09 at 17:52