You already chaged the if statement to "if (firstSwipe == true)" right? Otherwise it's changing the value of firstSwipe. After that I'd add some breakpoints or NSLogs to see if the code is really doing what you expect, and what the values of your variables are.
You need to figure out is firstSwipe staying false until I swipe, and if so why is it getting into my your code when it shouldn't?
As both methods move the character, however, what I think that the downward velocity is applied before the upward velocity of the jump. Is there a piece of delay code or something that I can use to delay the firstSwipe = true until the jump has finished?
What's the value of jumpCounter the first time this is run? If jumpCounter is less than one, then firstSwipe is set to true right away.
Can you state the problem again? You have some code that you don't want to run until after the firstSwipe and after the first jump? Then it sounds like you need a firstJumpDone or isJumping variable too.
When the user swipes up on the screen, the character (a uiimageview) jumps. The idea of the game is to make him jump from block to block to prevent him from falling off the bottom of the screen. To achieve this, 'gravity' needs to be applied (just an addition of +15 to his center.y value) if he is not in the process of jumping or resting on a block. My problem is that 'gravity' must not be applied until after the first swipe, so that the game can commence without him disappearing, and I have done this by detecting if firstSwipe == true in my gameLoop. I thought that if I set firstSwipe = true in the jump method, the gravity would only become active if no other movement was happening, but as the gameLoop is called 30 times a second, the character falls before he jumps.
If I still haven't made it clear (which is a big possibility), I will post my code to see if that makes more sense than my ramblings.
One other quick point - how do I access my blocks in my arrays blockArray and Stopped blocks? With a 'for (block in blockArray, stoppedBlocks)' method?
Thanks a lot for all your help
Cam
Last edited by iPhoneDevelopment; 02-05-2010 at 02:18 PM.
You already changed the if statement to "if (firstSwipe == true)" right?
It's not clear to me whether (A) firstSwipe is changing before it's supposed to; before the first swipe is detected or (B) firstSwipe is working properly, but the code for falling is being run when it should not be run because you have some other condition you want to wait for like the first jump is complete.
Do you know which one is going on? A is probably a mistake in syntax somewhere, B is a mistake in design. I'd add two NSLogs to find out which it is:
Code:
//put this at the top of your game update method;
//the one triggered by the timer.
NSLog (@"firstSwipe is : %d", firstSwipe);
//put this inside the if statement that makes you fall.
NSLog (@"falling now!");
And yes, you can loop through all of the blocks in an array with a for loop
Code:
for (UIImageView *block in stoppedBlocks){
//do something to "block"
//it will loop through all of the blocks in stoppedBlocks.
}
It was B: a design error. I have thoroughly changed the movement of the character, and everything now works as it should .
How do I remove the blocks that have fallen off the bottom of the screen (as the simulator seems to freeze after a certain number of blocks have fallen; I'm guessing due to memory issues)?
Excellent! Sorry I couldn't help more, but you know more about your project now than I do.
You can have the loop that's scrolling the "stopped" blocks also check if the block is off of the screen, and remove the block if it is. There's a trick though -- you can't modify an array while you're looping through it using the for (X y in z) method -- so post your loop that's moving the "stopped" blocks and we'll fix it up.
I think I've got it to work.. but possibly not. This is what I'm using:
Code:
for (UIImageView *block in stoppedBlocks) {
block.transform = CGAffineTransformTranslate(block.transform, 0.0, 1.4);
if (block.center.y > 600) {
[block removeFromSuperview];
} }
Do you mind if I put your name in the credits of my app, as a 'special thanks'?
I wouldn't have been able to make it without you, so I wanted to show my appreciation. I am now on the road to iPhone game development!
I don't mind a bit, that would be great. "Sean Maher" or "Smasher" is fine. Let me know when the game comes out.
The code you posted will probably work, but the blocks never get removed from the array. Eventually the game may still slow down as the stoppedBlocks array gets bigger. I'd do this:
I changed the style of loop so that we could remove items from the array - the other style doesn't allow you to change the array while looping. Every time we remove an item we also subtract 1 from i so we don't skip any items.
Basically what I want is the score_value from my main view controller to be saved to NSUserDefaults as highscore_value if it is larger than the one already saved there, and then be shown in my GameOverViewController in the highscore label, but at the moment the highscore label updates to the highest score of the previous games, not the one that has just ended. Any advice?
Thanks,
Cam
Last edited by iPhoneDevelopment; 02-07-2010 at 07:20 AM.
You have the order backwards - you're showing the high score screen (which shows the old high score) and then you're calling the reset function that saves the new high score.
Do you know of any good tutorials or examples of more advanced collision detection? I want to know bascially if my character is above, below, or at either side of the block (so that the block becomes solid, and my character can rest on top of it, but can't travel through it from the bottom or sides).
Do you know of any good tutorials or examples of more advanced collision detection? I want to know bascially if my character is above, below, or at either side of the block (so that the block becomes solid, and my character can rest on top of it, but can't travel through it from the bottom or sides).
I don't know any tutorials, sorry. You could google for "writing a platformer" or "collision detection" - I know you'll find a lot of junk mixed in with the good stuff on that second search.
In general, you should be able to check the center point or frame of your character against the locations of the blocks - if you're above the y will be less, if you're below the y will be greater, etc. If you sketch out "good" and "bad" positions on graph paper should shold be able to see what conditions to check - you have all the info you need (width and height of all object, origin an center point of all objects).
A search through the forum yielded an earlier post from you to detect if an object was above another object. I have adapted it, and it works for the blocks in my blockArray. I cannot get it, however, to work with my stoppedBlocks array at the same time. Here is it at the moment:
Code:
for (UIImageView *block in blockArray) {
for (UIImageView *block in stoppedBlocks) {
float charBottom = (character.frame.origin.y + character.frame.size.height);
float blockTop = block.frame.origin.y;
float heightAboveBlock = blockTop - charBottom;
bool onTop = heightAboveBlock <10 //char is a little above the top of the box
&& heightAboveBlock >-10 //or a little below the top of the box
&& character.center.x > block.frame.origin.x //x is greater than left side
&& character.center.x < block.frame.origin.x + block.frame.size.width; //x is less than right side
if (onTop){
character.frame = CGRectMake(character.frame.origin.x, blockTop-character.frame.size.height,
character.frame.size.width, character.frame.size.height);
ySpeed +=0;
} } }
How do I get it to work for both arrays?
(I have given up with the notion of hitting blocks from the sides and bottom for two reasons: 1) it would make the game incredibly hard to play 2) it would have been quite difficult to achieve :P)
Those two loops don't need be "nested" inside each other. You were repeatedly checking the blocks in stoppedBlocks; repeating it once for each block in blockArray, but not using the blocks in blockArray.
Code:
//only need to calc this once, because it doesn't change
float charBottom = (character.frame.origin.y + character.frame.size.height);
for (UIImageView *block in blockArray) {
//do the stuff to check if we hit "block"
}
for (UIImageView *block in stoppedBlocks) {
//do the stuff to check if we hit "block"
}
I did not check the code inside the loops, but "ySpeed +=0" is definitely incorrect - that's the same as saying "ySpeed = ySpeed + 0" , which is the same as doing nothing.
If I put the 'float charBottom =' etc. before the 'for (UIImageView *block...', I need to re-declare 'block'. If I just put 'UIImageView *block;' the app crashes as soon as it is run. How do I declare 'block' for both the arrays before the for() statements?
If I put the 'float charBottom =' etc. before the 'for (UIImageView *block...', I need to re-declare 'block'. If I just put 'UIImageView *block;' the app crashes as soon as it is run. How do I declare 'block' for both the arrays before the for() statements?
Thanks
Cam
You don't need to declare "block" outside the loops; it's only used inside the loops. Calculating charBottom doesn't require that block is defined at all, that's why I moved it outside the loops. You still need to calculate blockTop inside the loops, since it's different for each block.
Ah right, I get it. I thought you originally meant to include all but the if(onTop) variable outside the for() statements, but I now see that this would not have worked. Setting the speed of the character to the speed of the block does not seem to work, however, so I am going to post my jumping code and ask whether you would kindly take a look and see how to make my character fall at the same speed of the block:
UPDATE: I have experimented changing the character's speed, but when he lands on a block he continuously bounces, and then if you swipe he flies way off the screen. I assume this is to do with my jumping code. All I want him to do is fall at the same speed as the block and wait for the next swipe.
UPDATE: I have experimented changing the character's speed, but when he lands on a block he continuously bounces, and then if you swipe he flies way off the screen. I assume this is to do with my jumping code. All I want him to do is fall at the same speed as the block and wait for the next swipe.
That sort of "bouncing" usually happens when you have a collision, but you do nothing to eliminate the collision before the next run loop so you collide again, etc. I would temoprarily NSLog the frames of the two objects every time you get a collision, and see if you can tell what's happening.
I also see in the code you posted you're still doing "ySpeed += 0" - adding zero to the speed does nothing, so that's probably not what you meant.
I think part of the problem is that the collision occurs if my character comes up from under the block. How do I only get a collision if he falls down onto the block from above?
Thanks
Cam
Last edited by iPhoneDevelopment; 02-13-2010 at 02:19 PM.
I seem to have managed to get the character fall at the same speed as the blocks, but there is now another problem. He cannot jump whilst standing on a block, and if he is standing on a block when it falls off the bottom of the screen he freezes there, and the game neither ends nor can you move him. I have attached my view controller as a .txt file (with all unnecessary methods removed).
I am sooo close to finishing, this collision is the final step!
Thanks,
Cam
Last edited by iPhoneDevelopment; 02-17-2010 at 03:47 AM.
ySpeed += 0;
//which is the same as
ySpeed = ySpeed +0;
//which is the same as
//ySpeed = ySpeed;
Which is the same as doing nothing. Whatever that section is supposed to do is not getting done.
Also in characterJump you copy jumpCounter into the local variable setter make some changes and then copy it back; that seems needlessly confusing when you can just use jumpCounter.
I doubt that either for these are the root of your problem; you really need to use breakpoints or NSLogs to figure out what your code is really doing, and how it's different than what you want.
For example: He cannot jump whilst standing on a block. Why not? Does characterJump not get called, or does characterJump not work properly when on a block? If it's not called, why not etc. etc.