Is there a way to make a object visible at a random place?
Once again I have trouble with NoBlock I think, the room is like this: player is in a cellar. There are rats running around. If the player kicks a rat and the rat close enough the rat dies.
So I have the rat (the first of them) as a character and I want a object to appear where the rat is as it dies. If that’s not possible or too hard for a novice like me I guess I just give the player the rat in the inventory but I thought I ask here first.
Here is my code:
// main global script file
function cRat_1_Mode8()
{
if ((cRat_1.x - cRose.x < 200) && (cRat_1.x - cRose.x > -200) && (cRat_1.y - cRose.y < 120) && (cRat_1.y - cRose.y > -120)) {
cRose.Say("hit");
//object[1].Move(cRat_1.x, cRat_1.y, 5, eNoBlock, eWalkableAreas);
//cRat_1.Transparency=100;
//object[1].Visible=true;
Ratisdead=true;
}
else{
cRose.Say("Miss");
}
}
// room script file
int beeninroom;
bool closeenoughtofight;
bool deadrathere;
function room_Load()
{
gHealth.Visible=true;
deadrathere=false;
}
function room_RepExec()
{
if(deadrathere==false)
{
if (character[2].Moving!=1)
{
character[2].Walk(Random(320),Random(200));
oDeadrat.Move(cRat_1.x, cRat_1.y, 50, eNoBlock, eWalkableAreas);
}
}
if ((cRose.IsCollidingWithChar(cRat_1) == 1)&&(deadrathere==false))
{
cRose.Say("Oach!");
health-=1;
}
if (Ratisdead==true)
{
cRat_1.Transparency=100;
//oDeadrat.Move(cRat_1.x, cRat_1.y, 5, eNoBlock, eWalkableAreas);
//oDeadrat.StopMoving();
//Wait(100);
deadrathere=true;
cRat_1.Clickable=false;
oDeadrat.Visible=true;
//cRat_1.Solid=false;
}
Well you're using Object.Move (which is similar to Character.Walk or Character.Move). It's intended to, over time move the object from it's current coordinates to the newly specified ones. If you want to directly set the object's position, instead of having it "walk" or "move" to those coordinates, you can just set the coordinates directly:
// player kicks rat
oDeadrat.X = cRat_1.x;
oDeadrat.Y = cRat_1.y;
Keep in mind that Object.X/Y are capitalized while Character.x/y are lower-case (due to backwards-compatibility). Also you might consider making your rat-kicking a bit more generic, since presumably the code will be largely the same. So just basing it off what you have:
void KickRat(Character *rat)
{
if ((rat.x - cRose.x < 200) && (rat.x - cRose.x > -200) && (rat.y - cRose.y < 120) && (rat.y - cRose.y > -120))
{
cRose.Say("hit");
Ratisdead = true;
}
else cRose.Say("Miss");
}
function cRat_1_Mode8()
{
KickRat(cRat_1);
}
That way you don't have to copy and past the same code over and over for each rat. You can just call the function and pass in the appropriate Character. I know you're not the strongest of programmers (though you do put a very strong, admirable effort forward :=), so let me know if I need to clarify that further.
Also, it might make more sense for you to use a standard distance function to check the distance between the player and the rat..unless you want to specifically be able to control separate distances along each axis?
Edit: By the way, just off the top of my head I was looking at this, and if the rat was at (0, 0) and the player was at (199, 119) the player would be able to kick the rat. This character of yours seems to have some rather long legs! Oh, and:
int DistanceFromCharacter(this Character*, Character *otherCharacter)
{
int x = (this.x - otherCharacter.x);
int y = (this.y - otherCharacter.y);
return FloatToInt(Maths.Sqrt(IntToFloat((x * x) + (y * y))));
}
// usage:
if (cRat_1.DistanceFromCharacter(cRose) <= 50)
{
// if rat was within 50px of cRose...
}
Do you want a number of rats randomly running around without blocking the character/player actions? If this is the case then you will need to move the rat characters using the eNOBLOCK option and check for their movement complete in repeatedly_execute(). When movement is complete then you could randomly select another position to walk to.
Here is some untested code that illustrates whatI'm talking about. I don't have AGS installed on this computer so I didn't lookup the built-in functions used below for the correct parameter list. Sorry but you'll have to correct any errors yourself. HYope you find this helpful.
// *** Room Script ***
define MAXX 640
define MAXY 400
function MoveRat(character *rat) {
int x,y;
if (rat.IsMoving()) {
// Do nothing
}
else {
x = Random(MAXX);
y = Random(IMAXY);
rat.Move(x,y,ENOBLOCK);p
}
}
function repeatedly_execute() {
MoveRat(eRat1);
MoveRat(eRat2);
MoveRat(eRat3);
MoveRat(eRat4)
:
MoveRat(eRatN);
}
Thanks for the flattery but I think you spoke too soon, sir. :=
Could you help me with one more thing, please?
Where do I put the code? ???
I guess I really only need to check the base line as the rat isn’t so big but could be useful for other things, although the legs shouldn’t be that long! ;D
And thanks RickJ too, I will look into your code too. :)
Well checking only the baseline would actually probably make the problem worse because then if the rat was at (0, 120) and the player was at (320, 120) they would be able to kick the rat, but if the player was at (0, 121) they wouldn't be able to.
Seeing as there's some confusion about where to place the code, let me help you out:
// main global script file
int DistanceFromCharacter(this Character*, Character *otherCharacter)
{
int x = (this.x - otherCharacter.x);
int y = (this.y - otherCharacter.y);
return FloatToInt(Maths.Sqrt(IntToFloat((x * x) + (y * y))));
}
void KickRat(Character *rat)
{
if (cRose.DistanceFromCharacter(cRat) <= 50) // rat is within 50px, adjust this as needed
{
cRose.Say("hit");
Ratisdead = true;
}
else cRose.Say("Miss");
}
function cRat_1_Mode8()
{
KickRat(cRat_1);
}
// room script file
int beeninroom;
bool closeenoughtofight;
bool deadrathere;
function room_Load()
{
gHealth.Visible = true;
deadrathere = false;
}
function room_RepExec()
{
if (!deadrathere) // this is the same as checking for false, just shorter
{
if (!cRat_1.Moving) // I'm guessing character 2 is cRat_1?
{
cRat_1.Walk(Random(320), Random(200));
}
}
if ((cRose.IsCollidingWithChar(cRat_1)) && (!deadrathere))
{
cRose.Say("Ouch!");
health--; // this is the same as -= 1
}
if (Ratisdead)
{
cRat_1.Transparency = 100;
deadrathere = true;
cRat_1.Clickable = false;
oDeadrat.Visible = true;
}
}
And Rick, I'm not really sure why you felt the need to explain code that she was already using. I know you said you didn't have AGS installed, but there's also a number of glaring issues in your code that a quick glance-over would indentify (including the lack of a hash '#' at the start of your #define macros, misspelling your macro "MAXY" as "IMAXY", and an erroneously-typed 'p' at the end of one of the lines). Even without a compiler I would imagine that to a trained programmer's eye these would be rather obvious.
A function to simplify the random walking code is a good idea if she's going to have a lot of characters roaming around, so no offense intended by what I said about explaining the code. I just meant that she was already handling it. Angel, if you want to implement Rick's code, let us know if you have problems as it's pretty easy to fix (it's just another way of doing what you're already doing, but simplified for multiple characters). ;)
Monkey, apparently my brain was running in standby mode when I made the post. Clearly I didn't read and understand BA's original post as thoroughly as I should have. Thought she was having the typical problem many people have with non-blocking background action.
Funny thing you should mention the #define thingy -- I do vaguely remember thinking that those naked defines looked funny for some reason. :=
[edit]
BlueAngel thanks for your kind words. ;)
Looks like it works well in my tryout game, now I going to try it in my real game too. :)
Just changed this:
function cRat_1_Mode8()
{
KickRat(cRat_1);
object[0].X = cRat_1.x;
object[0].Y = cRat_1.y;
}
Off to play around with the distance to see how long legs she really has. ;D
My miller is happy with all help :)
(http://www.tumblr.com/photo/1280/7795630724/1/tumblr_lokfircxZk1qmtukk)