Skip to main content

News

Topic: Mooch's Platformer (with Questions™) (Read 3225 times) previous topic - next topic

  • Mooch
  • [*][*][*]
Mooch's Platformer (with Questions™)
I'm making a platformer, and as the title indicates, I have some questions about my own code which, paradoxically, I think someone else can answer better than me.

Okay, so I'm messing around and I don't understand why my gravity script doesn't work the way I think it should.

Code: (Javascript) [Select]
function gravity() {
  var blobX = GetPersonX("blob");
  var blobY = GetPersonY("blob");
  var blobDown = blobY + 16;
  var blobObstructed = IsPersonObstructed("blob",blobX,blobDown);
  if (blobObstructed = 1) {
  QueuePersonCommand("blob",COMMAND_MOVE_SOUTH,true);
  }
    else {
    QueuePersonCommand("blob",COMMAND_MOVE_WEST,true);
    }
}

function game() {
CreatePerson("blob", "blob.rss", false);
AttachInput("blob");
AttachCamera("blob");
SetRenderScript("gravity();");
MapEngine("room1.rmp", 60);
}


(The Command_Move_West is just there to test.)

Okay, so for some reason, this script just makes the character move downward no matter what! It's as if blobObstructed returns 1 no matter what, which it shouldn't. I tested by putting the character in the middle of nowhere, with nothing underneath. Still moves downward. Why is this?

Also, the way this script works (I know it's crap, by the way, just messing around for now), you can still move the character back and forth, both as its falling and after it hits the ground. However, if I change the SetRenderScript to a SetUpdateScript, the player's ability to control the character is completely frozen, you can't move the character at all, it just goes down 'til it hits an obstruction then stays there. I don't understand why that should be. Then again, I kinda forget how Render vs UpdateScript works, so...

Any help would be mucho appreciado ^_^

(P.S. Secret Bonus Question: If I change the QueuePersonCommand's "true" parameter to "false," you can move left and right while falling, but once you hit the ground, the character becomes unmovable. I can't figure out why that parameter would have that effect.)
  • Last Edit: May 11, 2014, 12:24:31 am by Mooch

Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #1
You're writing "if (blobObstructed = 1)" instead of "if(blobObstructed == 1)".  =  is the assignment operator while == is the comparison operator, you are setting blobObstructed equal to 1 every time.

  • Mooch
  • [*][*][*]
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #2

You're writing "if (blobObstructed = 1)" instead of "if(blobObstructed == 1)".  =  is the assignment operator while == is the comparison operator, you are setting blobObstructed equal to 1 every time.


...

...

*turns away*
(Don't let them see you cry. Don't let them see you cry tears of shame.)

Heh, thanks. Man, see? Always miss little things like that.

I also messed up a few other things; blobObstructed should check for 0, not 1, and the blobDown variable is unnecessary. In fact, running it the way I have it, it lets you "walk" up one tile. Like, just float one block off the ground, and doesn't make you fall. If I just use blobY it's fine.

New probs, but they're due to the crappy code, presumably. For instance, the code makes you walk slow 'cause it's constantly shoving you downward. I can easily fix that by checking whether you're in contact with the ground, and skipping the gravity thing if so. Well, probably not "easily" for me, but you know.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #3
When you program, you ask questions and no, they are not the of the kind you ask a community (unless it's dire). The kind of programming questions you ask are the kind like: What value must I check against? When this happens what happens as a result? If this... While this is... Do that... You. Ask. Questions.

I think what you demonstrated in the post right above mine is the ability to look back, actually read what you typed, and fix the mistake. You might be thinking this is a rare off chance occurrence, simply by being hasty to post your troubles here, but I've seen this from you before. I know; I was much like you. But it takes time to work things out.

Also learning from examples is great, it's really how I learned. So, I would post a gravity tutorial here. but I'm exhausted right now. I'll do it tomorrow or sometime after. But I think you demonstrate the gist of gravity in your first post. The next thing to work on is obstruction handling.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Mooch
  • [*][*][*]
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #4
^ *can't figure out if that was an admonishment*

It wasn't hastiness, though, it was complete obliviousness, heh. It's been months since I've written any code whatsoever, I forgot about the double equals. Or rather, I assumed that the code would know I was checking and not assigning within the parenthesis of an if statement.

I've decided to tease out the detection from the gravity code. I'm gonna make two separate functions.

1) A "player state checker," which determines if the player is standing, falling, swimming, flying, moving, dying (mail upgrade it). Not interested in generalizing this to be a "any given entity state checker" 'cause I'm just doing whatever just to get some code working however my brain figures out to do it.

2) The gravity code, which shoves the player around depending on her state.

(This post was originally much longer, but I cut it all out. From now on, I'm gonna try to post as much code as possible and as little rambling and thinking-out-loud as possible.)

Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #5
I'd say it'd be a good idea to get a programming buddy over skype or something who can look over your code for dumb things that you don't catch because you just wrote that code. I'd liken it to having someone proofread something you just wrote, because unless you wait a couple days before picking it up again you'll think "yes, this is correct, I just wrote this" instead of thinking "wow i missed something really obvious how did I do that"

  • Mooch
  • [*][*][*]
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #6

I'd say it'd be a good idea to get a programming buddy over skype or something who can look over your code for dumb things that you don't catch because you just wrote that code. I'd liken it to having someone proofread something you just wrote, because unless you wait a couple days before picking it up again you'll think "yes, this is correct, I just wrote this" instead of thinking "wow i missed something really obvious how did I do that"


That'd be awesome! But Skype et. al. are out because I have hyperacusis and can't stand pretty much any sort of sound at all, especially electronic sounds (i.e. a speaker or earbuds or whatevs). I'm only even able to use a computer at all 'cause I have a silent setup. Plus I also have a sleep disorder, so my schedule's highly irregular. Also, if I bug one specific person, they're sort of obligated to respond. If I make a topic like this, though, anyone who wants to respond can, and anyone who doesn't doesn't have to.

Maybe if everyone has a Facebook profile I could just Friend you all, and anytime I have a tiny question like this, I could PM whoever's online. But like I said, then that's a one-on-one, sorta foists my problems on one single person, whereas with an open topic like this, you could just ignore it if you wanted and no one would know.

Most of my posts in this topic aren't going to be as ridiculously simplistic as that first one was, though. Like I said, I'm just months out of it.

EDIT: Booyah.

Code: (Javascript) [Select]
// Player data.
var blobX = 0;
var blobY = 0;
var blobYV = 0;  // y velocity
var blobYVM = 4; // y velocity max
var blobGravity = 0.25;
var blobJump = 3;
var blobObstructed = 0; // obstructed below, obviously

function PlayerMovement() {
blobX = GetPersonX("blob");
blobY = GetPersonY("blob");
if (IsKeyPressed(KEY_LEFT)) {
QueuePersonCommand("blob",COMMAND_MOVE_WEST,true);
}
if (IsKeyPressed(KEY_RIGHT)) {
QueuePersonCommand("blob",COMMAND_MOVE_EAST,true);
}

blobObstructed = IsPersonObstructed("blob",blobX,blobY+1);
if (blobYV < blobYVM) {  
blobYV += blobGravity;
}
// Always pushes player downward. That's gravity!

if (blobYV > 0 && blobObstructed == 0) {
SetPersonY("blob",blobY += blobYV);
}
// Fall when not obstructed, don't fall when not not obstructed.
}

function game() {
CreatePerson("blob", "blob.rss", false);
AttachCamera("blob");
SetRenderScript("PlayerMovement();");
MapEngine("room1.rmp", 60);
}


Works great. Well, I'm still playing with the gravity. Trying to get a more natural fall effect. Prolly gonna have to use exponents or summat. And obvs gotta add a lot more stuff, like jumping for one. The point is, it works.

Toldja. Just outta practice.

I originally tried doing this OOP style, but for some reason it just wouldn't work. The code was basically identical, just all up inside a Class. It threw a "Player1.update is not a function" error in my face, but it totally WAS a function. How rude!

Once I ripped everything out and used global variables, though, all was well. I'll try shoving it back inside a class some other time. My eyes and joints are achin'. I really shouldn't code for more than half an hour at a time. (This took me an hour.)
  • Last Edit: May 09, 2014, 04:47:44 pm by Mooch

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #7
Hey if you want to see that as a class, here you go, I also added the ability to detect jumps. It's nowhere near the level of Mario but I think it shall suffice. Look at the landed variable it's important to the reason why jumping can't be exploited. Also, the landing isn't perfect, it may hover a few pixels above the ground because of the speed. Falling at full speed he'll move at 4 pixels per frame. That means depending on the frame he could be considered 'at ground' anywhere between 0 to 3 pixels above the floor. There are ways of fixing this, but it involves a bit more code and, well, this is good enough to get the idea of what a platformer is all about.

Code: (javascript) [Select]

function GravityEngine(name) {
this.YV = 0;  // y velocity
this.YVM = 4; // y velocity max
this.gravity = 0.25;
this.jump = 3;
this.name = name;
this.landed = false;

this.playerMovement = function() {
var x = GetPersonX(this.name);
var y = GetPersonY(this.name);
var isObstructed = IsPersonObstructed(this.name, x, y + this.YV);

if (IsKeyPressed(KEY_LEFT)) {
QueuePersonCommand(this.name, COMMAND_MOVE_WEST, false);
}

if (IsKeyPressed(KEY_RIGHT)) {
QueuePersonCommand(this.name, COMMAND_MOVE_EAST, false);
}

if (IsKeyPressed(KEY_SPACE) && this.landed) {
this.YV = -this.jump;
this.landed = false;
isObstructed = false;
}

// Always pushes player downward. That's gravity!
if (this.YV < this.YVM) {  
this.YV += this.gravity;
}

// Fall when not obstructed, don't fall when not not obstructed.
if (!isObstructed && !this.landed) {
SetPersonY(this.name, y + this.YV);
}
else if (isObstructed) this.landed = true;
}
}

var gravity = new GravityEngine("blob");
function game() {
CreatePerson("blob", "player.rss", true);
SetUpdateScript("gravity.playerMovement();");
MapEngine("testmap.rmp", 60);
}



^ *can't figure out if that was an admonishment*


It was admonishment because it was criticism because it was sage advice. ;) 90% of all small programming concerns are figured out 10 minutes away from the keyboard. It's weird, but while a forum is indeed there to answer questions, sometimes small things can be almost annoying especially when they make a post 3 minutes later saying: "I found the solution myself, thanks!". I have seen so much of that.  :-\
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #8
I should add, sometimes you can agonize over a problem for a very long time, and still find the answer almost immediately after asking the question  :)

I wouldn't want anyone here to be afraid to ask questions in general.

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #9

I should add, sometimes you can agonize over a problem for a very long time, and still find the answer almost immediately after asking the question  :)

Yeah, I find this usually happens because you re-analyze and explain your code.

  • Mooch
  • [*][*][*]
Re: Mooch's Big Fat "Why Doesn't This Work" Topic
Reply #10
I feel very proud to say, for the first time ever in life, I didn't find Radnen's sample code useful. Because I already did even better!

Code: (Javascript) [Select]
// Player data.
var blobX = 0;
var blobY = 0;
var blobYV = 0;  // y velocity
var blobYVM = 4; // y velocity max
var blobGravity = 0.25;
var blobJump = 3.5;
var blobAbove //
var blobBelow // obstruction checkers
var jumpYet       //
var lastJump = 0; // to prevent rapid jumping

function PlayerMovement() {
// Seed the variables with the player's current data.
blobX = GetPersonX("blob");
blobY = GetPersonY("blob");
blobAbove = IsPersonObstructed("blob",blobX,blobY-12);
blobBelow = IsPersonObstructed("blob",blobX,blobY+1);

// Left and right movement. Need to add animation, directions.
if (IsKeyPressed(KEY_LEFT)) {
QueuePersonCommand("blob",COMMAND_MOVE_WEST,true);
}
if (IsKeyPressed(KEY_RIGHT)) {
QueuePersonCommand("blob",COMMAND_MOVE_EAST,true);
}

// ugh, even _I_ think this is an eyesore, but it stops you falling through the floor
if (blobYV < blobYVM) {
blobYV += blobGravity;
}
if (blobYV > 0 && IsPersonObstructed("blob",blobX,blobY+blobYV+1)) {
var vBuff = 0;
while (!IsPersonObstructed("blob",blobX,blobY+vBuff))
vBuff++;
SetPersonY("blob",blobY+vBuff-1);
blobYV = 0;
}
else {
if (blobYV < 0 && IsPersonObstructed("blob",blobX,blobY+blobYV))
blobYV = 1;
SetPersonY("blob", blobY+blobYV);
}

// lets you jump from the ground if there's no block above you
jumpYet = GetTime() - lastJump; // stops you jumping rapidly up staircases
if (jumpYet > 450 && blobAbove == 0 && blobBelow == 1 && IsKeyPressed(KEY_D)) {
blobYV = -blobJump;
lastJump = GetTime();
}
}

var blah = "";
var font = GetSystemFont();

function mainLoop() {
PlayerMovement();
blah = blobYV.toString();
font.drawText(16, 16, blah);
}

function game() {
CreatePerson("blob", "blob.rss", false);
AttachCamera("blob");
SetRenderScript("mainLoop();");
MapEngine("room1.rmp", 60);
}


It's still a bit messy and disorganized (I still really haven't found a comment style that's quite "me"), and I haven't done it OOP style (though I'm not sure if it's worth the bother considering the miniscule scope of this project), but it works like a mofo -- not only does my fancy new gravity code prevent you from getting stuck in the floor (by using a "buffer" to check for obstructions ahead of the player and reel back the blobYV if so, thus preventing wonky numbers from shoving you a few pixels into the ground), but I used GetTime to add a subtle delay to jumping, because before I added that, if there was a staircase and you ran at it while holding Jump, you'd just zoom right up the staircase ('cause the second a single pixel of yours had a ground tile under it, it'd let you jump again). Now, with the delay, you'll jump up on stair at a time.

There's two things I don't understand, though.

1) My jump delayer makes you jump shorter than before. Prior to implementing it, a blobJump value of 3 allowed you to just jump one block high. After implementing it, you can't surmount a single block with blobJump = 3. I had to increase it to 3.5, and I just cannot figure out why that should be.

2) I got stuck with my "vertical buffer" code, so I cracked open Vince's Flippin' Matrix code and found something similar and better, and used it to fix what was wrong with mine. I can't figure something out, though. In the last section of the code...
Code: (Javascript) [Select]
	else {
if (blobYV < 0 && IsPersonObstructed("blob",blobX,blobY+blobYV))
blobYV = 1;
SetPersonY("blob", blobY+blobYV);
}

...if you put curly brackets after the "if" like normal, it screws up the code. That is, if you change the above to this...
Code: (Javascript) [Select]
	else {
if (blobYV < 0 && IsPersonObstructed("blob",blobX,blobY+blobYV)) {
blobYV = 1;
SetPersonY("blob", blobY+blobYV);
                }
}

...the code breaks. It won't let you jump, and prevents you from falling (you can walk off a cliff onto thin air).

For the life of me, I can't figure out why bracketing that 'if' does that. Because it's inside an else? Is that a thing? Maybe I just never put an 'if' inside an 'else' before, so I never noticed.

Next up, I'm gonna add momentum to jumping. That way, if you jump while running, you can't hold in the opposite direction midair and totally turn around, you can merely modulate how far in the original direction you jump (keep holding in forward, jump farther; hold in backward, jump less far).

Then I'll probably add swimming, and then that'll probably be it for the features. Then I'll pretty-up the code, prolly go OOP after all, if only 'cause I'll be able to more easily re-use the code later.

I'm gonna have fewer "why doesn't this work" questions than I thought, and more "why does this work the way it does" questions and "woo hoo finished some code" showoffmanship. So I've renamed the topic accordingly.

(Vince, you'll get a credit since I hijacked some Flippin' Matrix code to fix my own dumb buffer code.)

((Hee hee! A credit! I'm actually making a game ^_^))

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Mooch's Platformer (with Questions™)
Reply #11
I'm glad you are figuring it out! :)

Code: (javascript) [Select]

else {
                if (blobYV < 0 && IsPersonObstructed("blob",blobX,blobY+blobYV)) {
                        blobYV = 1;
                        SetPersonY("blob", blobY+blobYV);
                }
        }


The reason the brackets don't work here is because the line of code is really like this:
Code: (javascript) [Select]

else {
                if (blobYV < 0 && IsPersonObstructed("blob",blobX,blobY+blobYV)) {
                        blobYV = 1;
                }
                SetPersonY("blob", blobY+blobYV);
        }


When you use an if, curly brackets are optional. But! If you don't use curly brackets only the first thing to the next ';' semicolon is considered. That's why it did what it did. The if condition only saw the next line, the blobYV = 1 part then stopped. By putting curly braces after an if you are telling it to look past just the first statement, but instead a list of statements in the block.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Mooch
  • [*][*][*]
Re: Mooch's Platformer (with Questions™)
Reply #12
Ohh! I see. Thanks ^_^

In unrelated and depressing news, I gotta scrap my gravity and jumping code :(

I was testing in an open room, and it worked fine. If I was making something like Mario, the code would be just dandy. However, I'm making something with mostly single-block passages (the levels look like mazes, despite being sidescrolling), and for some reason the code won't let the character jump or fall into one-block sideways passages.

Presumably it's the buffer. Since it's checking ahead of the player for obstructions, you can't "fit" into a one-block-high passage.

Oh well, back to the drawing board. Gonna have to think of some other way of preventing falling into blocks.

Re: Mooch's Platformer (with Questions™)
Reply #13
Even if this is just a litle project, I would like to see this completed and kept here somewhere.

When I tackled gravity before, I could find hardly anything on it here or on the old forums. It would be nice to have a example project :)

Keep up the good work all! :)