Help with game development


(Miloslav Číž) #61

Yes, you’re not using the newly added animation frame in the drawing function, try this:

void drawopponent() {
int frame = opp.stance == OppStance::oppStanding ? 0 : (opp.stance * 2 - 1 + opp.animationFrame);
// ^ This should hopetully select the right opponent sprite.

sprites.drawOverwrite(opp.x,opp.y,opponentImages,frame);
}

Are you even using the standing stance anywhere? Or is the opponent always running?


(JohnnydCoder) #62

Thanks for the help!

I may use the standing position for a slide-tackling function if I have enough memory (which I probably will have).:smile:


(JohnnydCoder) #63

Alright, I think that I have almost everything down with the opponent AI! :slightly_smiling_face:
I have one weird problem, however: the opponent cannot move Right. I don’t know why!:question:


(Miloslav Číž) #64

I don’t know, looking at the code I’ve given you I can’t see any problem – you may have mixed some +ses with -ses somewhere. Could you send me the source files so that I can try to run it and look for the bug? Either post it here (it would probably be best if you put all the files into a zip or rar achive and simply upload it in a post) or if you don’t want to make the code public for some reason, you can send it to me in a private message.


(JohnnydCoder) #65

Sorry @drummyfish, I was a bit busy with the Game Jam and forgot about this project. :slightly_frowning_face:

Here is the source code:

Thanks for waiting!


(Pharap) #66

Now all it needs is a licence and it’s good to go.


(JohnnydCoder) #67

Actually @Pharap, I was handing out the source code so you could look for a bug that I mentioned earlier:

So, I am still working on the project. :wink:


(Pharap) #68

Fair enough, but you should still think about putting a licence on it at some point if you want people to be able to distribute it and/or edit it.
(See here for details.)


I’d like to offer to help you with the bug,
but I’m a bit busy at the moment.


(Simon) #69

Is this the issue you are referring to? The opponent seems to move to the right to me. Can you elaborate on the problem??


(JohnnydCoder) #70

Really? The last time I tested it, the opponent wasn’t moving right.

I’ll look at it again.:smile:

Thanks!


(JohnnydCoder) #71

I checked on projectABE and the bug is still there.

The opponent cannot move :arrow_right: still!

Here’s a video of the problem:
ArduboyRecording

@Pharap, I will look into the license.

Thanks for the link! :grinning:


(Pharap) #72

I haven’t really had chance to look at your code up until now, but I’ve just had a look and I can see your problem(s).


Technically your code shouldn’t actually even be working.

OPP_SPEED is defined as 0.5, which isn’t an integer.
0.5 should be truncated to 0 so opp.x += OPP_SPEED should be equivalent to opp.x += 0.
I’m guessing somehow 0.5 is being rounded to 1?

As for why the opponent won’t move to the right…

You change the opponent’s stance every 50 frames, but you move the opponent every 7 frames.
This means that opp.x never equals ballx, so what happens is the opponent gets stuck in a loop:

if(ballx > opp.x) {
  opp.stance = OppStance::oppRunningR;
}
else if(ballx < opp.x) {
  opp.stance = OppStance::oppRunningL;
}

The opponent gets stuck going back and forth between these two conditions, never breaking out of them because it’s always overshot ballx.

So my advice is:
A) Change OPP_SPEED to 1 or make opp.x a float instead of an int

B)

  if (!opp.hasBall && arduboy.everyXFrames(7)) {
    switch (opp.stance)
    {
      case OppStance::oppRunningR:
        if(ballx < opp.x)
          opp.x += OPP_SPEED;
        break;

      case OppStance::oppRunningL:
        if(ballx > opp.x)
          opp.x -= OPP_SPEED;
        break;

      case OppStance::oppRunningF:
        if(bally < opp.y)
          opp.y += OPP_SPEED;
        break;

      case OppStance::oppRunningB:
        if(bally > opp.y)
          opp.y -= OPP_SPEED;
        break;
    }
  }

And C) I noticed that you don’t actually update the x and y of ballRect, oppRect or playerRect, so when you test arduboy.collide(ballRect, playerRect) and arduboy.collide(oppRect, ballRect), the results aren’t accurate.


(Simon) #73

But if you move to the right, the player does too.

Is it more that you are looking for the difference between the player and enemy and if its different you make the enemy move. If they are the same, he does nothing?


(JohnnydCoder) #74

Thanks @Pharap for your overview of my code!

I am getting some errors saying that player and opp are not being declared in their scopes. Can you help with that?

@filmote, I am going to focus on that soon. I spotted it before, however I am trying to address this problem first.
The problem is that the opponent can’t move to the ball facing right if that makes sense to you. :slightly_smiling_face:

Thanks again!

EDIT: I fixed the error, but now my opponent isn’t moving at all.:slightly_frowning_face:

EDIT #2: I fixed it! Thanks for your help!


(JohnnydCoder) #75

Hey @Pharap, can you tell me how I am not updating the x or y of all my Rects and how to fix that?

Also, could you show me what you think the oppAttack function could look like?

Thanks in advance!


(Pharap) #76

When you do this:

Rect playerRect = {
  player.x, player.y, PLAYER_WIDTH, PLAYER_HEIGHT
};

It copies the value of player.x to playerRect.x and copies the value of player.y to playerRect.y.
That copy only happens once.
This doesn’t magically bind the value of player.x to playerRect.x (or player.y to playerRect.y).
player.x and playerRect.x are two completely separate variables (as are player.y and playerRect.y).

If you want to keep playerRect.x up to date with player.x then you have to manually update it.

However, manually updating it all the time would be a pain the neck.
It would be much easier to only create playerRect as and when you need it (i.e. you only need it when you’re doing collision checking, otherwise you don’t need it).

I.e. instead of:

void oppGoal()
{
	if (arduboy.collide(oppRect, ballRect))
	{
		opp.hasBall = true;
	}

	if(opp.hasBall == true)
	{
		oppScore += 1;
	}
}

Do:

void oppGoal()
{
	Rect ballRect = { ballx, bally, BALL_SIZE, BALL_SIZE };
	Rect oppRect = { opp.x, opp.y, OPP_WIDTH, OPP_HEIGHT };

	if (arduboy.collide(oppRect, ballRect))
	{
		opp.hasBall = true;
	}

	if(opp.hasBall == true)
	{
		oppScore += 1;
	}
}

So you’re only creating the rectangles as and when you need them for collision checking.

Fundamentally your existing problem is (like I said) that the opponent keeps overshooting the ball, so they get trapped in a never ending loop because they never actually reach where the ball is.

The easiest way to solve this is to stop the opponent from moving when they’re in line with the ball.

So you’d be looking at changing this:

case OppStance::oppRunningR:
	opp.x += OPP_SPEED;
	break;

case OppStance::oppRunningL:
	opp.x -= OPP_SPEED;
	break;

To this:

case OppStance::oppRunningR:
	if(opp.x < ballx)
	{
		opp.x += OPP_SPEED;
	}
	break;

case OppStance::oppRunningL:
	if(opp.x > ballx)
	{
		opp.x -= OPP_SPEED;
	}
	break;

However, in addition to that there’s something else you can do.
At the moment, your AI only looks at the ball as if it’s a single point instead of a wide shape.
If you change the code so it looks at the ball as being a wide shape then it will look more realistic/intelligent.

I.e.

Change this:

if(opp.x < ballx)
{
	opp.stance = OppStance::oppRunningR;
}
else if(opp.x > ballx)
{
	opp.stance = OppStance::oppRunningL;
}

To this:

if(opp.x < ballx)
{
	opp.stance = OppStance::oppRunningR;
}
else if(opp.x > (ballx + BALL_SIZE))
{
	opp.stance = OppStance::oppRunningL;
}

And change:

case OppStance::oppRunningR:
	if(opp.x < ballx)
	{
		opp.x += OPP_SPEED;
	}
	break;

case OppStance::oppRunningL:
	if(opp.x > ballx)
	{
		opp.x -= OPP_SPEED;
	}
	break;

To:

case OppStance::oppRunningR:
	if(opp.x < ballx)
	{
		opp.x += OPP_SPEED;
	}
	break;

case OppStance::oppRunningL:
	if(opp.x > (ballx + BALL_SIZE))
	{
		opp.x -= OPP_SPEED;
	}
	break;

And in case it’s not clear why, hopefully this diagram will make sense:
BallRectangle

(I’ve purposely only done X for you, you’ll have to figure out how to generalise it to Y.
If I did Y as well then I don’t think you’d learn as much.)


Also, one of the golden rules of debugging:
Run through the code manually in your head/on paper.
If you figure out what the code is actually doing then the difference between what it’s actually doing and what you want it to do is the solution to your problem.


(JohnnydCoder) #77

Thanks for the help!

Also, thanks for the advice on debugging! :smile:


(JohnnydCoder) #78

One quick question: is there any way to make the font bigger for the arduboy text? :smile:


#79

There’s a few libraries for smaller fonts but I don’t think there are any larger than the 5x8 default


#80

setTextSize?