Making an object snap to another in bge

I am making a board game that is similar to checkers in bge, however I can’t figure out how to get the pieces to snap to the black squares when I click and drag them over to the next position. So my question is, how do I get an object to snap to the location of another object in bge?

A) drag your objects within a grid (eg. only 1.0,2.0,3.0… coordinate values allowed.) Disadvantage: you can’t freely move the objects around

B) have a (maybe invisible) drop dummy at the snap position. When the mouse is over the drop dummy and you drop: --> copy the position and orientation of the drop dummy to the dropped object.


I’m pretty sure there are much more methods

Wish I could figure out how to upload a .blend file so I could see what you mean. I guess I’m slow.

go to advanced, select manage attachements. select a blend file (see the restrictions on that file type)…

Okay so after a moment of modifying the original to be less than what I had on it, heres the blend how do I get the pieces to snap to the black squares when I click and drag in the bge

Attachments

Q.blend (958 KB)

I guess maybe I’m not being to clear. I want the game pieces to snap to the location like a drag and drop. I’ve tried orientation but I can’t figure out how to get it to work. Any help here?

Hi,

I updated your file with a drag and drop module.
I removed the logic from the “stones”. Having it on each single stone will make you go crazy if you want to change the logic later on. Beside that it is a performance hit.

The mouse is enabled by the camera, to separate this logic.

I added an helper object “selector”. It contains the drag&drop logic. You can make it invisible if you do not like it. Just remove the selector.visible = … statements.
If you want to replace the meshs, make sure to disable collsision on its faces. (Otherwise the mouse can hit the selector object, which wouldn’d result in unexpected behaviour).

You can see there is an additional plane parented to the selector. I added this because if you move the cursor fast, you might loose contact to the dragged object hitting nothing. This results in some ugly effects too. This plane remains invisible and can be increased in size if necessary.

Don’t worry that the module looks that huge. This is because it contains a few tasks.

  • select: first click on an object with property “selectable” makes it selected and parented to the selector.
  • drag: while holding the left mouse key, the selector will be moved to the mouse position. If there is an object with property “field” under the selector, the selector will snap to its position.
  • drop: when releasing the left mouse key the selected object will be dropped. This can be over an snapped object, which make the selected object be placed there. Or it can be somewhere else, which forces the selected object to bounce back to its original position.

The red cube is a test, that you can’t snap to “non”-fields.

I hope you like it.

What is left for you:
I think you need to add some logic, that deals with the situation if an field is already occupied by another one.
I suggest to keep this logic separate from any mouse over logic. Because the stones do not cover the fields completely. This leaves the option to move a stone to the uncovered part of an field.

squeeze file…squeeeeze…a bit more …Done!

Attachments

A.blend (962 KB)

Monster, you sir are my hero!

Hi there.

I don’t know anything about scripting but i needed something just like this script that you’ve made for AndreVega, Monster.
But i don’t know how to change the restriction from XZ Plane to XY Plane. The way it is now i can’t include objects afected by physics or they just fall down in the Z axys.

What do i need to change?


'''
SELECT
======
Select an "selectable" object and move it 
over an "field" object.
If dropped somewere else the object bounces back to 
its original position.
Restriction:
 Fixed to XZ-Plane
'''
__author__ = "Monster"
__version__ = "1.0"

damrs.3D

you have to change some of the coordinates from fixed y- to fixed z-axis. I haven’t tested it jet, but give it a try:

in def getFieldToSnap

 
 rayEnd = [
  mousePosition[0],
  mousePosition[1]<i> +100.0</i>, # ray along +Y
  mousePosition[2]]

change to

 
 rayEnd = [
  mousePosition[0],
  mousePosition[1] ,
  mousePosition[2] <i>- 100.0</i>] # ray along -Z

in def snapToObject


 selector.worldPosition = [fieldPosition[0],<i>0</i>,fieldPosition[<i>2</i>]]

change to


 selector.worldPosition = [fieldPosition[0],fieldPosition[<i>1</i>], <i>0</i>] # grap x,y ;z = 0 (where the stone are placed)

do a similar change to def freePosition

Be aware the stones will be placed at z=0.0. If your fields are at different hights, this will not look that good. But we could work on it.

It didn’t work.
I forgot to mention that i’m using Blender 2.49b. Maybe it was important for you to know.

It promped me an error:

In the Python window:

"Blender Game Engine Started

 File "Select.py", line 79
    selector.worldPosition = [hitPosition[0],hitposition[1] 0]
                                                                                 ^ 

SyntaxError: invalid syntax
Python module not found - controller “Select.move#CONTR#1”:
SystemError: NULL result without error in PyObject_Call

Blender Game Engine Finished"

Sorry for grammar errors, English is not my first language.

Thanks for your attention to my question.

Here’s an idea that’s worth a quick experiment.

1.Parent your player object, the default cube, to an empty at the same position.
2.Make it a slow parent relationship in Properties Panel, Animation Hacks. Give it a time offset of say… 60 ticks.
3.Add 3 or 4 cubes and drag to to various random locations within the viewport. These cubes will be targets.
4.Give each of the target cubes a Left Click and a Mouse Over sensor and a Python controller. The script detects a left mouse click on the target object and returns it’s world position. Make its world position a global variable. eg GameLogic.Target = own.worldPosition
5. Give the Empty a Left Click sensor and a Python controller. It’s script detects a left click anywhere onscreen and sends the Empty to own.worldPosition = GameLogic.Target.

The player cube will make a smooth move to the target location.

From this you can fool around and do all sorts of things.

damrs.3D

you forgot a comma after hitposition[1]

It worked, Monster! :yes: :yes: :smiley: :smiley:

One simple comma missing…
Scripting is trully complicated…

Well, i didn’t mention what i was trying to do.
The idea is to make a very, very, basic Tower Defense game, but in 3D. The Player needs to be able to drag and drop the Towers where he/she pleases (hence the need for this script) to destroy the incoming waves of enemies. The 3D aspect of the game is that the player can watch the “battles” from multiple angles or circle arround with the camera, i don´t know yet. The idea was to make something simple to play when my brain stops working when modeling some objects… :slight_smile:

And now, thanks to you, this small game might just see the light of day.

Your idea doesn’t look too bad, Equip. But i need scripts for that and i don’t now how to make them. I have tried some pretty big logic combinations and, of course, it turned the game really slow. I have already a few scripts i might use but maybe i will need some help changing them, like with this one.

Thanks, guys!