How do you make your bullet patterns?

A place for people with an interest in developing new shmups.
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

How do you make your bullet patterns?

Post by Aru-san »

Personally, in Game Maker, I use a variable-based timer system supplemented with the Step function to create bullet patterns. With variables, there's no limit to how many variable-based timers I can make (Game Maker only supports up to 12 timers in one object).

A sort-of basic example for one of the "enemies" in a shmup I'm making right now in GM. This assumes that you have "Treat uninitialized variables as value 0" turned on.

Create action:

Code: Select all

rotatevalue = 270

hitpoint = 80
medalbonus = 150
medalrelease = 0
medaltimer = 0
Step action:

Code: Select all

mastertimer += 1

if mastertimer > 59     {initialtimer0on = 1}
if mastertimer > 59     {initialtimer1on = 1}
if initialtimer0on = 1  {initialtimer0 += 1}
if initialtimer1on = 1  {initialtimer1 += 1} 

if initialtimer0 = 10
{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
if initialtimer0 = 20
{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
if initialtimer0 = 30
{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
if initialtimer0 > 59
{
    initialtimer0 = 0
}

if initialtimer1 = 120
{
    rotateright = 1
}
if initialtimer1 = 210
{
    rotateright = 0
    rotateleft = 1
}
if initialtimer1 = 390
{
    rotateleft = 0
    rotateright = 1
}
if initialtimer1 = 480
{
    initialtimer1 = 120
}

if rotateright = 1  {rotatevalue += 1}
if rotateleft = 1   {rotatevalue -= 1}

//Don't edit below this point.

if hitpoint < hitpoint*0.2
{
    sprite_index = s_turretcrit
    medalrelease = 1
}
if medalrelease = 1 {medaltimer += 1}

if medaltimer = 5
{
    bonus = instance_create(x,y,o_medal)
    bonus.speed = 1
    bonus.direction = random(360)
    medalbonus -= 1
    medaltimer = 0
}

if hitpoint < 1
{
    instance_destroy()
    score += global.enemyworth
}
if medalbonus < 1
{
    instance_destroy()
    score += global.enemyworth
}
How do you go about making your bullet patterns when you're making a video game?
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Post by Rozyrg »

Cool approach... thanks for sharing this. I'll have to look this over more seriously once my brain is in a more capable state of mind to parse code. :)

Making actual bullet patterns is up next for my game... the ones I have now just kinda dribble out in an ugly, uninteresting way. :?
The only thing cool they do so far is change color to make themselves more visible when they collide with your fire.

Still, what I want to do is make several basic 'bullets' that do lots of different things... the idea being that they can change depending on which enemy fires them or on the situation (i.e. for rank/power increases.) Don't expect it'll be hard... just worried about making them not look like crap atm.
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Post by Aru-san »

Here's a little demo of the aforementioned pattern(s). This was all done using the variable-based timer system.
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
Danbo
Posts: 466
Joined: Sun Aug 03, 2008 6:58 am
Location: glasgow

Post by Danbo »

I'm currently working on integrating Lua scripting into my game to define boss attacks and stage enemy layouts... while I don't really know Lua at all, the Luabind library for c++ is apparently decent, which simplifies things... In the end, it would be great if the code could look less like a bunch of if statements and more like :

Code: Select all

// Fire a wave of bullets
for (i = 0; i < 180; i++)
    fireBulletAtAngle(i, speed)
// Delay for a bit before doing another attack
delay(500)
laserAttack()
delay(400)
while(hp > 400)
    doMoreAttacks()
    delay(500)
and it could progress in a more linear fashion like that, big switch statements and the like don't really appeal to me... I had a look at Kenta Cho's BULLETML XML deal, but I really hate XML parsing and a linear script makes more sense for this. I think when it comes to defining where turrets and destroyable targets / etc are on ground terrain, I may use a document style like that. Or just have a big block of createTurret calls at the start of a script. I dunno.
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Post by Rozyrg »

Aru-san wrote:Here's a little demo of the aforementioned pattern(s). This was all done using the variable-based timer system.
Nice! Very neat and clean. ;)

Certainly something for me to shoot for at this point...
User avatar
null1024
Posts: 3823
Joined: Sat Dec 15, 2007 8:52 pm
Location: ʍoquıɐɹ ǝɥʇ ɹǝʌo 'ǝɹǝɥʍǝɯos
Contact:

Post by null1024 »

I use timelines. Very easy to use, and you can very easily copy, paste, and then modify pasted sections.
And yes, timelines even for small enemies.

I'm considering using patterns from a flat file, with time, relative initial position, and X/Y deltas, namely since I'm trying to move to making games in Java, but I *hate* doing any file parsing for some reason. Unless it's pathetically easy.


@aru-san:
Why no switch statements for the specific time parts? Much cleaner than bunches of ifs.
Come check out my website, I guess. Random stuff I've worked on over the last two decades.
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Post by Aru-san »

null1024 wrote:@aru-san:
Why no switch statements for the specific time parts? Much cleaner than bunches of ifs.
Converted. You're right, it does look much cleaner than a deluge of ifs.

Code: Select all

//New code now utilizing switch statements.

mastertimer += 1

if mastertimer > 59     {initialtimer0on = 1}
if mastertimer > 59     {initialtimer1on = 1}
if initialtimer0on = 1  {initialtimer0 += 1}
if initialtimer1on = 1  {initialtimer1 += 1}

switch (initialtimer0)
{
    case 10:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 20:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 30:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 60:
        initialtimer0 = 0
        break
}

switch (initialtimer1)
{
    case 120:
        rotateright = 1
        break
    case 210:
        rotateright = 0
        rotateleft = 1
        break
    case 390:
        rotateleft = 0
        rotateright = 1
        break
    case 480:
        initialtimer1 = 120
        break
}

if rotateright = 1  {rotatevalue += 1}
if rotateleft = 1   {rotatevalue -= 1} 

//Don't edit below this point.

if hitpoint < 17
{
    sprite_index = s_turretcrit
    medalrelease = 1
}
if medalrelease = 1 {medaltimer += 1}

switch (medaltimer)
{
    case 5:
        bonus = instance_create(x,y,o_medal)
        bonus.speed = 1
        bonus.direction = random(360)
        medalbonus -= 1
        medaltimer = 0
        break
}

if hitpoint < 1
{
    instance_destroy()
    score += global.enemyworth
}
if medalbonus < 1
{
    instance_destroy()
    score += global.enemyworth
}
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
Shatterhand
Posts: 4099
Joined: Wed Jan 26, 2005 3:01 am
Location: Rio de Janeiro - Brazil
Contact:

Post by Shatterhand »

Aru-San, just to let you know.

I do the same thing. I think it's the best approach using gamemaker.
Image
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Post by Rozyrg »

null1024 wrote:I use timelines. Very easy to use, and you can very easily copy, paste, and then modify pasted sections.
And yes, timelines even for small enemies.
Interesting. I've noticed they have no problem 'overlapping' from the few times it's happened by accident on mine. Didn't think to use it that particular way, though.
User avatar
worstplayer
Posts: 861
Joined: Sun Jun 17, 2007 6:48 pm
Location: Slovakia

Post by worstplayer »

You could make a simple script for launching bullets like for example

Code: Select all

bul=instance_create(argument0,argument1,enemy_bullet)
bul.speed=argument3
bul.direction=argument2
return bul
so instead of writing

Code: Select all

{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
You could simply type

Code: Select all

shoot(x,y,rotatevalue,5)
It'll save you a lot of work with more complex patterns.
"A game isn't bad because you resent it. A game is bad because it's shitty."
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Post by Aru-san »

worstplayer wrote:You could make a simple script for launching bullets like for example

Code: Select all

bul=instance_create(argument0,argument1,enemy_bullet)
bul.speed=argument3
bul.direction=argument2
return bul
so instead of writing

Code: Select all

{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
You could simply type

Code: Select all

shoot(x,y,rotatevalue,5)
It'll save you a lot of work with more complex patterns.
Thanks for the tip! I'll give it a shot first thing when I wake up.
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
Shatterhand
Posts: 4099
Joined: Wed Jan 26, 2005 3:01 am
Location: Rio de Janeiro - Brazil
Contact:

Post by Shatterhand »

I usually have a few scripts that create bullets patterns "on the go". If I want a spread, for example, I just use

b_spread(numberofshots,spacebetweenbullets,speed)


I can share some of the scripts if you wish, but it's all very simple stuff to figure out.
Image
User avatar
monkeyman
Posts: 225
Joined: Wed Nov 14, 2007 8:53 pm

Post by monkeyman »

worstplayer wrote:You could make a simple script for launching bullets like for example

Code: Select all

bul=instance_create(argument0,argument1,enemy_bullet)
bul.speed=argument3
bul.direction=argument2
return bul
so instead of writing

Code: Select all

{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
You could simply type

Code: Select all

shoot(x,y,rotatevalue,5)
It'll save you a lot of work with more complex patterns.
Usually I use timelines and if statements like Aru San demonstrated, and while I think I understand the Switch / Case example - could you explain how the above works? Not sure what the 'return bul' does or how you implement that.

Aplogies if this is all beginners stuff but the extent of my programming before gamemaker is as follows:

10 print "monkeyman"
20 goto 10
run :wink:
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Post by Aru-san »

monkeyman wrote:
worstplayer wrote:You could make a simple script for launching bullets like for example

Code: Select all

bul=instance_create(argument0,argument1,enemy_bullet)
bul.speed=argument3
bul.direction=argument2
return bul
so instead of writing

Code: Select all

{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
You could simply type

Code: Select all

shoot(x,y,rotatevalue,5)
It'll save you a lot of work with more complex patterns.
Usually I use timelines and if statements like Aru San demonstrated, and while I think I understand the Switch / Case example - could you explain how the above works? Not sure what the 'return bul' does or how you implement that.

Aplogies if this is all beginners stuff but the extent of my programming before gamemaker is as follows:

10 print "monkeyman"
20 goto 10
run :wink:
Make a script in GM as seen in the 1st code. The arguments are a way of making a new command using the script. With this set, you can now create a command using GML in the code section of an object:

Code: Select all

[name of script]([relative x position],[relative y position],[shot direction],[shot speed])

Example of a bullet shooting downwards at 4 frames per second, spawning at 120,160:

shot(120,160,270,4)
Then instead of having a clutter of shoot, shoot.speed, and shoot.direction for every bullet, you can just use the simplified version by plugging in the arguments as seen on the last code.

It's actually helped a lot, too. Compare with the last bit of code I wrote with this:

Original code

Code: Select all

switch (initialtimer0)
{
    case 10:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 20:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 30:
        shoot = instance_create(x,y,o_ebullet)
        shoot.speed = 5
        shoot.direction = rotatevalue
        break
    case 60:
        initialtimer0 = 0
        break
}
New code

Code: Select all

switch (initialtimer0)
{
    case 10:
        shot(x,y,rotatevalue,5)
        break
    case 20:
        shot(x,y,rotatevalue,5)
        break
    case 30:
        shot(x,y,rotatevalue,5)
        break
    case 60:
        initialtimer0 = 0
        break
}
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
monkeyman
Posts: 225
Joined: Wed Nov 14, 2007 8:53 pm

Post by monkeyman »

@Aru San
Makes sense, so shoot in your example is the name of the script right?

Making bosses should be far quicker using this method - thanks all!
User avatar
Pixel_Outlaw
Posts: 2646
Joined: Sun Mar 26, 2006 3:27 am

Post by Pixel_Outlaw »

I use emitter objects that have a series of references or pointers to a series of burst objects. The emitter acts as a holder which calls bursts. Each burst specifies how many bullets and at what angles they fire.
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
gema9923
Posts: 12
Joined: Thu Apr 30, 2009 2:28 am

Post by gema9923 »

Code: Select all

Sint32 ShootBullet( float startx , float starty  , int width , Sint32 angles , int color , float speed  ,int type ,int temp0 , int temp1, int temp2   , int temp3, int temp4, int pic)
{


	if (mp->life>0 || event->Continue<=0){
	for ( Sint32 i = 0; i < BULLET_MAX-Target-BULLETLIMIT; i++ )
	{
		if ( pBullet[i].Step == 0 )
		{
			pBullet[i].Frame=frame;
			pBullet[i].spriteID = pic;
			pBullet[i].Step = type;
			pBullet[i].x= startx*1.0f;
			pBullet[i].y= starty*1.0f;
			pBullet[i].dx = startx*1.0f;
			pBullet[i].dy = starty*1.0f;
			pBullet[i].w = width;
			pBullet[i].angle = angles;
			pBullet[i].isBeam = false;
			pBullet[i].Time = 0;
			pBullet[i].BeamPower=0.0;
			pBullet[i].BeamMax=0.0;
			pBullet[i].BeamSpeed=1.0;
			pBullet[i].color = color;
			pBullet[i].movetype = 0;
			pBullet[i].godmode = 0;
			pBullet[i].speed = speed*(1.00+(0.01*rank_speed));
			
			for ( Sint32 j = 0; j < RAPID_MAX; j++ )
			{
			pBullet[i].counter[j] = 0;
			}
			pBullet[i].counter[0] = temp0;
			pBullet[i].counter[1] = temp1;
			pBullet[i].counter[2] = temp2;
			pBullet[i].counter[3] = temp3;
			pBullet[i].counter[4] = temp4;
			return i;
		}
	}
	}
	return -1;
}
My method to create a bullet in my game "Magical Broom Shooting"
By the way this is C++ Language.
User avatar
null1024
Posts: 3823
Joined: Sat Dec 15, 2007 8:52 pm
Location: ʍoquıɐɹ ǝɥʇ ɹǝʌo 'ǝɹǝɥʍǝɯos
Contact:

Re:

Post by null1024 »

monkeyman wrote:@Aru San
Makes sense, so shoot in your example is the name of the script right?

Making bosses should be far quicker using this method - thanks all!
The variable shoot looks like it's pointing to the created the bullet object... unless you mean shot, in which, yeah .
Come check out my website, I guess. Random stuff I've worked on over the last two decades.
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Re: Re:

Post by Aru-san »

null1024 wrote:
monkeyman wrote:@Aru San
Makes sense, so shoot in your example is the name of the script right?

Making bosses should be far quicker using this method - thanks all!
The variable shoot looks like it's pointing to the created the bullet object... unless you mean shot, in which, yeah .


"shot" is the script. I've modified it so that the item being shot is also taken into account.

Now the script syntax is "shot([relative x],[relative y],[direction],[speed],[object name])," making it flexible for anything that's emitted out, even my own shots and medals.

Also, there's a new demo out for my game. I have new bullet patterns, some which are pretty tough.
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
monkeyman
Posts: 225
Joined: Wed Nov 14, 2007 8:53 pm

Re: How do you make your bullet patterns?

Post by monkeyman »

null1024 wrote:
monkeyman wrote:@Aru San
Makes sense, so shoot in your example is the name of the script right?

Making bosses should be far quicker using this method - thanks all!
The variable shoot looks like it's pointing to the created the bullet object... unless you mean shot, in which, yeah .

Yes I meant 'shot' - I'll learn to read one day!
My shmup Projects
Finished: Invader! -- Tri Hunter -- Proj Raiden
WIP: Infinity Squadron
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Re: How do you make your bullet patterns?

Post by Rozyrg »

Code, scripts... still can't quite wrap my head around it all yet. :P

Anyways, I've finally come to my own (admittedly convoluted) solution. I made a little 'swiss-army-knife' bullet emitter object that an enemy creates when it fires. It immediately collides with the craft, adjusting all the pertinent variables within the emitter accordingly. Number of bullets per burst, spread density, etc..

Nothing fancy yet; but it's a start at least.
User avatar
Sasupoika
Posts: 471
Joined: Sat Nov 15, 2008 11:44 am

Re: How do you make your bullet patterns?

Post by Sasupoika »

Well, I created a bullet-shooting function:

Code: Select all

void ShootBullet(int x, int y, float speed, float angle, int thesprite, int IDi)
IDi is ID of the bullet, and if bullet has specific ID such as 55, it gives bullet special properties such as bouncing.
Int thesprite gives number which image to use for bullet. I used this way since I can easily give properties such as animation and hitbox in the function.
The bullets I have created are simply large array ( 5000 ), and I recycle through it when shooting bullets.

Making a specific pattern is quite easy.
I have made couple of reload-variables which disallow shooting unless reload-variable is under 0.
Anyway; this code:

Code: Select all

i=0;
if(reload<0){



  while(i<10){

    float Random = sf::Randomizer::Random(-10.f, 10.f);
    float Random2 = sf::Randomizer::Random(5.f, 8.f);

            ShootBullet (520, 200, Random2, Random+GetAngle(520,200,Sprite.GetPosition().x,Sprite.GetPosition().y), 1,54);

    Random = sf::Randomizer::Random(-10.f, 10.f);
    Random2 = sf::Randomizer::Random(5.f, 8.f);

            ShootBullet (520, 200, Random2, Random+GetAngle(520,200,Sprite.GetPosition().x,Sprite.GetPosition().y), 2,54);

    Random = sf::Randomizer::Random(-10.f, 10.f);
    Random2 = sf::Randomizer::Random(5.f, 8.f);

            ShootBullet (520, 200, Random2, Random+GetAngle(520,200,Sprite.GetPosition().x,Sprite.GetPosition().y), 3,54);

    Random = sf::Randomizer::Random(-10.f, 10.f);
    Random2 = sf::Randomizer::Random(5.f, 8.f);

            ShootBullet (520, 200, Random2, Random+GetAngle(520,200,Sprite.GetPosition().x,Sprite.GetPosition().y), 4,54);

    i=i+1;
  }

i=0;

  while(i<30){

            ShootBullet (520, 200, 4, GetAngle(520,200,Sprite.GetPosition().x,Sprite.GetPosition().y)+i*12, 5,1);

    i=i+1;
  }


reload=160;
}

The ID 54 makes bullet explode in rings when it touches the wall.
Would result in this:

Image
ImageImage
User avatar
genecyst
Posts: 153
Joined: Fri Nov 21, 2008 3:26 pm
Location: europe
Contact:

Re: How do you make your bullet patterns?

Post by genecyst »

maybe this should be useful for you.

http://www.asahi-net.or.jp/~cs8k-cyu/bu ... dex_e.html

i don't know if someone has already posted it but it's easier to try it out than to explain how it works
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Re:

Post by Rozyrg »

worstplayer wrote:You could make a simple script for launching bullets like for example

Code: Select all

bul=instance_create(argument0,argument1,enemy_bullet)
bul.speed=argument3
bul.direction=argument2
return bul
so instead of writing

Code: Select all

{
    shoot = instance_create(x,y,o_ebullet)
    shoot.speed = 5
    shoot.direction = rotatevalue
}
You could simply type

Code: Select all

shoot(x,y,rotatevalue,5)
It'll save you a lot of work with more complex patterns.
Finally getting around to figuring this stuff out. I made an emitter that can do almost everything I need *except* create new bullet instances on the fly... having to make a predefined amount of them beforehand sucks. :(

So yeah, think I'm gonna give this a try...

What is the relevance of 'bul' in the first example relative to the others? Is it necessary to reference when calling the script or is it supposed to be the name of the script as well? I know I'm a bit slow when it comes to this. >_>
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Re: How do you make your bullet patterns?

Post by Rozyrg »

Ah screw it... finally get it to run the script and I get the same bullshit results as I did before, except worse. *sigh*

Once again, just feels like I'm wasting time figuring this stuff out. :?
User avatar
worstplayer
Posts: 861
Joined: Sun Jun 17, 2007 6:48 pm
Location: Slovakia

Re: How do you make your bullet patterns?

Post by worstplayer »

Rozyrg wrote: What is the relevance of 'bul' in the first example relative to the others? Is it necessary to reference when calling the script or is it supposed to be the name of the script as well? I know I'm a bit slow when it comes to this. >_>
The 'bul' variable is local to the script (ie. you can't access it outside said script), and it stores index of the object created with instance_create. So no, it doesn't have to be name of the script, or to reference it anywhere.
"A game isn't bad because you resent it. A game is bad because it's shitty."
User avatar
Aru-san
Posts: 815
Joined: Sat Mar 29, 2008 7:45 pm
Location: North America
Contact:

Re: How do you make your bullet patterns?

Post by Aru-san »

Rozyrg wrote:Ah screw it... finally get it to run the script and I get the same bullshit results as I did before, except worse. *sigh*

Once again, just feels like I'm wasting time figuring this stuff out. :?
What does your code look like when you're creating bullet patterns based off the script? Can you give an example?

For me, I primarily use my code in the Step events (only because the enemies are emitters in itself than can also spawn other emitters if needed). Here's an example of one of the turrets in Stage 75, for instance. I'll add footnotes to the code as well.
Warning: Long string of code coming up.

Code: Select all

mastertimer += 1 // Responsible for launching the timers below.
bonus = 0 // Rises up by 1 to indicate a multipler for harder patterns.

if mastertimer > 59     {initialtimeron = 1}
if initialtimeron = 1   {initialtimer += 1} // (1st pattern)
//Add bullets on 100sec. (2nd pattern)
if global.time7 < 6000
{
    mastertimer = 0
    initialtimeron = 0
    emergency0on = 1
    bonus = 1 // 2x will be given upon destruction with shots.
}
if emergency0on = 1     {emergency0 += 1}
//Make bullets faster at 50sec. (3rd pattern)
if global.time7 < 3000
{
    emergency0on = 0
    emergency0 = 999
    emergency1on = 1
    bonus = 2 // 3x will be given upon destruction with shots.
}
if emergency1on = 1     {emergency1 += 1}

// This is the section where all the bullet patterns are.

switch (initialtimer)
{
    case 15:
        shot(x,y,rotatevalue0,2,o_ebullet1)
        shot(x,y,rotatevalue1,2,o_ebullet1)
        shot(x,y,rotatevalue2,2,o_ebullet1)
        rotatevalue0 += 10
        rotatevalue1 += 11
        rotatevalue2 += 9
        rotatevalue3 += 12
        rotatevalue4 += 8
        initialtimer = 0
        break
}

switch (emergency0)
{
    case 15:
        shot(x,y,rotatevalue0,2,o_ebullet1)
        shot(x,y,rotatevalue1,2,o_ebullet1)
        shot(x,y,rotatevalue2,2,o_ebullet1)
        shot(x,y,rotatevalue3,2,o_ebullet1)
        shot(x,y,rotatevalue4,2,o_ebullet1)
        rotatevalue0 += 10
        rotatevalue1 += 11
        rotatevalue2 += 9
        rotatevalue3 += 12
        rotatevalue4 += 8
        emergency0 = 0
        break
}

switch (emergency1)
{
    case 15:
        shot(x,y,rotatevalue0,3.5,o_ebullet1)
        shot(x,y,rotatevalue1,3.5,o_ebullet1)
        shot(x,y,rotatevalue2,3.5,o_ebullet1)
        shot(x,y,rotatevalue3,3.5,o_ebullet1)
        shot(x,y,rotatevalue4,3.5,o_ebullet1)
        rotatevalue0 += 10
        rotatevalue1 += 11
        rotatevalue2 += 9
        rotatevalue3 += 12
        rotatevalue4 += 8
        emergency1 = 0
        break
}

// This section is used to switch the turret to its "critical" condition, spewing out medals when the HP is low enough.

if hitpoint < 29
{
    sprite_index = s_turretcrit
    medalrelease = 1
}
if medalrelease = 1 {medaltimer += 1}

// The higher the bonus variable, the higher the multipler AND the medal release rate.

if bonus = 0
{
    switch (medaltimer)
    {
        case 6:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            medalbonus -= 1
            medaltimer = 0
            break
    }
}
if bonus = 1
{
    switch (medaltimer)
    {
        case 4:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            break
        case 8:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            break
        case 12:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            medalbonus -= 2
            medaltimer = 0
            break
    }
}
if bonus = 2
{
    switch (medaltimer)
    {
        case 2:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            break
        case 4:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            break
        case 6:
            bonus = instance_create(x,y,o_medal)
            bonus.speed = 1
            bonus.direction = random(360)
            medalbonus -= 1
            medaltimer = 0
            break
    }
}

if medaltimer > 7 {medaltimer = 0}

if hitpoint < 1 // Kill the enemy with your shots and you get your points with a multipler, provided you're fighting a harder pattern.
{
    instance_destroy()
    if bonus = 0 {score += global.enemyworth*10}
    if bonus = 1
    {
        instance_create(x,y,o_bonus0)
        score += global.enemyworth*20
    }
    if bonus = 2
    {
        instance_create(x,y,o_bonus1)
        score += global.enemyworth*30
    }
}
if medalbonus < 1 // Let the medal supply run out and you get only your points without a multipler.
{
    instance_destroy()
    score += global.enemyworth*10
}
if global.time7 < 1 // Let the time run out and you only get 1/10 of your points.
{
    instance_destroy()
    instance_create(x,y,o_penalty)
    score += global.enemyworth
}
Image
[ Wonder Force IV -sorry Frenetic :c- ]
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Re: How do you make your bullet patterns?

Post by Rozyrg »

worstplayer wrote:
Rozyrg wrote: What is the relevance of 'bul' in the first example relative to the others? Is it necessary to reference when calling the script or is it supposed to be the name of the script as well? I know I'm a bit slow when it comes to this. >_>
The 'bul' variable is local to the script (ie. you can't access it outside said script), and it stores index of the object created with instance_create. So no, it doesn't have to be name of the script, or to reference it anywhere.
Ahhh... thanks for clearing that up. I tried putting in the same name as the script for the variables anyways and unsurprisingly.. variable error/crash at startup.
Aru-san wrote:
Rozyrg wrote:Ah screw it... finally get it to run the script and I get the same bullshit results as I did before, except worse. *sigh*

Once again, just feels like I'm wasting time figuring this stuff out. :?
What does your code look like when you're creating bullet patterns based off the script? Can you give an example?

For me, I primarily use my code in the Step events (only because the enemies are emitters in itself than can also spawn other emitters if needed). Here's an example of one of the turrets in Stage 75, for instance. I'll add footnotes to the code as well.
Thank you! That's quite a bit to pour over... should be helpful. :shock:

I think my script was fine, it was probably just my newb code getting in the way. Go figure, too.. I tried again and made a DnD mockup that actually worked (finally!) I'll post it as soon as I can move it over to GML.

(Once I've got that down I'm thinking I could squash that all down into another script?)

Basically, it's a spread/burst emitter that automatically adds bullet instances and adjusts firing angles accordingly, so that I only have to change a few specific variables for each enemy for it to do what I want. Right now it's it's own separate object (it collides with an enemy whenever they 'fire', checks a few variables, then does it's thing) and I've just been using Alarms up till now; but if I can get this all scrunched down into some decent code, I doubt I'll keep it this way. I'm already getting pretty tight on Alarms with a few enemies.
User avatar
Rozyrg
Posts: 918
Joined: Wed Feb 11, 2009 12:03 am
Location: Southeast USA

Re: How do you make your bullet patterns?

Post by Rozyrg »

Well, here's my little spread emitter:

bulshoo = bullet firing script, pretty much the same as the one listed above
burz_num = # of bullets per burst
bull_spr = # of bursts per spread
burz_spac = amount of spacing between bullets in a burst

The rest are for modifying firing angles, speed etc... I've tweaked them here so my (relative) DnD values still work as long as I need them to. I have a few more I need to put back in for adjusting the origin point so the bursts are more properly spaced. *lazy*

Code: Select all

if(burz_numcou=burz_num){instance_destroy()} else
 {

  repeat(bull_spr)

  {
   if (timr_1=0)
   {bulshoo(x+0,y+0,enbull,(bull_defang)*2,bull_spee-5)};
   if (timr_1=2)
   {bulshoo(x+0,y+0,enbull,((bull_defang)*2)-((bull_angadj)*(timr_2)),bull_spee-5);
    timr_1=0};
   if (timr_1=1)
   {bulshoo(x+0,y+0,enbull,((bull_defang)*2)+((bull_angadj)*(timr_2)),bull_spee-5)};
    

  if (timr_1=0){timr_2 +=1};

  timr_1 +=1
  }

  timr_1=0;
  timr_2=0;

  burz_numcou +=1
  alarm[3]=burz_spac

 }
I haven't got it to work quite right sans Alarms yet, though.
User avatar
null1024
Posts: 3823
Joined: Sat Dec 15, 2007 8:52 pm
Location: ʍoquıɐɹ ǝɥʇ ɹǝʌo 'ǝɹǝɥʍǝɯos
Contact:

Re: How do you make your bullet patterns?

Post by null1024 »

In Java, I'm working on a method to do patterns, haven't tried it yet, but still working on it.

Code: Select all

int[][] bulletlist = new int[6][100]; //first arg: 0 - time to fire at, 1 - xpos, 2 - ypos, 3 - xdelta, 4 - ydelta, 5 - on/off.
In my game loop, it'd check to see if the time for the current shot waiting passed, if it did, create it, and add to the shot waiting position, so it'd check the next item in the array. The first part is what part of the bullet to check, the second, which bullet in the list being referred to.

There may be a problem with firing multiple bullets at the same time, but...
This is also intended for bosses. Normal enemies will have their own little timers and stuff.
Come check out my website, I guess. Random stuff I've worked on over the last two decades.
Post Reply