Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Pizzatime
Apr 1, 2011

YOU CAN PLAY IT RIGHT HERE

Controls are WASD (jump, stop, slide, run right). You might have to click the game window with your mouse once if you can't control anything.

I don't wanna poo poo up the Game Development thread any further, so here it is: My own little thread for my own little game that nobody will reply to ever, but hey.

Keep in mind that I'm terribly new to coding and probably have borderline retarded code. Feel free to point out anything that bothers you, or just help me with my problems, or call me a terrible coder, whatever you feel like. I'm trying to comment my code as much as I can, so it's easier to understand what I was thinking writing that paradox or this division by zero.

My current problem: If you jump over or slide under a bullet, the game traces "points!" and makes a little sound. After 5 bullets or so, it stops doing that. No sound, no trace. If you keep jumping and sliding, it occasionally does it one more time after failing to do so like 3 times, and sometimes it also did it again if you jumped a bullet once the last one spawned and the game traces "An Exit Appears". I have no idea why.

Here's the Code for that section:
code:
//If player jumps over a bullet, he gets points!

			if (counter > 4) 
				counter = 4;
			
			if (counter == 4)
				pointsstartVar = 1;
			
			if (pointsstartVar == 1)
			{
				if((player.x >= bullet.x - 2 && player.x < bullet.x + 2) && jumppointVar == 0)
				{
				if (player.y < bullet.y)
				{
					trace("points");
					jumppointssound.play();
					jumppointVar = 1;
				}
				}
			}
			
			if ((pointsstartVar == 1) && (player.height == 8))
			{
				if((player.x >= bullet.x - 2 && player.x < bullet.x + 2) && slidepointVar == 0)
				{
				if (player.y > bullet.y)
				{
					trace("points 500");
					slidepointssound.play();
					slidepointVar = 1;
				}
				}
			}
			
			if (player.touching == FlxObject.FLOOR)
			jumppointVar = 0;
			if (player.height == 13)
			slidepointVar = 0;
			
the counter is counter += FlxG.elapsed, and is there to not crash the game by asking to check for x and y values of nonexistant objects (the bullets).
If the counter is above 4, it gets locked at 4, cause that's when the first bullet has appeared, and I'm assuming it wastes memory if you have a counter ticking up for nothing. Then the counter makes a variable click on, so the if function doesn't have to reference the counter. Again, which I assume saves memory or data or whatever you'd call it.

That's all I can think of for now, thank you for reading.

Pizzatime fucked around with this message at 17:00 on May 6, 2014

Adbot
ADBOT LOVES YOU

Pizzatime
Apr 1, 2011

I'm one step closer to the solution. I found out that it stops working whenever there's another bullet to the right of the one you're jumping over/sliding under. So the faster the timer gets, the more likely it is that there has already another bullet spawned on the right of the screen, and the one you're jumping over won't count anymore. The closer you move to the right edge of the screen, the longer it still works. And if I keep the spawninterval at a static 2.5, it never stops working because there's only another bullet spawning when the first one is already gone.
At first I thought it's simply that two or more bullets will cause this, but it really seems to be that the function only checks the rightmost bullet. I don't know how to fix it yet, but the problem has at least become more apparent. Also I've tidied up the function.

code:
//If player jumps over a bullet, he gets points!
			if (counter > 4)
				counter = 4;
				
			if (counter == 4)
				pointsstartVar = 1;
			
			if (pointsstartVar == 1)
			{
				if (player.x >= bullet.x - 2 && player.x < bullet.x + 2)
				{
				if (player.y < bullet.y && jumppointVar == 0)
				{
					trace("points");
					jumppointssound.play();
					jumppointVar = 1;
				}
				else if (player.y > bullet.y && player.height == 8 && slidepointVar == 0)
				{
					trace("points 500");
					slidepointssound.play();
					slidepointVar = 1;
				}
				}
			}
			
			if (player.touching == FlxObject.FLOOR)
			jumppointVar = 0;
			if (player.height == 13)
			slidepointVar = 0;
That's all for now.

Pizzatime fucked around with this message at 11:20 on May 7, 2014

HaB
Jan 5, 2001

What are the odds?
Good on you for learning a new skill. You're doing it the best possible way, too: MAKE poo poo. BREAK poo poo.

That being said - I have some general tips to offer you and some other possible approaches to try.

First, try to avoid comments like this:

code:
if ((player.touching == FlxObject.FLOOR) && (player.height != 8)) //if touching floor & height is not 8
The reason being is: the code itself is understandable on it's own. The comment is just clutter. It may not seem like a big deal right now, but when you're looking through lines and lines of code, anything that provides LESS clutter is appreciated.

Comments like THIS on the other hand:
code:
counter += FlxG.elapsed; //counter that's used to not crash stuff with the bullets
are better, because I would have had no idea what you were doing here otherwise. In fact I still really don't.

And then there's this:
code:
//Makes the spawntimer be the negative equal of the elapsed time
spawnTimer -= FlxG.elapsed;
:( First, -= is not "the negative equal". It's a shorthand operator for subtraction. So these two lines are equivalent:
code:
x = x - 5;

x -= 5;
The problem with your comment is that I have no idea what you're doing there or what it's meant to accomplish. So are you subtracting the elapsed time from spawntime and when it reaches zero it spawns a bullet? If so - spawntimer is a bad variable name. It's not timing anything, so it's not a -timer. So that leads to my biggest overall tip:

Spend time to make sure your code is readable. if the code itself isn't obvious, then add a comment to clarify. I have been coding for 20 years, and I can't count the number of times I have been looking at some routine going "wtf is this guy doing here?" only to find out that "this guy" was ME, years earlier - before I had the value of writing readable well documented code drilled into my head. ;)

So I don't know Flash or Flixel or whatever language you are working in, but here's one possible approach to your bullet problem:

Assuming your bullets basically have 3 properties: X position (Left/Right), Y position (Up/Down) and Velocity (how fast they are moving). If you know in advance the greatest number of bullets that can EVER be on screen at one time - you can go ahead and create them in advance. Give them X and Y coords which make them off the screen, and give them a velocity of 0. You have a list for them already.

Add one more property to the bullets: an isActive flag, true/false, indicating if it's currently on screen, in play, etc.

Then, break up your createbullet function into two: createbullets and spawnbullet.

Something like this (again I don't know Flash. Pretend this is pseudo code):

code:
// this is the max number of bullets you ever expect to have on screen at once:
public var:Number MAX_BULLETS = 100;  // or whatever value.  5, 15, 10000 

//Creates the basic bullets at random height with fixed speed
                public function createbullets():void
                {
			for(var i = 0; i < MAX_BULLETS; i++) {
                        	var x: Number = 0;
                        	var y: Number = 0;
                        	bullet = new FlxSprite(x,y);
                        	bullet.makeGraphic(5, 2, 0xffffffff);
				bullet.isActive = false;
                        	bullets.add(bullet);
	
			}
                }

		public function spawnbullet():void
		{
			// find the first bullet which is NOT active:
			for(var i = 0; i < bullets.count; i++) {
				if(!bullets[i].isActive) {
					// found one.  randomly set x,y,velocity
					bullet.x = FlxG.width;
                        		bullet.y = FlxG.random()*20+145;
					bullet.acceleration.x = -100;
					bullet.isActive = true;
					break;  // this jumps us completely out of the for loop.  Use whatever the Flash equivalent is.  (assuming it has one)
				}
			}

		}
You get the idea (I hope). Basically you set up to POOL of bullets by calling createbullets in your create() method. Then you don't have to worry about something referencing an object which doesn't exist yet. When you want a bullet to spawn, call spawnbullet. You will also need a corresponding despawnbullets to find bullets which are offscreen and set isActive to false;

This a long post with a lot to absorb, so I will stop here. Good luck, tho!

Pizzatime
Apr 1, 2011

Oh man thanks a lot, there's a lot of stuff there that really helps me get better at this. Also thank you for the kind opening, words of encouragement are more important than I thought at first when delving into something you know nothing about.

On the "counter": I've managed to forego it completely. I switched it out with a simple if (bullet != null) on top of the whole bullet function. So it's starting exactly when I need it to, not sometime about when it has to, and I can get rid of that silly timer.

On the "spawntimer": I've copied that bit from some other tutorial, and yesterday evening, when I had learned enough that I thought maybe I could try and understand it, I went through everything related to it in the code. It seemed like a really shoddy thing that actually appeared to not make sense at times, even though it does work.
The spawninterval is declared as 2.5, then the spawntimer is declared as -= FlxG.elapsed, or itself - FlxG.elapsed. But then this:

code:
		public function resetSpawnTimer():void
		{
		spawnTimer = spawnInterval;
		spawnInterval *= 0.95;
		}
I can get behind it multiplying itself by 0.95 everytime so the interval gets shorter, but why would the spawninterval be declared as 2.5 at the beginning when it calls this function in create, which makes the interval be the timer anyway. Oh also, is spawnInterval *= 0,95 the same as spawnInterval = spawnInterval * 0.95? If so, hey, I'm learning!

I will try and implement your suggestion on the whole bullets things and report back with what comes of it. Again, thank you very very much!

Another thing that came up: I've made a little intro state that basically looks like the playstate, but doesn't have any bullets, scrolling or controls. Just the player falling from the top of the screen on the play area and looping his stand animation until you press a key, then it loads the playstate. My problem here, no matter what I input as the y spawn position of the player in the playstate, he doesn't spawn standing on the ground. He always spawns being in the air, and does his jumping animation for a frame or two along with his landing sound. I'd like him to appear standing on the ground though, because that'd be a seamless transition from the little intro state, but I can't figure out how.

And one more thing: I tried making a reset button for when you die and wanna start over, but no matter if I reset the state, or switch the state to itself, the game crashes. I read somewhere that states are not meant to be loaded more than once, but that shouldn't go for a reset of the state, right? Switching from the intro state to the playstate works fine though. Just a reset of the playstate results in a crash, which I find odd.

Pizzatime fucked around with this message at 11:34 on May 7, 2014

Pizzatime
Apr 1, 2011

- Don't waste your time, I've already figured it out. More at the bottom of this post. -

Here's another super simple thing I just can't get to work.

code:
			if (player.touching == FlxObject.FLOOR)
				{
				player.play("crystal");
				crystalVar = 1;
				}
				
			if ((crystalVar == 1) && (player.finished))
				{
					player.play("stand");
				}
I want the "crystal" animation to play if you touch the ground (you start by falling from the sky) and then, once the "crystal" animation is finished, I want the "stand" animation to start playing and keep looping. The problem is, it doesn't. The "crystal" animation keeps looping, even though it's set not to loop in it's create, though I guess that just happens because the if function keeps checking for the floor to be touched. I've had problems with the "finished" property before. It's supposed to work like this http://flixel.org/docs/org/flixel/FlxSprite.html#finished . But either I'm doing something wrong, or it doesn't work as advertised.

I did it with that variable for now to make sure the problem isn't that I hosed up the if function. I figure a better way to write it would be:

code:
			if (player.touching == FlxObject.FLOOR)
				{
				player.play("crystal");
				if (player.finished)
				{
					player.play("stand");
				}
				}
				
Does exactly the same thing though, just loops "crystal". :(

e: A minute later I've figure it out. I guess I'll explain the mistake anyway, just in case any code newbies are reading this and wonder.
I had to set it to if (player.justTouched(FlxObject.FLOOR)). Otherwise it kept checked for the floor to be touched, and as long as it did, it played the "crystal" animation. With justTouched, it only checks for the initial touch, and that's what you want here.

Pizzatime fucked around with this message at 13:46 on May 7, 2014

Pizzatime
Apr 1, 2011

Okay so I'll be writing this out just so I maybe figure this out just by writing it out.

So I have two similar functions that both use a counter in two different states. One works, and one doesn't.

In the one that does, I set the counter in the beginning, like so:

code:
public var animationcounter:Number = 0;
And in the one that doesn't, I do the same, like so:

code:
public var publictimer:Number = 0;
Then, at the beginning of the update function, I set FlxG.elapsed to substract from that timer:

code:
animationcounter -= FlxG.elapsed;
code:
publictimer -= FlxG.elapsed;
Now I have some function that sets it to something, somewhere at the beginning of the update function:

code:
if (spawnInterval == 0.7)
	publictimer = 2;
code:
if (player.justTouched(FlxObject.FLOOR))
{
	player.play("look");
	animationcounter = 1;
	crystalVar = 3;
}
			
And then there's another function that does something once it reaches 0:

code:
if ((animationcounter < 0) && (player.finished) && crystalVar == 3)
{
	player.play("crystal"); // you stand
	crystalpixel.kill();
	crystalVar = 1;
}
code:
if (spawnInterval == 0.7 && publictimer <= 0)
	bigbullet.acceleration.x = -100;
And then, the first one does what it's supposed to, and the second one does nothing.

Note: If I set the bullet function to

code:
if (publictimer = 2)
	bigbullet.acceleration.x = -100;
and have the publictimer just jump to 2 once the spawninterval hits 0.7, it works. So it's gotta have something to do with the publictimer not ticking down like I think it does.

I havn't tested it yet, but I'm pretty sure I've figured it out. The spawnInterval == 0.7, right? So it keeps setting the publictimer to 2, and it never hits 0. There we go, there we go. Man, coding is awesome.

Pizzatime fucked around with this message at 18:29 on May 7, 2014

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
Just a quick driveby comment:

Pizzatime posted:


code:
if (publictimer = 2)
	bigbullet.acceleration.x = -100;

You forgot an extra =, so you're assigning the number 2 to the variable publictimer instead of checking if its the same as 2.

Pizzatime
Apr 1, 2011

Whoops, thanks Karma.

I've cleaned up my code. Look at what Playstate has turned into:
code:
package
{
	import flash.geom.Rectangle; //Loads the Rectangle for FlxScrollZone
	import flash.media.Sound;
	import org.flixel.*; //Loads Flixel
	import org.flixel.plugin.photonstorm.*; //Loads FlixelPT
 
	public class PlayState extends FlxState
	{	
		public var level:Level1;
		public var player:Player;
		public var bulletslevel1:BulletsLevel1;
					
		[Embed(source = "../msc/wod2_2.mp3")]public var music1:Class;
		
		override public function create():void
		{
			
			//Level
			level = new Level1;
			add(level);
			
			//Player
			player = new Player(FlxG.width / 2, 156);
			add(player);
			
			//Bullets
			bulletslevel1 = new BulletsLevel1;
			add(bulletslevel1);
			add(bulletslevel1.bullets);
	
			//Music
			FlxG.playMusic(music1, 0.5);
			
			//Sounds
			add(player.walkingsound);
			add(player.landingsound);
			add(player.slidingsound);

			super.create();
		}

		override public function update():void
		{ 
			super.update();
			
			if (FlxG.overlap(bulletslevel1.bullets, player))
				player.die();

			FlxG.collide(level.floor, player);	
		}
	}
}
Everything else went into Player, Level1 and BulletsLevel1 respectively. And it still works! I did this in anticipation of having multiple levels, and I think it'll work. Oh yea!

Pizzatime
Apr 1, 2011



It's got a name now :3:

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
What IDE are you using? That accidental assignment within a conditional should have been caught by any halfway-decent IDE...

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
That looks like FlashDevelop to me.

  • Locked thread