Pasting the error message (along with the line it's complaining about) would be preferable to a screenshot of the error message.
Based on lordconstant's code, I would guess it's complaining about the player.y variable.
Your sprite code seems to indicate you don't have a y variable for your sprites, but you do have a rect.y variable. Try that.
That said, I would second the suggestion that you look at some tutorials, like the lazyfoo one that was already linked. It will guide you through a lot of these initials issues you're likely to face/question.
For games with 3D movement and collision detection, collision data is usually not hard coded (live in the code as pre-determined values) at all. Instead, collision data lives in the data files loaded while playing the game. This can be e.g. a mesh that's used to represent collision surfaces (potentially with different materials or other ways of distinguishing behaviour).
The collision data is usually not a 1 to 1 representation of the visual data. The collision data is usually a lot simpler -- think boxes and planes instead of intricately detailed corners.
This is often the case for pure 2D games as well, but 2D games tend to be less performance heavy, and can often-times afford more detailed collision data (e.g. pixel perfect collision).
The extent of collision data will vary from game to game. Some games probably have collision in areas you're never able to reach, because it was put in and there was no reason (performance not critical or time not allowing) to remove it again. This is especially true if the components are made by e.g. the art department, and later placed by level designers. The art assets might have included more collision data than was strictly speaking required, due to not knowing in advance how the assets were going to be used in every scenario.
Other games might have a much more aggressive stance, pruning away all unneeded collision data in order to reduce file/memory usage, performance, or other causes.
Something you might see, from the code side, is hard-coded limits to how high and/or low you can go. This can e.g. be used if you happen to fall through the floor, hitting the hard-coded limit might signal "kill the player and respawn him somewhere safe", basically as a "just in case" measure.
the programmer seems to think there should be a more efficient way to detect matches.
Most likely, this is true.
Most likely, this does not matter at all.
Unless there are cases which the code does not handle correctly, or if the code's efficiency is a real (measurable) problem, notions like "it can be done better" should be filed away for the sequel. Your goal is to finish and ship the game, not to rewrite pieces of code until the end of time.
As is often the case, perfect is the enemy of good [enough].
EDIT: If there are real problems (measurable or use cases where it fails), posting details on those specific areas would be required for further feedback.
EDIT 2: Ninja skills are definitely improving today.