Flash too slow?

Subscribe to Flash too slow? 23 posts, 6 voices

Sign in to reply


 
avatar for Pimgd Pimgd 725 posts
Flag Post
So, since I have vacation again, I tried making something again.
This time, I went for something danmaku-style, since I have been playing way too much Touhou. But oh well.

The problem is, once ~500 bullets are on the screen, the game starts uh... lagging. I'm running it at 60 FPS, maybe too high, but without those 60 FPS, the game looks slow.
I added spellcards (preset patterns) too it, causing it too lag waaaay more. Only during one of those spellcards though. Here's a link to the uploaded swf: http://www.freewebs.com/pimgdtextrpg/TouhouDanmaku.swf

Controls: Arrow keys for moving, hold shift to focus (move slower, and show hitbox)

Is it normal for flash to start lagging at this point, or did I fail at coding? I used arrays and functions and classes and other stuff to run most of the code only once. (bullets go through ~100 lines of direction and other stuff settings, and use 20 lines for flying + graze)
I also ripped a lo- all the sprites from Touhou, as I was just funning around. But I'm trying to learn, so hey, why not.

As for the code:

//on character
onClipEvent(load){ stop(); }
onClipEvent(enterFrame){
	_global.enemyTimer++;
	_global.gameTime++;
	_global.scoreTimer++;
	if(_global.scoreTimer == 10){
		_global.score += _global.difficulty;
		_global.scoreTimer = 0;
	}
	if(_global.bulletsdead == 2){
		_global.bulletsdead = 0;
	}
	if(_global.gameTime == 1800){
		_global.spellcard = 1;
		_global.bulletsdead = 2;
	}
	if(Key.isDown(key.SHIFT)){
		this.gotoAndStop(2);
		if(Key.isDown(key.LEFT)){
			this._x = this._x - 1;
		}
		if(Key.isDown(key.RIGHT)){
			this._x = this._x + 1;
		}
		if(Key.isDown(key.UP)){
			this._y = this._y - 1;
		}
		if(Key.isDown(key.DOWN)){
			this._y = this._y + 1;
		}
	} else {
		this.gotoAndStop(1);
		if(Key.isDown(key.LEFT)){
			this._x = this._x - 2.5;
		}
		if(Key.isDown(key.RIGHT)){
			this._x = this._x + 2.5;
		}
		if(Key.isDown(key.UP)){
			this._y = this._y - 2.5;
		}
		if(Key.isDown(key.DOWN)){
			this._y = this._y + 2.5;
		}
	}
	if(this._x < 13.5){
		this._x = 14;
	} else if(this._x > 486.5){
		this._x = 486;
	}
	if(this._y < 21){
		this._y = 21.5;
	} else if(this._y > 479){
		this._y = 478.5;
	}
	if(_global.bulletsdead == 0 && _global.spellcard == 0){
		if(_global.difficulty == 1){
			if(_global.enemyTimer >= 25){
				_global.enemyTimer = 0;
				var Spawner = _root.attachMovie("Spawner", "Spawner"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner.spawntype = new Array(1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0);
				Spawner.inspellcard = 0;
			}
		} else if(_global.difficulty == 2){
			if(_global.enemyTimer >= 20){
				_global.enemyTimer = 0;
				var Spawner = _root.attachMovie("Spawner", "Spawner"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0);
				Spawner.inspellcard = 0;
			}
		} else if(_global.difficulty == 3){
			if(_global.enemyTimer >= 15){
				_global.enemyTimer = 0;
				var Spawner = _root.attachMovie("Spawner", "Spawner"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0);
				Spawner.inspellcard = 0;
			}
		} else if(_global.difficulty == 4){
			if(_global.enemyTimer >= 10){
				_global.enemyTimer = 0;
				var Spawner = _root.attachMovie("Spawner", "Spawner"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner.spawntype = new Array(2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,0);
				Spawner.inspellcard = 0;
			}
		}
	}
	if(_global.bulletsdead == 1){
		_global.lifecounter++;
		if(this._alpha == 100){
			this._alpha = 0;
		} else if(this._alpha == 0){
			this._alpha = 100;
		}
		if(_global.lifecounter >= 60){
			_global.bulletsdead = 0;
			_global.lifecounter = 0;
			this._alpha = 100;
		}
	}
	if(_global.spellcard == 1){
		_global.spellcard1Time++;
		if(_global.spellcard1Time < 50){
			if(_global.spellcard1Time == 1){
				_global.spellcardmsg = 1;
			}
			if(_global.spellcard1Time == 10){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 50;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1); 
			} else if(_global.spellcard1Time == 20){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 75;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 30){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 100;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 40){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 125;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			}
		} else if(_global.spellcard1Time < 100){
			if(_global.spellcard1Time == 50){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 150;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 60){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 175;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 70){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 200;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 80){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 225;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 90){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 250;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} 
		} else if(_global.spellcard1Time < 150){
			if(_global.spellcard1Time == 100){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 275;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 110){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 300;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 120){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 325;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 130){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 350;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 140){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 375;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			}
		} else if(_global.spellcard1Time < 200){
			if(_global.spellcard1Time == 150){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 400;
				Spawner._y = 150;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 160){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 25;
				Spawner._y = 450;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0);
			} else if(_global.spellcard1Time == 170){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 475;
				Spawner._y = 450;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0);
			} else if(_global.spellcard1Time == 180){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 55;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} else if(_global.spellcard1Time == 190){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 80;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1);
			} 
		} else if(_global.spellcard1Time < 250){
			if(_global.spellcard1Time == 200){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 105;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 210){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 130;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 220){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 155;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 230){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 180;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 240){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 205;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			}
		} else if(_global.spellcard1Time < 300){
			if(_global.spellcard1Time == 250){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 230;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 260){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 255;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 270){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 280;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 280){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 305;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			} else if(_global.spellcard1Time == 290){
				var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
				Spawner._x = 330;
				Spawner._y = 100;
				Spawner.inspellcard = 1;
				Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
			}
		}
		if(_global.spellcard1Time == 300){
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 355;
			Spawner._y = 100;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
		}
		if(_global.spellcard1Time == 310){
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 380;
			Spawner._y = 100;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
		}
		if(_global.spellcard1Time == 320){
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 405;
			Spawner._y = 100;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
		}
		if(_global.spellcard1Time == 400){
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 20;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 30;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 40;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 50;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 450;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 460;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 470;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 480;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1);
		}
		if(_global.spellcard1Time == 450){
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 50;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 70;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 90;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 110;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 130;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 150;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 170;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 190;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 210;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 230;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 250;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 270;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 290;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 310;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 50;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 70;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 90;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 110;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 130;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 150;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 170;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 190;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 210;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 230;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 250;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 270;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 290;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 310;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 10;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 20;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 30;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 40;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 50;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 60;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 70;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 80;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 90;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 100;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 490;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 480;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 470;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 460;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 450;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 440;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 430;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 420;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 410;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
			var Spawner = _root.attachMovie("Spawner","Spawner" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
			Spawner._x = 400;
			Spawner._y = 10;
			Spawner.inspellcard = 1;
			Spawner.spawntype = new Array(0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0);
		}
		if(_global.spellcard1Time == 900){
			_global.spellcard1Time = 0;
			_global.spellcard = 0;
		}
	}
}
//==================================

//Spawner Class:

class Spawner extends MovieClip
{
	var disappear;
	var bulletcounter;
	var inspellcard;
	var spawntype;
	var dir;
	var i;
	function onLoad()
	{
		disappear = 1;
		bulletcounter = 0;
		this._visible = false;
		if(inspellcard == 0){
			_x = random(400) + 50;
			_y = random(300) + 50;
		}
		if((_x < (_root.HakureiReimuMC._x + 50)) and (_x > (_root.HakureiReimuMC._x - 50)) and (_y < (_root.HakureiReimuMC._y + 50)) and (_y > (_root.HakureiReimuMC._y - 50))){
			this.removeMovieClip();
		}
	}
	function onEnterFrame()
	{
		bulletcounter++;
		if(bulletcounter >= 1){
			for(i = 0; i<(spawntype.length - 1); i++){
				if(spawntype[i] == 1){
					dir = i + 1;
					var Bullet = _root.attachMovie("Bullet","Bullet" + _root.getNextHighestDepth(), _root.getNextHighestDepth());
					Bullet._x = _x;
					Bullet._y = _y;
					Bullet.dir = dir;
				}
			}
			if(spawntype[16] == 1){
				dir = 999;
				var Bullet = _root.attachMovie("Bullet","Bullet" +_root.getNextHighestDepth(), _root.getNextHighestDepth());
				Bullet._x = _x;
				Bullet._y = _y;
				Bullet.dir = dir;
			}
			bulletcounter = 0;
		}
		disappear--;
		if(disappear <= 0){
			this.removeMovieClip();
		}
	}
}

//========================================

//Bullet class:

class Bullet extends MovieClip
{
	var yspeed;
	var xspeed;
	var dir;
	var dy;
	var dx;
	var grazed;
	function onLoad()
	{
		stop();
		_global.bullets++;
		grazed = false;
		if(dir == 1){
			yspeed = -1;
			xspeed = 0;
			_rotation = 0;
		} else if(dir == 2){
			yspeed = -0.75;
			xspeed = 0.25;
			_rotation = 22.5;
		} else if(dir == 3){
			yspeed = -0.5;
			xspeed = 0.5;
			_rotation = 45;
		} else if(dir == 4){
			yspeed = -0.25;
			xspeed = 0.75;
			_rotation = 67.5;
		} else if(dir == 5){
			yspeed = 0;
			xspeed = 1;
			_rotation = 90;
		} else if(dir == 6){
			yspeed = 0.25;
			xspeed = 0.75;
			_rotation = 112.5;
		} else if(dir == 7){
			yspeed = 0.5;
			xspeed = 0.5;
			_rotation = 135;
		} else if(dir == 8){
			yspeed = 0.75;
			xspeed = 0.25;
			_rotation = 157.5;
		} else if(dir == 9){
			yspeed = 1;
			xspeed = 0;
			_rotation = 180;
		} else if(dir == 10){
			yspeed = 0.75;
			xspeed = -0.25;
			_rotation = 202.5;
		} else if(dir == 11){
			yspeed = 0.5;
			xspeed = -0.5;
			_rotation = 225;
		} else if(dir == 12){
			yspeed = 0.25;
			xspeed = -0.75;
			_rotation = 247.5;
		} else if(dir == 13){
			yspeed = 0;
			xspeed = -1;
			_rotation = 270;
		} else if(dir == 14){
			yspeed = -0.25;
			xspeed = -0.75;
			_rotation = 292.5;
		} else if(dir == 15){
			yspeed = -0.5;
			xspeed = -0.5;
			_rotation = 315;
		} else if(dir == 16){
			yspeed = -0.75;
			xspeed = -0.25;
			_rotation = 337.5;
		} else if(dir == 999){
			this.gotoAndStop(2);
			dx = (this._x - (_root.HakureiReimuMC._x));
			xspeed = (dx*dx)/dx;
			if(xspeed < 0){
				xspeed = xspeed*-1;
			}
			dy = (this._y - (_root.HakureiReimuMC._y));
			yspeed = (dy*dy)/dy;
			if(yspeed < 0){
				yspeed = yspeed*-1;
			}
			if(xspeed > yspeed and dx < 0 and dy < 0){
				yspeed = dy/dx;
				xspeed = 1;
			} else if(xspeed > yspeed and dx >= 0 and dy < 0){
				yspeed = (dy/dx)*-1;
				xspeed = -1;
			} else if(xspeed > yspeed and dx < 0 and dy >= 0){
				yspeed = dy/dx;
				xspeed = 1;
			} else if(xspeed > yspeed and dx >= 0 and dy >= 0){
				yspeed = (dy/dx)*-1;
				xspeed = -1;
			} else if(xspeed <= yspeed and dx < 0 and dy < 0){
				yspeed = 1;
				xspeed = dx/dy;
			} else if(xspeed <= yspeed and dx >= 0 and dy < 0){
				yspeed = 1;
				xspeed = dx/dy;
			} else if(xspeed <= yspeed and dx < 0 and dy >= 0){
				yspeed = -1;
				xspeed = (dx/dy)*-1;
			} else if(xspeed <= yspeed and dx >= 0 and dy >= 0){
				yspeed = -1;
				xspeed = (dx/dy)*-1;
			}
		}
			
	}
	function onEnterFrame()
	{
		_y += yspeed;
		_x += xspeed;
		if(this._x < 0 or this._x > 500 or this._y < 0 or this._y > 500 or _global.bulletsdead == 1 or _global.bulletsdead == 2){
			_global.bullets--;
			this.removeMovieClip();
		}
		if(!grazed){
			if(this.hitTest(_root.HakureiReimuMC)){
				if(!(this.hitTest(_root.HakureiReimuMC.hitboxreimuMC.truehitboxreimuMC))){
					_global.score += 100;
					_global.amountgrazed++;
					grazed = true;
				}
			}
		}
	}
}

//==================

//And the hitbox on the bullets:

onClipEvent(enterFrame){
	if(this.hitTest(_root.HakureiReimuMC.hitboxreimuMC.truehitboxreimuMC)){
		_global.bulletsdead = 1;
		_global.lifes--;
	}
}

It's huge, maybe.
 
avatar for SavageWolf SavageWolf 765 posts
Flag Post

Try using functions and switch statements.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

Are switches faster?

Also – The game seems to have more trouble moving all 500 bullets than running through my code.

I’ll try adding switch statements and running again.

 
avatar for SavageWolf SavageWolf 765 posts
Flag Post

You have 500 movieclips running at 60fps, halve the fps and double the numbers. Also try to find a way to use less bullets. Anyway good game.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

It’s danmaku! Why less bullets?

 
avatar for Draco18s Draco18s 2339 posts
Flag Post
Originally posted by Pimgd:

It’s danmaku! Why less bullets?

Because Flash can’t handle that many dynamic objects at one time.

Edit:

I saw a “spellcard” (?) once in 10000 points. I can run this game at 59-60 FPS consistently (thinking its too slow) and only use 20% of my total processing power. As I’m typing this my score has gone up another 2000 points or so. The random starbursts are rather boring.

Also, you can only gaze any given bullet once, even if I graze-collide with it again later.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

So, effectively, the answer to the question is “Yeah, flash lags at that point, and yes, flash is not really the best in terms of speed.”

If I remade this code in AS3, would it be a lot faster, or is the difference not worth it?

And, of course, this makes it an interesting challenge: Optimizing code to make stuff as CPU-friendly possible.

Originally posted by Draco18s:
Originally posted by Pimgd:

It’s danmaku! Why less bullets?

I saw a “spellcard” (?) once in 10000 points. I can run this game at 59-60 FPS consistently (thinking its too slow) and only use 20% of my total processing power. As I’m typing this my score has gone up another 2000 points or so. The random starbursts are rather boring.

You can? Mine cant, it’s having trouble with those spell cards. And yes, it’s easy, because I was toying around. I could make it harder, but then it would cause even more lag.

 
avatar for Cervello Cervello 76 posts
Flag Post

You have 500 movieclips running at 60fps, halve the fps and double the numbers. Also try to find a way to use less bullets. Anyway good game.

It’s ENTIRELY possible to make a 60fps bullet-curtain shmup with 500+ objects on screen run smoothly in Flash, even on average computers. See games like Pararalyzer for an example of this. Play it in Hard mode to see what I’m talking about. (Unfortunately, Pararalyzer’s a huge download due to unoptimized music, but it’s worth the wait.)

I happen to be making a 60-fps Flash shmup myself, but there are a lot of things you should (and probably need to) do to make this kind of thing work. I’m not going to go through all of them right now, but one thing you should do is to make a “pool” of pre-created MovieClips by creating a list of, say, 200~300 of them when the game starts, and toggle their visibility instead of creating and removing them. Also, Flash’s default hitTest is sloooow, and absolute hell if you run it hundreds of times to check the player’s collision with enemy bullets, let alone the thousands of times per frame it takes just for enemy and player bullets. I suggest you use the distance formula instead.

If I remade this code in AS3, would it be a lot faster, or is the difference not worth it?

Yes, it’s definitely worth switching to AS3, since not only is it faster than AS2, it offers the added flexibility and functionality you need to make more code optimizations possible (or at least much easier). Also note that MovieClips themselves can be slow when rendered in large numbers, so you may want to look into using Sprites or pixel blitting.

 
avatar for truefire truefire 670 posts
Flag Post

I’m not going to go through all of them right now.

perhaps you could link to a tutorial or such on this? i have the same problem very frequently, although i usualy have more like 1500 onscreen (running 5 fps cuz of lag). believe it or not, my first game, pong, lags on my 2GB ram, dual core, because of hte particle effects.

 
avatar for Draco18s Draco18s 2339 posts
Flag Post
Originally posted by Pimgd:
Originally posted by Draco18s:
Originally posted by Pimgd:

It’s danmaku! Why less bullets?

I saw a “spellcard” (?) once in 10000 points. I can run this game at 59-60 FPS consistently (thinking its too slow) and only use 20% of my total processing power. As I’m typing this my score has gone up another 2000 points or so. The random starbursts are rather boring.

You can? Mine cant, it’s having trouble with those spell cards. And yes, it’s easy, because I was toying around. I could make it harder, but then it would cause even more lag.

I can. Of course, my machine is a 3.0 GHz dual core…

 
avatar for Cervello Cervello 76 posts
Flag Post

perhaps you could link to a tutorial or such on this?

heriet (the maker of Pararalyzer) has a nice blog post outlining most of the ways she uses to make Pararalyzer work, but it’s in Japanese. And even if you can read it, it only goes through the stuff you do AFTER you get your rendering method straight – and that’s kinda tedious to go in-depth with.


I picked up almost all of my know-how by starting with that blog post and working with the as3 documentation and Google, but to summarize, the key points are:

  • Use Sprites or Bitmaps instead of MovieClips. This means using BitmapData instead of vector-format drawings, though flash lets you save your vector drawings as bitmap images, which you can import to your library. Pixel blitting may or may not be better than using Sprites due to a bunch of factors – I went with pixel blitting, but performance wise they are pretty close.
  • For Sprites and pixel blitting, use a static instance of the BitmapData instead of creating a new one for each.
  • Create all instances of objects beforehand (ie: NEVER use the word “new” in your frame events).
  • Use simple hit detection. (ie: rectangular or distance)
  • Take advantage of the many general optimization tricks out there, like trig and integer math.



I’m not too keen on making a guide to rudimentary pixel blitting in Flash right now, even though Flash makes it pretty simple and friendly. I made a rudimentary implementation for myself, but I believe the PixelBlitz engine can do more advanced pixel blitting for you. But again, Sprites should be much easier to work with for those that are accustomed to MovieClips, and they’re probably just as fast anyway.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

Whoa guys, whoaaaa…

Ugh, I’m on the learning train again. Hurray.

 
avatar for truefire truefire 670 posts
Flag Post

Sounds interesting. im gonna get on the learning train too, once i finish the 3D simulation im working on.

 
avatar for jonathanasdf jonathanasdf 1592 posts
Flag Post

quick reply: it shouldn’t be lagging at that point at all. My shmup/danmaku has way more bullets and it doesn’t lag. You’re just doing bad stuff performance wise (although my randomly-generated scrolling clouds does lag a bit hehe)

Anyways, I suggest you go learn AS3 before working any more, if that’s possible. You don’t have too much code done, so seriously think about going to AS3. It is perfect for these type of games because of the Vector object, which is about 30-40 times faster than using an Array.

And what I’m using for my bullet checking: This is only for the enemy bullets. Because I’m lazy I did a simplified version of it, if you’re a bit less lazy you can be even more efficient.

Anyways, first distance formula, find the distance. Divide that distance by the sum of the maximum speeds of the bullet and player. You now have the minimum amount of time needed until that bullet could possibly collide into the player. So, don’t hittest at all until that amount of time passes, then check for distance again.

Now about actual code:

The way that you have your movement code set up is inefficient. Especially if you’re thinking of adding multiple playable characters to the game. For border checking, you can use if/else because there is no way that x can be both <13.5 and >486.5 at the same time. you can speed it up further by only checking every time the player actually moves.

For the difficulty, it’d be a lot smarter to have a class for the levels, and extend that, and have some kind of levelmanager load them, because you definitely want multiple levels, and I’m quite sure you don’t want the code on the character to get too big (you still have to add in shooting, power, bombs, etc. Of course, don’t just copy touhou, add your own stuffs in too)

Having only one var Spawner declared at the top will be much faster than declaring a ton of local Spawners. Of course, you should think of making an enemy class to do all of this attaching for you. When you are doing leveldesigns there will be lots of enemies coming, and it’d be much easier to just call one function and have it attach everything for you than having many many lines for each enemy.

In your spawner class:

once again, declare variables in the class instead of locally. having a var Bullet called every frame is slow.

In your bullets;

I’m not sure whether or not using a switch will be faster, I don’t think so and don’t think it matters much.

Using and and or instead of && and || is a LOT slower. seriously. Also, this might be a bit advanced, but whenever possible, bitwise is a lot faster than logical. Just ignore that if you didn’t understand.

Oh yeah, I suggest you don’t do enterframe on each movieclip, because then it will be quite impossible to pause the game. Have a main loop in the main class and call all the other thing’s functions, so you can easily add in a pause game function.

That said, I really suggest you redo this, in AS3. If you need help, add me on jonathanasdf@hotmail.com

Actually scratch that, I’m going on vacation for a month so….

meh you can still add me if you want to. then maybe we can play SWR or IaMP or PoFV some time (I suck at the first 2)

Otherwise, it might be the 60fps lagging you. I’m only going to be using 36fps though, with my background effects 60fps will be uber laggy lol. Perlin noise algorithms aren’t the most processor friendly effects…






Just read a bit of the article/saw the game. Pah that game’s so small lol. Why does it even need to run at 60fps? You can’t really tell the difference.

That said, looks like there’s a lot of things I can do too. I’m using MovieClips, and I’m calling new instances of ships when I’m making them (I don’t really understand what that means “Create all instances of objects beforehand (ie: NEVER use the word “new” in your frame events).” because each new enemy needs to be a new instance….)

And I need to use a simpler hit detection. That said, I’m probably not going to switch to BitmapData though, just because I don’t like it hehe.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

Well, then, my question is:

What does && and || mean for the computer?

 
avatar for jonathanasdf jonathanasdf 1592 posts
Flag Post

&& is exactly the same as and, and || is the same as or. It just functions faster than those keywords, which are for AS1.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

Ah, thanks. I’ll try getting the data, then adding these bitwise thingies, then run again.

Hurray!

The spellcard runs 20 frames longer before entering lag, and the lowest lag point turns to 25 FPS. AVG at 35.
Now, for the lolz, lets try whether it lags because of hitTests… by disabling them.

Hittests off: ~35 FPS on Hard
Hittests on: ~28 FPS on Hard

Interesting. Now, the distance thingie, lets try something…

But before that, I just realized something. Grazes always graze, and then they might hit the hitbox. Therefore, I can remove the checker if it hits the hitbox, and just score- and grazes- if it hits.

Added that – It seems to have added about ~0.5 FPS extra. Oh well, anything helps.

 
avatar for Cervello Cervello 76 posts
Flag Post

Pah that game’s so small lol. Why does it even need to run at 60fps? You can’t really tell the difference.

Try it at x2 size then. The menu effects lag at that size, but actual gameplay is still smooth for me.

I don’t see why the size of the screen has any bearing on the fact that controls and animations are simply smoother at 60fps, though. (I don’t know about you, but they feel much smoother to me.) Pararalyzer has a 30fps option in the options menu, so try that for a quick, direct comparison. I get similar results when I try 30fps rendering with my game prototype.

I don’t really understand what that means “Create all instances of objects beforehand (ie: NEVER use the word “new” in your frame events).” because each new enemy needs to be a new instance….

I’m assuming you’re using a different class for each enemy type. Instead, you can simply make one Enemy class, and set a bunch of variables to determine what image will be displayed, what it’s stats are and what it’s OeF is. That way, instead of creating and destroying instances, you can “destroy” instances by setting them invisible and taking out/not running the OeF, then recycling it when you “create” a new enemy by simply setting all the variables again and making it visible. Have a pool of 100~200 instances ready in a list from the beginning, and you’ll never need to create or destroy.

You can do all that for bullets and particles as well, but those may need bigger pools than 100 or 200, depending on gameplay.

How (or whether, though I suggest it) you implement that is up to you, since there are plenty of ways to manage the “live” and “dead” instances.

 
avatar for jonathanasdf jonathanasdf 1592 posts
Flag Post

Sorry for the bump, didn’t have internet for the past week.

Anyways, I see what you mean. That won’t work for me, each level will have a unique set of enemies, if I was to put it in one class it would be way too confusing to code and debug. I’d rather sacrifice some optimization for some brain cells. ^^

That said, I took the background out and tried running at 60fps. It runs pretty smoothly, around 58-62. If I add the background in it runs a lot slower… so I guess i’ll put it as an option, for simple or sophisticated backgrounds.

I still need to optimize my bullets things though. They still lag the game somewhat when there are too many on screen at once. If there are any good optimization strategies for movieclips, with multiple classes of the bullets, please let me know.

 
avatar for Pimgd Pimgd 725 posts
Flag Post

As for what I heard lately, timers make things worse.
Could you run a check with twice as many bullets (to create lag),
run once with the timer/distance thing, and one time without?

 
avatar for jonathanasdf jonathanasdf 1592 posts
Flag Post

I’ll try it. But why would using a timer be slower than hittesting every frame?

 
avatar for Pimgd Pimgd 725 posts
Flag Post

I asked that same question…
Apparantly, the reason is

variable++
and an if check

takes more system resources than

an if check

 
avatar for jonathanasdf jonathanasdf 1592 posts
Flag Post

the if check is fast, but the hittest check is slow…

it’s much faster to check whether or not a variable is == 0 than to check whether two objects overlap, even if you don’t use the default hitTest method and use all math. When the variable != 0 you don’t have to do the hittest check, because you know it can’t be hitting no matter what.

Anyways, here’s my results, take it however you like. It does appear that using the timer takes more memory, but that’s only natural, because you have more code.

 - timer : 250 bullets, 60 fps, 18mb
             500 bullets, ~30 fps, 27mb
             1000 bullets, 16fps, 37mb
             2000 bullets, 8 fps, 64mb
             5000 bullets, ~4 fps, 135mb 

 - no timer: 250 bullets, 40fps, 14.5mb
                500 bullets, 25fps, 21mb
                1000 bullets, 15fps, 35mb
                2000 bullets, 8 fps, 60mb
                5000 bullets, flash crashed

First of all, I tested this with flash’s built in hitTest method, so the fps is a bit lower than my current implementation which uses completely math. However, I think I still need to optimize it a bit more so that I can run ~500 bullets at 60fps, which is probably the max amount of bullets that I will have on screen at any one time.

it looks like that for big amounts of bullets, both ways run at around the same fps, but for small amount of bullets there is a really visible difference. There’s no way you’ll have over 500 bullets onscreen at once, even touhou doesn’t have that much bullets on screen at once. unless of course you’re forgetting to remove your bullets.

Sign in to reply


Click Here