Target Selection

BlitzMax Forums/BlitzMax Programming/Target Selection

Cruis.In(Posted 2013) [#1]
Hey guys, I am trying to use a mouse click to switch targets.

I've setup a dummy image at the mouse x/y, I've converted the position to world coordinates using the mouse x/y, since I am checking against world object x/y

The collision works fine when I click. So if my mouse pointer (which has the dummy alphad image) is over an image of another object and I click, the collision is successful.

Now based on that I'd like to be able iterate through a list of objects and return the object ID of the object clicked and of course get its x/y... I've tried for eachin loop which does return the coordinates and I am 'locked' onto those coordinates whereever the target object moves to.

But when I click a different object even if of the same type....it doesn't change to that objects position.




Cruis.In(Posted 2013) [#2]
It seems that the collision stops working, once there is more than one enemy object. So if I isntance an enemy object, I can click him and get my target x/y to be his own. But if I instance another one and try clicking it, the collision isn't executing, I guess thats because I am saying for each ship in the list, if collide, and since my mouse pointer with my dummy image cannot be over all the images at the same time, it is not true and therefore no collision and therefore, won't get a new set of target coords.

Now to work around that..


Jesse(Posted 2013) [#3]
there is a problem here:
     'keep updating your chosen targetx/y no matter where it moves 				
	        TargetX = E.x
		TargetY = E.y


because its inside the for/next loop targetx and targety will always have the last enemy coordinates.

why don't you do it like this instead:

	For Local E:Enemy = EachIn list	
		If GetDistance (ship.x, ship.y, X, y) < 2000
			If MouseHit(1)
				If ImagesCollide2(testpic, MouseoffsetX, MouseOffsetY, 0, 0, viewfactor, viewfactor, E.Image, E.X, EY, 0 , E.angle, viewfactor, Viewfactor)
						
						target = E						 
				End If
											 
			End If
		End If


       Next


where target is of type enemy

also are you using strict or super strict?
I see an error in the imagescollide2 line.


Cruis.In(Posted 2013) [#4]
hey thanks for the reply, I am using strict, where is the error? SO i can make sure it didn't happen in my adjustment after I pasted it.

not sure how target = e gets the x/y?


Jesse(Posted 2013) [#5]
you have:
E.X, EY,

I think it should be:
E.X, E.Y

...

not sure how target = e gets the x/y?


target in this case is a type Enemy and instead of crating a variable for targetx and targety, you just create a variable to hold the address of the type enemy:
field target:Enemy


target becomes a temporary place holder for the selected enemy. obviously target in this case will hold the actual enemy targeted. you are not creating new instances, you are just using a temporary variable to hold the selected object in the list.

[edited]

also target can be used to determine if an object was selected for targeting

if target = null no target has been selected
if target <> null target has been chosen


[edit]

another, once you find the target, there is no need to go through the for/next loop. just use exit to exit the loop.


Who was John Galt?(Posted 2013) [#6]
Also, does the first call to mousehit not clear the hit event? May want to assign mousehit to a variable before checking it for each enemy. I may be barking up the wrong tree. Haven't run the code.


Cruis.In(Posted 2013) [#7]


Still only gets the first one. Won't switch either. I'm keeping at it, if I've implemented it wrong inform me :)

The issue is as I am tracking, the collision won't return 'true' unless I click the first enemy I 'generate'


Jesse(Posted 2013) [#8]
John Galt made an interesting point that I overlooked.

every mouse hit is stored in a sort of a stack. Every time you make a call to mousehit an imput is removed from the stack so since you are calling it from with in the for loop(which you don't need to do) if you hit the mouse only one time, the mouse hit will be removed from the stack on the first iteration of the loop. so after the first iteration(first mouse hit call) is as if no mouse mousehit occurred.

I made some modifications, try and see if that helps. otherwise, if you don't mind sending me the code, I can help you from there. otherwise you are pretty much on your own.
	Field target:tenemyship


	'Select Player Target
	Method SelectTarget()
	
		SetAlpha 1
		
		DrawImage(testpic, mouseoffsetx, mouseoffsety)
		
		If target
			DrawImage(testpic, target.x, target.y)
		EndIf
		
		'Translate the MouseX and MouseY to world Coordinates
		MouseOffsetx = (ship.x + MouseX()) - screen_width/2
		MouseOffsety = (ship.y + MouseY()) - screen_height/2
		
		If Not Target
			If MouseHit(1)
				For Local E:tenemyship = EachIn ShipMasterlist
				
					If GetDistance (x, y, E. X, E.y) < 2000
						If ImagesCollide2(testpic, MouseoffsetX, MouseOffsetY, 0, 0, viewfactor, viewfactor, E.Image, E.X, E.Y, 0 , E.angle, viewfactor, Viewfactor)
						
							target = E
							Exit
							
						End If
					End If
				Next
			End If
		EndIf
		
		
	End Method



Zeke(Posted 2013) [#9]
i have never liked mousehit/keyhit behavior, so i changed polledinput.bmx:

this will not reset keyhit/mousehit states until Flip.


Derron(Posted 2013) [#10]
@Zeke.
I think the default Behaviour is okay as long as there is no "ResetKey/Button"-Method available. I myself am using a Keywrapper/Mousewrapper lib to get the functions I want.

It is like saying: hey someone wants to check mouse button state: it will surely care about others wanting that information too. The stack-principle can befound in multiple parts of blitzmax so it is no surprise.
Better have a mouse/keywrapper running each "update" to store certain variables. Additional you can store things like "last click" "last click position" etc.
Better than suggesting core modifications for beginners.


bye
Ron


Cruis.In(Posted 2013) [#11]
Hey guys thanks for the help, Jesse, John, Derron, Zeke as usual. You solved it quite early on up...I had a left over piece of code from testing it which was messing up the solution. After hours of trying various stuff etc, and re-trying I hope you can forgive me that it slipped past me. Funny since it was mainly just one or two things.

Either way can work target = E or targetx targety

I somehow prefer Target = E because its way cooler :)

Also I put a check for the mouse hit and a call to the function, instead of running it in the main loop and having the mouse hit in function.

Also the mousehit thing which John rose was an issue too, remember I said it wasn't returning another collision once I had selected a target? Removing the house hit from the loop squished that.


@Zeke Thanks for that, I had an issue with flushmouse recently which I went into the blitz source code for and altered and it fixed it. But your re-code to not flush until flip is good. So think I'll borrow i'll use it if you don't mind :)



Since I am scaling everything based on the player position for a zooming in and out effect, I now have to adjust the formula for moving the dummy image with the mouse pointer when I scale. Although that's ringing bells in my head since the mouse pointer itself will not be affected by any scale. :)

Might have to adjust the target images to screen coords instead of the mouse pointer to world coords.

Thanks again


Cruis.In(Posted 2013) [#12]
here is a test of the issue.

http://speedy.sh/8JfmJ/test.zip


contains three files, test.bmx, test dummy image, and two image graphics for targets. Total 33kb.

http://speedy.sh/8JfmJ/test.zip

once you 'zoom' out or in the mouseoffset x/y is no longer = to the enemy image x/y

best to just zoom out, and create one BOT. So you can see the numbers on the screen.

Press 'P' to create a bot.

thanks :)


Jesse(Posted 2013) [#13]
you need to compensate for the scale when checking collision and placing objects on the screen.
I marked all of the changes I made hopefully you can figure it out.
I also modified the flushz part since my version( the newest version) of Blitzmax does not support flushz.




Cruis.In(Posted 2013) [#14]
that is my fault sorry...I modified the source to make a flushmousez() function.

I see you don't need it anyhow.

Ah such a mistake I should really be kicking myself, I know I have to test at rotation and scalling, and hence since my application runs on the global viewfactor (everything is scaled by it), I figured that is enough for the imagescollide2 check to satisfy its need for knowing the current scale of all images.

But because of the way its done, the objects screen coordinates are drawn different than the world coordinates using the offset, and so I need to test at their screen coord and not the world coord.

Damn probably got the whole forest/trees syndrome, been going for weeks at 4-6 hours a day lol.....

Not spotting these things.....

With your pointing out of my error, the other simple change to was

Check at the actual Offset...since that has the viewfactor included in its calculation already.

If ImagesCollide2(testpic, MouseoffsetX, MouseOffsetY, 0, 0,viewfactor, viewfactor, E.Image,..
E.OffsetX,.. '*************************************************
E.OffsetY,..


If Target
DrawImage(TestPic, Target.OffsetX, Target.OffsetY) '******************************
End If


Thanks again Jesse.


Jesse(Posted 2013) [#15]
haha! I am surprised I didn't see that. my defense is that I didn't look at it for more than 10 minutes.

I am glad you got it all together now.


Cruis.In(Posted 2013) [#16]
You don't need to defend yourself friend....certainly not from me!

Also the example was easy to follow yes?


Jesse(Posted 2013) [#17]
Yes.