Author Topic: We're rewriting SMW  (Read 34733 times)

Offline JM Dragon

  • Stomp Arena Staff
  • this title came sooner than the last
  • **
  • Posts: 3629
Re: I'm rewriting SMW
« Reply #15 on: October 10, 2011, 06:22:00 PM »
Quote from: "Blaspergerstoise"
Good news: I've fixed the jumping problem simply by checking if the player is jumping before checking if the player is on the ground. There's also no magnet effect either. So all that needs to be fixed is that off-by-one-on-the-left-side collision problem.

Also, something weird: collision is now broken on both sides. On the leftmost side, the player will fall through the block if it is on the leftmost half of the block. On the rightmost side, the player will fall through the block if it is on the rightmost half of the block.
I got it.

The problem is that you're only checking one of a few possible places for ground collision. I made a few (crappy) images to help illustrate what the problem is:

The green rectangle is the skin. The blue box is the collision check. The purple box is where relX, relY places the skin, and the brown box is solid ground.

The player can move left on the block, but only up to 8 pixels off. Once the player moves past 8 pixels:

Rounding sets the player's relative position to the left of the solid block, along with the collision detection, causing the player to fall through the block.

I think using Math.round() is hurting here more than it is helping, and the reason is that Math.round() changes the value of relX and relY in the middle of a block instead of the edge. Math.floor() or Math.ceil() <ceiling> would be more reliable in this case, because it is easier to predict the values that relX and relY will snap to.

I prefer to use floor() to check collision to the left of the player, then check to the right of the player with relX+1. The same effect can be done with ceil() and relX-1. If you use rounding, the check would have to be performed either to the left or to the right of the player, depending on the effect of the rounding.



Edit @Felix-The-Ghost:
Quote from: "Felix-The-Ghost"
Quote
 
Code: [Select]
for(int i = 0; i < tiles.length; i++)
   {
      for(int j = 0; j < tiles[i].length; j++)

Quote
It's an extremely inefficient loop that draws tiles on the screen. If the tile at [j] is not null, then draw that tile's image.

I don't really know what you're trying to do, I don't know why you'd ever compare j < tiles.length; j++ and i < tiles.length;, they seem unrelated.

I'd expect something like
Code: [Select]
for(int i = 0; i < tiles[i].length; i++)
   {
      for(int j = 0; j < tiles[j].length; j++)
Notice the changes, that's what I would've thought you intended to write.

Dang it. I always used HTML on BBCode forums and BBCode on HTML forums >:(

This is a due to a quirk with the Java language. A 2D array is actually an array of arrays (I believe c# calls them jagged arrays). For example, let's say there is an array that is allocated as int a[2][7]. checking a.length would return 2, and a[value] would return 7. Here's my explanation of what he was doing, in comment mode:
Code: [Select]
   //check rows
   for(int i = 0; i < tiles.length; i++)
   {
      //check columns
      for(int j = 0; j < tiles[i].length; j++)
 

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #16 on: October 10, 2011, 06:40:26 PM »
Quote from: "Big JM"
Quote from: "Blaspergerstoise"
Good news: I've fixed the jumping problem simply by checking if the player is jumping before checking if the player is on the ground. There's also no magnet effect either. So all that needs to be fixed is that off-by-one-on-the-left-side collision problem.

Also, something weird: collision is now broken on both sides. On the leftmost side, the player will fall through the block if it is on the leftmost half of the block. On the rightmost side, the player will fall through the block if it is on the rightmost half of the block.
I got it.

The problem is that you're only checking one of a few possible places for ground collision. I made a few (crappy) images to help illustrate what the problem is:

The green rectangle is the skin. The blue box is the collision check. The purple box is where relX, relY places the skin, and the brown box is solid ground.

The player can move left on the block, but only up to 8 pixels off. Once the player moves past 8 pixels:

Rounding sets the player's relative position to the left of the solid block, along with the collision detection, causing the player to fall through the block.

I think using Math.round() is hurting here more than it is helping, and the reason is that Math.round() changes the value of relX and relY in the middle of a block instead of the edge. Math.floor() or Math.ceil() <ceiling> would be more reliable in this case, because it is easier to predict the values that relX and relY will snap to.

I prefer to use floor() to check collision to the left of the player, then check to the right of the player with relX+1. The same effect can be done with ceil() and relX-1. If you use rounding, the check would have to be performed either to the left or to the right of the player, depending on the effect of the rounding.
I just tried changing Math.round to Math.floor. Changing it to floor did solve collision problems on the rightmost side of blocks, but the leftmost side is still having problems. In addition, changing to Math.floor caused the "magnet effect" when jumping and when moving left.

On the other hand, using Math.ceil did the exact opposite: it solve collision problems on the leftmost side, while the rightmost side experienced faulty collision. It also caused the "magnet effect" when the player makes contact with the ground and when the player moves right.

Also, Math.floor and Math.ceil return a double, so they must be cast to an int.

EDIT: This gives me an idea...

EDIT 2: Nope, my idea didn't work.
« Last Edit: October 10, 2011, 06:45:18 PM by EON8ight »

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #17 on: October 10, 2011, 06:42:40 PM »
Big JM, I don't understand whay a check for columns (j) should not need to know anything about (i).
And the rows check doesn't seem to even be accessing an array, unless Java has really screwy syntax.

Checked here: I guess it does. I think it looked weird to me because [s:1zcmstu8]usually I use temporary variables to access the 2D array:[/s:1zcmstu8] I'm not sure what I'm trying to say here :P
Code: [Select]
  for(i = 0; i < 4; i++)
    for(j = 0; j < 5; j++)
      arr[ i ][ j ] = i * j;

Quote
I just tried changing Math.round to Math.floor. Changing it to floor did solve collision problems on the rightmost side of blocks, but the leftmost side is still having problems. In addition, changing to Math.floor caused the "magnet effect" when jumping and when moving left.

On the other hand, using Math.ceil did the exact opposite: it solve collision problems on the leftmost side, while the rightmost side experienced faulty collision. It also caused the "magnet effect" when the player makes contact with the ground and when the player moves right.

The problem is which ever way you round you will have a gap (It'll round over, ignoring the solid you were standing on to begin with, and still are), you need to check the collision of both floor and ceil, as see if either one is solid. (Later you'll also have to see if one is a death block, eg) It doesn't make sense to collide with only one block if clearly the player is right between them.

The point on the player used for relative X/Y should be in the middle for this case. then floor will return the leftmostX or topmostY and ceil will return the rightmostX and topmostY.

The only problem with that is it'll say you're colliding with tiles on the ground even if you over lap them just a little (I don't remember if SMW does that or not, but it'll be bad if you were standing next to lava, eg)

Edit:Just remembered, SMW has a smaller bounding box, so you can overlap tiles without colliding with them (or standing on them) that's why you can stand next to a wall with Mario's face in it.

So:

the results of floor() on the left point of the player (or actually a little more than the exact left)
and
the results of ceil() on the right most (or a little less than the exact right)

This is what I mean:

I don't know how big the bounding box actually is though in SMW. I used 20x20 for example.
It should check the left corner and right corner of the bounding box

In the third picture, the left edge is still barely on the block (a scenario you're having problems with collision with) I guess you'd floor both points. I'm trying to illustrate checking four corner points instead of one.

Like in Big JM's example, since at least the right point is on a solid block, the player is standing on it (though it's also standing on whatever is under the other one, in this case air, but it could be lava, eg)

Offline JM Dragon

  • Stomp Arena Staff
  • this title came sooner than the last
  • **
  • Posts: 3629
Re: I'm rewriting SMW
« Reply #18 on: October 10, 2011, 10:16:08 PM »
Welp, looks like I have some things to learn as well. Is this "magnet effect" vertical? The effect didn't happen back when you were using Math.round() to find relX and relY. I'm thinking that it would be good to have rely calculated by rounding, so that floor() doesn't cause collision issues vertically.
 

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #19 on: October 10, 2011, 11:11:46 PM »
Quote from: "Felix-The-Ghost"
This is what I mean:

I don't know how big the bounding box actually is though in SMW. I used 20x20 for example.
It should check the left corner and right corner of the bounding box

In the third picture, the left edge is still barely on the block (a scenario you're having problems with collision with) I guess you'd floor both points. I'm trying to illustrate checking four corner points instead of one.
That's not the problem. The problem is, when the player is standing on a block and air (the first scenario next to the "smaller bounding box" diagram), the player falls through the block, as if the player were standing on nothing.

Would it be easier if I PM'd you guys the source code?

Also, any place we could collaborate in real-time instead of posting on a board? It would be more efficient.

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #20 on: October 10, 2011, 11:33:09 PM »
Don't we have an irc channel?
I think Big JM uses hotmail, and I use Gmail. I'm not sure if I can chat with him or not.
I can't write Java, but I could look at it and read it. Do you have any binaries to test that first scenario?

imwd dot skaught at gmail.com (gmail or gchat)

Visually, yes the sprite overlaps both tiles, I'm sure, but does you code currently account for more than one collision, or just one (can it actually handle literally standing on two different types of blocks instead of rounding to either one) The logic I presented addresses the issue of the code handling multiple collisions (not deciding which one to collide with solely)

An either or approach, is the left point on ground or is the right point on ground? (2 points to test)

Actually, I'm not even familiar enough with Java to know what to do with it. It's a scripted language, right? So I just edit the sources (no compiling needed)?

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #21 on: October 10, 2011, 11:49:09 PM »
I'll set up an SVN repository and some kind of workspace tomorrow.

The main problem, as you pointed out, is multiple collision. The player's position when collision is being taken into account is rounded to the nearest single tile - the players "relative position." The player probably won't be standing on more than two tiles at a time, so it looks like I'll have to create a new 2D array of booleans that is [64][48] (twice as large as [32][24]) for checking collision. It shouldn't be too hard. When it comes to checking for tile types, I'll use a priority-based method: if the player is standing on both a slippery block and a solid block, the slippery block gets priority. If the player is standing on both a slippery block and a hazard block, the hazard block gets priority. And so forth. I'll get to work on it tomorrow.

As for Java, everything must be compiled before it can be run. It reads similarly to C and C++, so if you can read any of those, you can probably read Java. I suggest using Eclipse (IDE for Java EE Developers) if you're going to be running my code.

If you guys have Skype, that would make things much easier.

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #22 on: October 11, 2011, 12:30:58 AM »
I think doubling the array sizes is a big no no. You shouldn't make it represent something it's not, you just need to update the logic for handling the collision -- the collision map is right where it needs to be (though I'm not sure what you are using to represent the different types)

Can you use Skype without a webcam? Cause I have none.

If you want to have it check just one tile to see if the majority of the sprite is on it it'd be back to use the midpoint and rounding (manually maybe, to account for being exacty inbetween the two to have one or the other take priority in that case)

I'm still liking the bounding box/four points idea since the player is the same height as the tiles.

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #23 on: October 11, 2011, 05:03:58 PM »
Quote from: "Felix-The-Ghost"
I think doubling the array sizes is a big no no. You shouldn't make it represent something it's not, you just need to update the logic for handling the collision -- the collision map is right where it needs to be (though I'm not sure what you are using to represent the different types)
I decided against changing the array sizes. I wrote a method that checks if the player is on an edge, and either Math.floor or Math.ceil their relX accordingly. It doesn't work, even though it should, so I have no idea what's wrong. As for checking tile types by giving each tile a TileType variable called type. TileType is an enum with the variables "solid, fallthrough, slippery, kill," and "killtop." I'll get the tile the player is standing on, and I'll use a switch case to determine what the type is by comparing it to tile.type, and do whatever needs to be done based on what type is.

Quote from: "Felix-The-Ghost"
Can you use Skype without a webcam? Cause I have none.
You don't need a webcam for Skype.

Quote from: "Felix-The-Ghost"
If you want to have it check just one tile to see if the majority of the sprite is on it it'd be back to use the midpoint and rounding (manually maybe, to account for being exacty inbetween the two to have one or the other take priority in that case)
Now that I think of it, my original plan (checking if the player is on an edge) won't accommodate for two tiles of different types, so it looks like I'll have to check what tile the majority of the player is on.

Quote from: "Felix-The-Ghost"
I'm still liking the bounding box/four points idea since the player is the same height as the tiles.
I tried adding more points to the player, but I'm not fully sure on how to do that, so I'll have to read Rectangle's documentation again.
« Last Edit: December 29, 2011, 01:56:37 PM by EON8ight »

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #24 on: October 11, 2011, 07:41:49 PM »
I set up an SVN repository. Big JM and Felix-The-Ghost, PM me your email addresses if you want access.

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #25 on: October 11, 2011, 09:35:10 PM »
Quote from: "I"
imwd dot skaught at gmail.com (gmail or gchat)
:D

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #26 on: October 11, 2011, 09:41:58 PM »
Quote from: "Felix-The-Ghost"
Quote from: "I"
imwd dot skaught at gmail.com (gmail or gchat)
:D
Check your emails.

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #27 on: October 11, 2011, 09:48:18 PM »
Alright. Got it set up. Tomorrow I'll get Skype and Eclipse/Netbeans for Java. I'll be really busy tonight.

Offline EON8ight

  • Stomp Arena Staff
  • Regular
  • *****
  • Posts: 129
  • Dropped the screw in the tuna
    • EON8ight's Repository
Re: I'm rewriting SMW
« Reply #28 on: October 11, 2011, 09:51:01 PM »
Quote from: "Felix-The-Ghost"
Alright. Got it set up. Tomorrow I'll get Skype and Eclipse/Netbeans for Java. I'll be really busy tonight.
Awesome!

Also, for being in the repository, you, Big JM, and KingPepe will be credited as developers. I've got grandiose plans for this. As soon as we can get a stable release out, things will be just like they were back in 2005.

If you need any help with anything, don't hesitate to let me know!

Offline Felix-The-Ghost

  • Too Much Free Time
  • *****
  • Posts: 1305
  • 1v1 Rust
    • http://members.allegro.cc/felix-the-ghost/index.html
Re: I'm rewriting SMW
« Reply #29 on: October 11, 2011, 10:36:44 PM »
Quote from: "Blaspergerstoise"
grandiose

Not really related, but with an accurate definition, that word has more of a negative connotation then positive :P I know what you mean though. No troll, just interesting.

Also, I started playing SMW late 2006, and didn't join (though I shadowed earlier) until 2007 :)
It was a lot more of a community then, though. Fun and creativity was all around. And not just because average age 12 :P

'Night everyone.