Driving stage (Cadillacs and Dinosaurs style)

mulambo

Member
Is there a way to make something like that stage from Cadillacs and Dinosaurs where the player drives a car and hits enemies on the road?
I guess the bg can be tiled, but what about spawning enemies? For now I only know how to spawn them when the character reaches a certain x position of the bg, but in the case of a scrolling bg (tiled one, that's probably the best solution, I guess), how to achieve a random spawning ?  Is there a way to end the stage after a certain time (example: 1 minute, 2 minutes, etc.)  ? Or is it necessary to make an extremely long bg and a selective spawning of enemies  (in this case: how to force the char to move forward and only be able to go up and down through the z axis of bg?)
 
You mean something like this?

You can just set the the at command to 0, so enemies automatically spawn without moving the stage, though I always set the first spawn at a low number so players don't get taken off guard from the start, but the rest of the following enemies are set to 0. If you want a time based spawn, there could be other ways, but I just made temporary enemy entities with empty frames that die on their own via script, how long it takes depends on the animation.

I'll give you some examples. These are the first 3 enemies from the stage in my video. I set "at" to 10 for the group command so the player has to move forward a little to make the enemies start spawning. All other enemies and group have "at" set to 0 afterward.
Code:
group 5 5
at 10

spawn HopterCopter__
health	40
coords 550 120 1
at 0

spawn RAIDER_SWATBOT__
health	30
coords 550 251 1
at 0

spawn Nebula__
health	20
coords 550 162 1
at 0

This is from another stage in the game. The "TempE" entity is the temporary enemy I was talking about. I sat that there with "Group" set to "1 1" so more entities don't spawn by mistake since I'm really using a random enemy spawner, and with group set to 1 1, no other entities will spawn since the random spawners are not entities and are not counted against the group, if I explained that right.

Code:
spawn TempE
health	20
coords 300 370 1
at 0

spawn SpeedSESb
mp 6
coords -100 225 1
at 20

spawn SpeedSESa
mp 6
coords -100 271 1
at 0

Here's the coding for TempE. IIRC, 100 delay equals a second, and with 4 frames, that makes 4 seconds. The 5th frame comes after the cmd that makes it kill itself at that frame.
Code:
name	TempE
type	enemy
shadow	0
alpha   0
remove  0
nomove 1
Facing 1
health	20

anim idle
	delay	100
	offset	101 87
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
@cmd killentity getlocalvar("self")
	frame	data/chars/misc/empty.gif

I think that's about it. I can give you the info you need for random enemy spawning but what you're asking for doesn't require that. I almost forgot to that you're asking how to make stage like this. For one, yes, it requires a scrolling BG, I just make the panel empty and use BGLayer for multiple BGs. The easiest way to do this with player entities is to put "Setweap #" in the stage so players automatically switch to a weapon entity, which then you can go whatever you want with. For the player, make a weapon entity for it and make sure it's set right in both files. Using Mikey's file cause he was in the video, I have multiple weapon entities for running and flying stage, so I use different "setweap" commands depending on the stage. This is just how I set weapons in my mod.
Code:
weapons    MICHELANGELO_ MICHELANGELO__ MICHELANGELO___ MICHELANGELO____
Underscores don't show up in game so I wont have to change the name.

Mikey's weapon from the video is weapon 4, matching the 4th weapon you see there. Here's 4th weapon file.
Code:
name	MICHELANGELO____
weapnum 4
weapnum is the weapon number, but I've already given you the details you need.

Hopefully this all helps.

X)
 
more like this
https://www.youtube.com/watch?v=n1X73XMqeiI
but i see the dynamics can be the same, just faster scrolling of bg (yup, I figured it was a matter of empty/transparent panel, with tiled/scrolling background) but no enemies attacking or reaching the player (they must just stand there waiting to be hit, so they should follow the same speed of the scrolling bg I guess)

I think I'll use the skipselect because I'm not familiar with weapon code so the player will be just a car that can move up and down, until it reaches a point of the stage. but this is the main part of the problem, how to make the stage end at a certain time.

the at 0 thing can be cool, but actually I forgot to mention that also the position of zombies should be random, is there a way to achieve that?
 
mulambo said:
more like this but i see the dynamics can be the same
They are, the only thing that's different between out videos is that I have a much wider Z plain to simulate flight, but the principles are the same.

just faster scrolling of bg (yup, I figured it was a matter of empty/transparent panel, with tiled/scrolling background) but no enemies attacking or reaching the player (they must just stand there waiting to be hit, so they should follow the same speed of the scrolling bg I guess)
Just give them the no move command and give their idle animation a "move -#" command. For smoother moving, I recommend duplicating teach frame(if you're using more then one), and setting delay to 2 or 3, they tend to look like they're clipping if you don't. Here's an example with Mikey's first attack on that board so you see what I mean. Delay is set to 2 with duped frames, so they are treated as if the total delay is 4, but it makes movement look much better.
Code:
anim	attack1
	loop	0
	delay   2
	offset	151 150
	bbox	142 98 28 42
	fastattack	1
	hitflash	Flash2
	attack1	0
        Fastattack 1
	frame	data/chars/Mikey/A4-0.gif
	frame	data/chars/Mikey/A4-0.gif
		bbox  142  98  37  42
                Move 4
		attack3  150  96  60  46  14  0  0  0  0  150
	DropV	1 2
	frame	data/chars/Mikey/A4-1.gif
	frame	data/chars/Mikey/A4-1.gif

I think I'll use the skipselect because I'm not familiar with weapon code so the player will be just a car that can move up and down, until it reaches a point of the stage. but this is the main part of the problem, how to make the stage end at a certain time.
Use the Temp enemy I suggested, and just give it a long animation before killing itself. Every 100 delay is 1 second, so I'm sure a minute is 6000 total delay. This can be done with delay 100 with 60 frames, delay 1000 with 6 frames(10 seconds per frame) or if you're sure your math is right, just 1 frame with delay 6000. When the entity dies, and it's the last enemy, it should end the stage.
Code:
name	TempE
type	enemy
shadow	0
alpha   0
remove  0
nomove 1
Facing 1
health	20

anim idle
	delay	1000
	offset	101 87
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
@cmd killentity getlocalvar("self")
	frame	data/chars/misc/empty.gif


the at 0 thing can be cool, but actually I forgot to mention that also the position of zombies should be random, is there a way to achieve that?
Luckily for you I just did this in another mod I'm working on. This would take a lot more explaining so I'll just copy as much of this as I can, and you should be able to examine the file.

Code:
name	TFerS
type	Panel
shadow	0
alpha   0
remove  0
speed 10
setlayer -10
offscreenkill 5000

palette       data/chars/misc/empty.gif

animationscript data/scripts/script.c

anim idle
      	@script
    void self = getlocalvar("self");
    if( frame == 5){
      int r = rand()%10;
      if( r < 1){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < 2){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 3){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r < 4){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      } else if( r < 5){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW5"));
      } else if( r < 6){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW6"));
      } else if( r < 7){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW7"));
      } else if( r < 8){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW8"));
      } else if( r < 9){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW9"));
      } else if( r < 10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW10"));
      }
    }
	@end_script
        loop    1
		@script
    void self = getlocalvar("self");
    int Code = getentityproperty(self,"mp");
    int Status = getindexedvar(Code);
     
    if(Status==1){
      performattack(self, openborconstant("ANI_FOLLOW11"));
    }
@end_script
	delay	5
	offset	161 131
	bbox	139 61 45 71
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif

anim Follow1
      	@script
    void self = getlocalvar("self");
    if( frame == 10){
      int r = rand()%10;
      if( r < 1){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < 2){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 3){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r < 4){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      } else if( r < 5){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW5"));
      } else if( r < 6){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW6"));
      } else if( r < 7){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW7"));
      } else if( r < 8){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW8"));
      } else if( r < 9){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW9"));
      } else if( r < 10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW10"));
      }
    }
	@end_script
        loop    1
	@script
    void self = getlocalvar("self");
    int Code = getentityproperty(self,"mp");
    int Status = getindexedvar(Code);
     
    if(Status==1){
      performattack(self, openborconstant("ANI_FOLLOW11"));
    }
@end_script
	delay	5
	offset	161 131
	bbox	139 61 45 71
	frame	data/chars/misc/empty.gif
	@cmd	spawn01 "FERNANDEZ_" 0 150 0
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif

anim Follow2
      	@script
    void self = getlocalvar("self");
    if( frame == 10){
      int r = rand()%10;
      if( r < 1){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < 2){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 3){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r < 4){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      } else if( r < 5){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW5"));
      } else if( r < 6){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW6"));
      } else if( r < 7){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW7"));
      } else if( r < 8){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW8"));
      } else if( r < 9){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW9"));
      } else if( r < 10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW10"));
      }
    }
	@end_script
        loop    1
	@script
    void self = getlocalvar("self");
    int Code = getentityproperty(self,"mp");
    int Status = getindexedvar(Code);
     
    if(Status==1){
      performattack(self, openborconstant("ANI_FOLLOW11"));
    }
@end_script
	delay	5
	offset	161 131
	bbox	139 61 45 71
	frame	data/chars/misc/empty.gif
	@cmd	spawn01 "FERNANDEZ_" 100 150 20
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif

anim Follow3
      	@script
    void self = getlocalvar("self");
    if( frame == 10){
      int r = rand()%10;
      if( r < 1){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
      } else if( r < 2){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
      } else if( r < 3){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW3"));
      } else if( r < 4){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW4"));
      } else if( r < 5){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW5"));
      } else if( r < 6){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW6"));
      } else if( r < 7){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW7"));
      } else if( r < 8){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW8"));
      } else if( r < 9){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW9"));
      } else if( r < 10){
        changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW10"));
      }
    }
	@end_script
        loop    1
	@script
    void self = getlocalvar("self");
    int Code = getentityproperty(self,"mp");
    int Status = getindexedvar(Code);
     
    if(Status==1){
      performattack(self, openborconstant("ANI_FOLLOW11"));
    }
@end_script
	delay	5
	offset	161 131
	bbox	139 61 45 71
	frame	data/chars/misc/empty.gif
	@cmd	spawn01 "FERNANDEZ_" 200 150 40
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif

anim Follow11
        loop    1
	delay	1
	offset	161 131
	frame	data/chars/misc/empty.gif
	offset    123 127
	delay     3
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame   data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	@cmd	killentity getlocalvar("self")
	frame	data/chars/misc/empty.gif
This is one of the random spawners I made. The entity is set to type panel with the speed set to 10, so it follows the screen exactly(useful for any other custom effects, like in my Sonic mod, I used it to spawn robots flying in the background at 3 random Z positions). I don't know how else you intend on doing what you're doing, but assuming you're not lining them up, which would take more effort, change the last # for each spawn01 command to change the Z plain the entity is spawned at. positive for lower then the spawner and negative for higher. The script and animations will do the rest of the work. The first two numbers are for the X and Z coordinates, so you can leave them at 0.

I should also let you know that I had to make another entity that kills this one after a certain time frame.
Code:
name	ESK10TF
type	Panel
shadow	0
alpha   0
remove  0
speed 10
setlayer -10
offscreenkill 5000

palette       data/chars/misc/empty.gif

animationscript data/scripts/script.c

anim idle
        loop    1
	 @script
     if(frame==2){
      setindexedvar(10, 1);
     }
     else if(frame==4){
      setindexedvar(10, 10);
     }
     @end_script
	delay	750
	offset	161 131
	bbox	139 61 45 71
	 frame     data/chars/misc/empty.gif
	delay	50
	 frame     data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif
	@cmd	killentity getlocalvar("self")
	frame	data/chars/misc/empty.gif
Delay is used as the timer again. At frame 2 it changes the number if the entities MP bar from 10 to 1, set in the level txt, to another, which forces the former animation to got to follow11 and kill itself. I have it set it back to 10 just to be safe when using more of these in the future. I have it set up like so in the level txt.
Code:
spawn TFerS
coords 240 223 1
mp 10
at 5100
spawn TFerS
coords 140 288 1
mp 10
at 5100
spawn TFerS
coords 140 288 1
mp 10
at 5100
spawn TFerS
coords 340 288 1
mp 10
at 5100

spawn ESK10TF
coords 220 218 1
at 5100
spawn ESK10TF
coords 220 218 1
at 5110
spawn ESK10TF
coords 220 218 1
at 5120
I spawn multiple "ESKs" or "Enemy Spawner Killers" because I had a few bugs where the one didn't always work, using more always kills them off.

If you need anymore help, I can walk you through your own entities later, it would be much easier the explaining it all at once.

X)
 
wow, that's a lot of info I'm sure it will be useful once I get my hands on the stage, I'll let you know if it works. for now, I'm figuring the method is a bit complicated, so I'll go with the long and boring way of an extremely long bg with transparent panel (like.... 6000x320 lol, or something like that, if the engine supports it), then just place each enemy one by one and then place a last enemy as boss right at the end of the stage with a really big bbox. but I think that I got plenty of info here to work on, so let's see in the future what it can bring, thanks! : )
 
For the scrolling part, you can take a look at this. It's better you make an empty panel with bg's/fg's serve as scrolling.

http://www.chronocrash.com/forum/index.php?topic=3432
 
mulambo said:
(like.... 6000x320 lol, or something like that, if the engine supports it), then just place each enemy one by one and then place a last enemy as boss right at the end of the stage with a really big bbox. but I think that I got plenty of info here to work on, so let's see in the future what it can bring, thanks! : )
You're welcome, but I should point out that you don't need a long BG, there's a command where you can set the BG to repeat for as many times are you want to, like 1000000s or so. In any case, you should check that link Maxman gave you.

X)
 
DJGameFreak TheIguana said:
there's a command where you can set the BG to repeat for as many times are you want to, like 1000000s or so.

Of course you can do so, but you can set -1 on xrepeat or zrepeat infinitely. Putting a million will just have to be a million as described.
 
all right, it worked. not as perfect as I've expected, but at least something that's good for what it was supposed for (sort of interactive cutscene / pre-intro).
thanks again everyone for the useful info!
 
maxman said:
DJGameFreak TheIguana said:
there's a command where you can set the BG to repeat for as many times are you want to, like 1000000s or so.

Of course you can do so, but you can set -1 on xrepeat or zrepeat infinitely. Putting a million will just have to be a million as described.

Nice, and now I wonder how to make the scrolling start and stop at various intervals, which would be useful for elevator levels.
 
now I wonder how to make the scrolling start and stop at various intervals, which would be useful for elevator levels.

You can use script to control autoscrolling speed like this:

Code:
group	1 1
at	0

spawn	delay
@script
  void main()
  {
    changelevelproperty("bgspeed", 0.5);
    changelevelproperty("vbgspeed", 1);
  }
@end_script
health  100
coords	160 190
at	0

spawn	delay
@script
  void main()
  {
    changelevelproperty("bgspeed", 2.5);
    changelevelproperty("vbgspeed", 0);
  }
@end_script
health  100
coords	160 190
at	0

spawn	delay
@script
  void main()
  {
    changelevelproperty("bgspeed", 0);
    changelevelproperty("vbgspeed", -2);
  }
@end_script
health  100
coords	160 190
at	0

That's quoted from my test level that I used to toy with this script :D
Anyways, changing bgspeed is for horizontal scrolling while vbgspeed is for vertical scrolling
Setting both parameter will result in diagonal movement similar to elevator in second stage of Undercover Cops
 
Back
Top Bottom