Click and drag puzzle

Started by maraki_ang3l, Thu 04/06/2009 16:48:00

Previous topic - Next topic

maraki_ang3l

I read in an older post how to click and drag pieces in oder to complete a puzzle but it was too old and the scripting language has changed i imagine.
Well in my game I have 8 pieces placed in my room , as objects and need to place them  correct .
First I want to be able to hold them with the left button and then to place them at the correct hotspot.
Can anyone help me with the scripting? :)

NsMn

Did you try the old script? Which errors did you get? It usually should work, though.

maraki_ang3l

http://www.adventuregamestudio.co.uk/yabb/index.php?topic=9963.0 


Here is the old post i have found and one member has uploaded a link with a puzzle i imagine exactly as i want it but when i download it ,AGS doen't run it

.M.M.


maraki_ang3l

May I ask a question I think silly but importart to me...How do I imort the modules into my game?

Matti

Right-click "scripts", chose "import script" and then the module file.

maraki_ang3l

This module doesn't help me but I fount this piece of code that could work if someone could help me a little bit with the "bold" expresions



int button_pressed=0, ob=-1;

if (mouse.IsButtonDown(eMouseLeft)) {
    if (button_pressed==0) {
      button_pressed = 1;
      ob = GetObjectAt(mouse.x, mouse.y);
     
    }
  } else {
    button_pressed=0;
    if (ob!=-1) {
      SetObjectBaseline(ob, 0);   
      ob=-1;
    }
  }
   

  if (ob != -1) {
    int width  = GetGameParameter(GP_SPRITEWIDTH, GetObjectGraphic(ob), 0, 0);
    int height = GetGameParameter(GP_SPRITEHEIGHT, GetObjectGraphic(ob), 0, 0);
    SetObjectBaseline(ob, game.room_height);
    SetObjectPosition(ob, mouse.x-width/2, mouse.y+height/2);
  }

Khris

This should work:

Code: ags
  int button_pressed;
  Object*ob;

  if (mouse.IsButtonDown(eMouseLeft)) {
    if (button_pressed==0) {
      button_pressed = 1;
      ob = Object.GetAtScreenXY(mouse.x, mouse.y);
    }
  } else {
    button_pressed=0;
    if (ob!=null) {
      ob.Baseline = 0;   
      ob=null;
    }
  }
   
 
  if (ob != null) {
    int width  = Game.SpriteWidth[ob.Graphic];
    int height = Game.SpriteHeight[ob.Graphic];
    ob.Baseline = game.room_height;
    ob.SetPosition(mouse.x-width/2, mouse.y+height/2);
  }

maraki_ang3l

My friend thank you very much I put your code but i put it in the fuction

function oPiece_Interact() 


which I guess isn't correct because when I click the object with  my mouse the object goes al little bit further and stops.In which Fuction am I supposed to put it in order to this code to work for my 8 pieces?

Khris

It should probably be inside the room's RepExec.

GuyAwesome

Yeah, I'd guess it should be in the room's repeatedly execute function (room_RepExec), except for the lines
Code: ags

  int button_pressed;
  Object*ob;

which can be anywhere before room_RepExec, outside of any other functions. By putting it in oPiece_Interact, it'll only move the piece when the mouse button is first pressed instead of until it's released.

If you want to make it so that only a particular cursor mode works (like Interact), you'll need to change
Code: ags

  if (mouse.IsButtonDown(eMouseLeft)) {

to
Code: ags

  if (mouse.IsButtonDown(eMouseLeft) && mouse.Mode == eModeInteract) {


maraki_ang3l

If I put the code in the room_RepExec how will it "work" with the objects of the room ,I make this question because I put the code there  and the mouse does't "catch"  my objects   :(

Thank you so mush for helping me  :)

GuyAwesome

If it's in room_RepExec, it should 'catch' your objects because of the ob = Object.GetAtScreenXY(mouse.x, mouse.y); line, basically works if you click ANY object, without having to set up individual interactions for each.
And it should be working - I've tried KhrisMUC's code, and it does exactly what it should. If it's not grabbing your objects, the only things I can think are:
The object isn't clickable (which doesn't make sense if it worked in oPiece_Interact).
The object is an odd shape or too small, and the cursor isn't quite over it when you click.
Did you create the room_RepExec function properly (in the 'Events' tab in the editor), or just type it into the room script?

maraki_ang3l

#13
 :o  I am sooo asamed , you are so right...I had written room_RepExec function properly in the 'Events' tab and then deleted it while I was experimenting...so so sorry.

That's why it din't work ...


With the ags can I place an object onto a hotspot and the puzle get solved. because if i type something like

if (oPiece==hotpot )

  {cChar.Say ("ok");}

GuyAwesome

#14
It's always the simple things you forget to check, isn't it? With me it's usually capitalisation that causes foul ups.  :P

I notice you were trying the JigsawModule - could you not get it to work properly? Because, it seems like using a module designed to do what you're after would be less work than having to adapt code that's way out of date.
Still, it should be possible to do what you want without the module. Is there nothing about completing the puzzle in the (old) code you've got? That might give you somewhere to start, at least.

EDIT:

OK, just saw the link to the post with the old code. Scorpiorus DOES provide a way to check if the puzzle is solved, so you should be able to adapt it. Updated but untested

Code: ags

  int i, correct = 1;
  while (i < Room.ObjectCount) {
    Hotspot *ho = Hotspot.GetAtScreenXY(object[i].X, object[i].Y);

    correct=correct*(ho.ID == i);
    Display("object number %d (correct=%d)", i, correct); //debug
    i++;
  }

  if (correct == 1) {
    Display("Puzzle has just been solved!");
    //NewRoom... or whatever
    // ...
  }


You could also modify the code you've got to check hotspots when you pickup/drop an object so you can't take them away from the right location. Something like (also UNTESTED)
Code: ags

int correct; // NOT in room_RepExec


// Rest in room_RepExec
  if (mouse.IsButtonDown(eMouseLeft)) {
    if (button_pressed==0) {
      button_pressed = 1;
      ob = Object.GetAtScreenXY(mouse.x, mouse.y);
      if (ob != null) {
        Hotspot *ho = Hotspot.GetAtScreenXY(ob.X, ob.Y);
        if (ho !+ null && ho.ID == ob.ID) {
          player.Say("No, that look right where it is.");
          ob = null;
        }
      }
    }
  } else {
    button_pressed=0;
    if (ob!=null) {
      Hotspot *ho = Hotspot.GetAtScreenXY(ob.X, ob.Y);
      if (ho != null && ho.ID == ob.ID) {
        player.Say("OK, that looks good.");
        correct ++;
      }
      ob.Baseline = 0;   
      ob=null;
      if (correct == Room.ObjectCount) {
        //All objects placed right, do whatever
      }
    }
  }
   
 
  if (ob != null) {
    int width  = Game.SpriteWidth[ob.Graphic];
    int height = Game.SpriteHeight[ob.Graphic];
    ob.Baseline = game.room_height;
    ob.SetPosition(mouse.x-width/2, mouse.y+height/2);
  }


Either way, you'll need to draw hotspots for each of the 8 pieces, where the bottom-left corner should be.

EDIT2: to add ho/ob != null checks.

maraki_ang3l

Well my friend your nickname is what you really are!!!

I can't describe with words how much I thank you  for helping me  :-*

GuyAwesome

No worries.
I guess that means it's working, then? Hope you didn't need to change the code much to get it running.

SMF spam blocked by CleanTalk