Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: MurrayL on Fri 11/01/2013 11:06:20

Title: Pointer type question
Post by: MurrayL on Fri 11/01/2013 11:06:20
Can someone please explain the difference between these two variable declarations?

Code (AGS) Select

Character *myCharacter = cEgo;
// and
AudioChannel* myChannel = aSound1.Play();


What is the effect of the asterisk being before the variable name as opposed to after the type, and vice versa?
Title: Re: Pointer type question
Post by: Khris on Fri 11/01/2013 11:48:00
There's no difference.
It's better form to use the latter because the asterisk is part of the type, not the name, but it doesn't matter to the compiler (which ignores whitespace outside of strings anyway).

It also becomes apparent if you define multiple pointers like so:
Code (ags) Select
Character* enemy1, enemy2;
Title: Re: Pointer type question
Post by: MurrayL on Fri 11/01/2013 11:51:54
Ah, that's a relief.

I've always put the asterisk after the type, but I've seen a few forum posts (and I'm pretty sure there are even a few instances in the AGS manual) where people have done it the other way around. Wanted to make sure I wasn't doing something wrong!
Title: Re: Pointer type question
Post by: SpeechCenter on Fri 11/01/2013 11:59:51
In C you can have
Code (C) Select
int *p1, i2;
or
Code (C) Select
int* p1, i2;
which in fact defines the same thing, a pointer to int (p1) and an int (i2). Therefore many prefer the first when using C and maybe that's why you saw these examples.

However, since AGS doesn't really have pointers as in C, you cannot define
Code (AGS) Select
Character *char1, *char2;
only
Code (AGS) Select
Character* char1, char2;

So it's true that in AGS attaching the pointer to the type makes it clearer.

(By the way, all of my examples are actually considered bad style since it's much clearer to define variables in separate lines)
Title: Re: Pointer type question
Post by: selmiak on Sun 13/01/2013 01:30:43
You learn something new every day. This confused me too as the manual really does it the one way and sometimes even within the same paragraph also the other way. Thanks for this topic :)
Title: Re: Pointer type question
Post by: miguel on Mon 14/01/2013 10:00:40
Sorry for using this topic but it's related to pointers as well.

Header:
Code (AGS) Select
struct herostats {
  int level;
  int exp;
  int max_exp;
  int health;
  int strenght;
  int dext;
  int atack_sword;
  int atack_mace;
  int atack_dagger;
  int atack_ranged;
  int atack_bolt;
  int armour;
  int defense;
  int luck;
  int mp;
  int damage;
  String name;
  String class;
  Character* Char;
};

Code (AGS) Select
import herostats stHero;

Main Global:
Code (AGS) Select
herostats stHero;
Code (AGS) Select
export stHero;

I found that I can use without problems something like:
Code (AGS) Select
stHero.Char.LockView(6);
      stHero.Char.Animate(2, 5, eOnce, eBlock);


But in a while loop, on a array attached to the struct, I get a null pointer when using the .Char reference.
Header:
Code (AGS) Select
struct badguystats {
  int level;
  int health;
  int strenght;
  int dext;
  int atack_sword;
  int atack_ranged;
  int atack_magic;
  int atack_bolt;
  int armour;
  int defense;
  int luck;
  int mp;
  int damage;
  String name;
  String class;
  Character* Char;
};
import badguystats stbandit[3];

Main:
Code (AGS) Select
badguystats stbandit[3];
export stbandit;


Function that returns null pointer:
Code (AGS) Select
function enemydetection() {
  int closestEnemy = -1;
  int maxRange = 700;
  int xDiff; int yDiff; int enemyDistance;
  int i=0;
  while (i< Game.CharacterCount) {
  xDiff = stHero.Char.x - stbandit[i].Char.x;
  yDiff = stHero.Char.y - stbandit[i].Char.y;
  enemyDistance = xDiff*xDiff + yDiff*yDiff;
  if (enemyDistance < maxRange) {
    stbandit[i].Char.FollowCharacter(stHero.Char, 0, 0);
  }
i++;
  }
}


What did I do wrong?
Title: Re: Pointer type question
Post by: Crimson Wizard on Mon 14/01/2013 10:19:19
@miguel:
And how do you initialize Char pointer for stHero and stbandits? That's more important.
I think that problem is that you count 0th character as 0th bandit, which is probably not correct. This is only a guess, by I think that character with id = 0 is player? In which case you should start counting from ID=1, and access bandits as stbandit[i - 1] in that loop. This will also prevent from forcing player character to follow himself.
Title: Re: Pointer type question
Post by: miguel on Mon 14/01/2013 10:43:13
Crimson, thanks for your reply:
I initialize them at game start:
Code (AGS) Select
function game_start()
{
  mouse.Mode=eModePointer;
  //////////////////////////////////////////////////////////
stHero.Char=cHero;
stHero.armour=1;
stHero.atack_dagger=1;
stHero.atack_mace=1;
stHero.atack_ranged=1;
stHero.atack_sword=1;
stHero.class="Not defined";
stHero.defense=1;
stHero.dext=1;
stHero.exp=0;
stHero.health=40;
stHero.level=1;
stHero.luck=1;
stHero.max_exp=1000;
stHero.mp=0;
stHero.name="Unknown";
stHero.strenght=1;
////////////////////////////////////////////////////////////
stbandit[1].armour=2;
stbandit[1].atack_magic=0;
stbandit[1].atack_ranged=0;
stbandit[1].atack_sword=2;
stbandit[1].Char=cbandit;
stbandit[1].class="Bandit";
stbandit[1].defense=2;
stbandit[1].dext=1;
stbandit[1].health=55;
stbandit[1].level=1;
stbandit[1].luck=2;
stbandit[1].mp=0;
stbandit[1].name="Bandit";
stbandit[1].strenght=2;


I'm trying what you said right now...

Edit: still get a null pointer
Title: Re: Pointer type question
Post by: Crimson Wizard on Mon 14/01/2013 10:55:54
Ah. So you init bandit starting from 1st index, not 0. In which case my suggestion about using stbandit[i - 1] was wrong.
But in same case you must start the loop from i = 1, because stbandit[0] has uninitialized Char pointer (but use stbandit[ i ] as before).
Title: Re: Pointer type question
Post by: miguel on Mon 14/01/2013 11:03:29
Got it!
Now I get array out of bounds on line 7
Code (AGS) Select
function enemydetection() {
  int closestEnemy = -1;
  int maxRange = 700;
  int xDiff; int yDiff; int enemyDistance;
  int i=1;
  while (i< Game.CharacterCount) {
  xDiff = stHero.Char.x - stbandit[i].Char.x;
  yDiff = stHero.Char.y - stbandit[i].Char.y;
  enemyDistance = xDiff*xDiff + yDiff*yDiff;
  if (enemyDistance < maxRange) {
    stbandit[i].Char.FollowCharacter(stHero.Char, 0, 0);
  }
i++;
  }
}
Title: Re: Pointer type question
Post by: Crimson Wizard on Mon 14/01/2013 11:07:32
:).
Well, what you are doing there, is making a loop from 0 to X, where X = number of characters. And for every i you pick one item from "bandits" array.
Question is, is number of characters the same as "bandits" array size? Is there a "bandit" corresponding to every character, or only to a few? Maybe you shouldn't make a loop like that, but use different condition?
Title: Re: Pointer type question
Post by: miguel on Mon 14/01/2013 11:27:14
Okay, now I understand. My little dungeon seems to be working now.
I was using scripts from the forums (the one in this topic obviously) to base my code and every program is its own case.
I know I'll mess it up again but until then thank you very much Crimson.

I wish the tutorial for beginners in pointers was more friendly. The day I fully understand it I will make one for cavemen like me!