Hmm, you do indeed fall down on the left hand side! That's a bug in my code then... Are the images in the animation slightly different sizes? That might explain it.
Oh and incidentally, you may notice that sometimes he falls into the ground and because of the new code, he can't move in either direction until he jumps first. This happens since he's technically in the ground, and so there's ground on both his right and left sides. The best way to fix this would probably be to prevent him falling into the ground in the first place - either looking ahead as he's moving (using getOneObjectAtOffset again to do this) or more simply to constantly check whether he's sunk into the ground, and if he has lift him out.
Ah don't get me wrong, I didn't mean get rid of the indentation completely! It was just absent in my examples above because the comments here truncate initial spaces. And to be honest, I'm really splitting hairs here because it's not necessarily essential and I've seen far far worse in terms of layout and code quality - but hey, you're welcome to take it or leave it! :-)
I just meant that in the first Samus class you had, it was a bit inconsistent and (most of the time) you seemed to be working with blocks of 8 spaces rather than 4 (which is the generally accepted amount.) Generally speaking, the rule with indentation is to indent four spaces every time you open a code block, and take that indentation back 4 spaces each time you close one. So for example, in your metroidWorld class at the moment you've got:
|public metroidWorld()
|{
| super(500, 450, 1);
| addObject(new Samus(), 140,90);
| addObject(new Ground(), 100,100);
| addObject(new Ground(), 140,116);
| addObject(new Ground(), 480,442);
| //etc...
|}
..which is fine up until the super() line, but then you seem to indent 8 more spaces for no apparant reason! Bringing the addObjects in line with the super() would be seen as more conventional and consistent.
There are exceptions to the indentation rule, with long lines for example (more than 80 characters) some people (not me) like to break the line up into smaller chunks and indent it 8 spaces (to avoid confusion with the lines below indented at 4.) Some people (including me) also like to not indent temporary "debug" statements at all (like System.out.println()'s for checking the status of variables) because it makes it more easy to locate said statements for altering / removing.
Also, by javadoc comments I mean ones similar in format to the one that appears at the start of the class:
|/**
| * Write a description of class Samus here.
| *
| * @author (your name)
| * @version (a version number or a date)
| */
You can also put these at the start of each method. For example, just before the approachWall() method you could put something like the following:
|/**
| * Determines whether Samus is approaching a wall on either side.
| * The side that's checked is determined by which arrow key is being
| * held down.
| *
| * @return true if Samus is approaching a wall, false otherwise.
| */
Here we've got a description of the method first, and then the @return annotation which signifies what values the method returns and under what conditions. If you've got methods with parameters, you can describe these using @param followed by the name of the parameter (use it more than once if you've got more than one parameter.) There's lots of them, you can use things like @see if your method is related to another method, you've seen @author and @version at the top of the page - those are probably the most common ones you'll come across, but there are others.
So what's the point of doing it that way? Quite simply, if you do that and then select documentation in the editor (instead of source code) you get nice little boxes and descriptions for each method based on what you've put in the comments.
Javadoc comments always start with /** and end with */. (You can also start comments with /*, but they won't be javadoc ones.)
At the end of the day though if you're just on here for a bit of fun programming and not aiming to take it too seriously, as long as your code's readable it shouldn't matter too much. If your project starts getting overly complicated, large, unreadable and unmaintainable then that's when you start to realise the benefits of proper javadoc comments and indentation! And likewise if you're aiming to take programming (in general) on to a higher level where you'll be working on things in teams, having a good, consistent coding style is very important for a number of reasons - and it pays to get into good habits early!
Well, whenever you move left or right you need to place a condition on that movement - let's say if we're approaching the wall in either direction, we don't want to move. (By approaching, I mean right on top of!) So, every time there's something like:
setLocation(getX() + 5, getY());
It becomes:
if(!approachWall()) setLocation(getX() + 5, getY());
As for the approach wall method, try this:
public boolean approachWall()
{
int widthOffset = (Greenfoot.isKeyDown("left") ? -1 : 1)*getImage().getWidth()/2;
for(int i=-15 ; i<15 ; i++) {
boolean result = getOneObjectAtOffset(widthOffset, i, Ground.class)!=null;
if(result) return true;
}
return false;
}
First of all you have to determine which way you're going to look for the offset on the correct side - that's what the first line does. The funny statement in the middle (Greenfoot.isKeyDown("left") ? -1 : 1) is the equivalent of:
int num = 0;
if(Greenfoot.isKeyDown("left")) {
num = -1;
}
else {
num = 1;
}
...and then using num in the widthOffset line instead of the tertiary operator. I should say though that while I'm all for it in situations like that where it can easily be understood, some people really aren't and think any use of it is bad coding style - so don't go too wild if you choose to use it. The first part is the condition, then there's a ?, then the value if the condition's true, followed by a :, and finally the value if the condition's false.
Anyway, we've then got a loop in there to check along the height of the image - we want him to be stopped by walls anywhere along his height, not just at the top or the base. If we encounter a wall at any point, then return true - otherwise keep looking. If we don't find a wall anywhere along his height, return false (because we're not approaching a wall.)
Few other bits I noticed in your code while I'm at it:
- Your indentation isn't the worst I've seen, but it does seem a bit bizarre! Did you write it in the Greenfoot editor or somewhere else? Proper indentation really does make code easier to read and debug, if you write programs that start getting really large, then debugging when code is all over the place is a nightmare!
- Along the same lines, javadoc comments for methods are also nice ;)
- Thirdly, using == to compare strings won't work. You need to use .equals instead, so: shoot == "yes" would become shoot.equals("yes"). It's all to do with the two types of equality in Java - basically, == will check if they're the same string - i.e. exactly the same object in memory. .equals() will tell you whether the strings have the same contents. In 99.99% of cases, including here, it's .equals() that you want! (== does work occasionally because of Java doing clever performance things behind the scenes, but programatically speaking it's still not correct.)
- In your metroidWorld class you're creating a lot of ground seperately - some for loops could condense that right down!
- Finally and on the same lines as point 3, why are you using a string? It seems to me that the shoot field would be much better off as a boolean..! Unless you need more than two values for some reason. However, in that case I'd recommend a bit of reading on enums. Sure strings will work if you get it right, but if you misspell something or make a typo, the compiler won't catch it and you'll probably spend quite a while debugging before you notice what's gone wrong!
Anyway, that was a bit of a mega comment (actually, what's the longest non-spam comment we've had on the gallery? Have I broken the record?) but I hope it's helped :-)
Definitely coming along! I managed to win :-) You might want to use the setPaintOrder method in world so that the text appears on top of everything else when you finish!
Few other suggestions, one's visual - making the white around the acorn image transparent would mean it doesn't stand out when the whole world changes colour. Photoshop would do that no problem, or you can use Paint.NET, which is free and will do it just as well! Also, movement of the rocks and the barrels seems a little jerky at the moment, making them smoother will make it much easier to see what's coming and then make an effort to avoid them, rather than just going for it and hoping for the best!
2009/4/28
Metroid NES
2009/4/28
Metroid NES
2009/4/28
Metroid NES
2009/4/28
Metroid NES
2009/4/28
zombies v. rambo version 3.0
2009/4/27
Blade Thrower
2009/4/27
SquirrelLauncher
2009/4/27
Metroid NES
2009/4/26
Blade Thrower