Various objects cargo trolleys
BlitzMax Forums/BlitzMax Programming/Various objects cargo trolleys
| ||
![]() ![]() I have a problem, when on stage, I have a single freight truck that pulls the tractor, everything works fine, it hooks from either of its two hooks without problem. If I put two cars, it does not work, any suggestions? |
| ||
I found something. Please don't wonder, I reformatted your code so i can see it better "in total".' - Enganchar / Desenganchar. Method Enganchar() For local cargos:TCargo = EachIn cargos.lista If xEntityDistance (cargos.ganchos[0], gancho ) <= 3.0 gancho1 = True If unionGancho:Int = 0 xShowEntity ( gancho ) Else xHideEntity ( gancho ) End If engancha = True ElseIf xEntityDistance (cargos.ganchos[1], gancho ) <= 3.0 gancho2 = True If unionGancho = 0 xShowEntity ( gancho ) Else xHideEntity ( gancho ) End If engancha = True Else gancho1 = False gancho2 = False xHideEntity ( gancho ) engancha = False End If Next If xKeyHit(xKEY_T) JointBisagra() End If End Method There is this variable "engancha". It is set to "true" if distance between two entities is smaller than 3.0 It is set to "false" if that is not the case. Now to the problem: you set it "false" in EVERY case if a "gancho" is not unioned. Example: cargos 1 of the list has "cargos.ganchos[1]" in distance < 3.0, it sets "engancha" to "true". now you go on to the next cargos: cargos 2 of the list has no "ganchos"-distance < 3.0, sets "engancha" to "false". So as soon as one cargos after a "connecting one" is not connecting, "engancha" will be set to "false". What you might want, is that "engancha" stays "true" if at least one of the catgos is connecting. Also: you doubled code which is not necessary. So what did I do in the following code? I disabled the ganchos before the loop - and if one of the ganchos is connecting, I enable it. ' - Enganchar / Desenganchar. Method Enganchar() 'set to false in all cases engancha = False gancho1 = False gancho2 = False For local cargo:TCargo = EachIn cargos.lista If xEntityDistance (cargo.ganchos[0], gancho ) <= 3.0 gancho1 = True engancha = True ElseIf xEntityDistance (cargo.ganchos[1], gancho ) <= 3.0 gancho2 = True engancha = True End If Next 'display the gancho if gancho1 or gancho2 got enabled If unionGancho = 0 and (gancho1 or gancho2) xShowEntity ( gancho ) else xHideEntity ( gancho ) End If If xKeyHit(xKEY_T:Int) JointBisagra() End If End Method But this _still_ has a flaw: this allows multiple cargos to connect to the same "gancho". So the following does a "first checked, first served" approach. An alternative would be to find the "closest" one (with lowest distance) and use that as the connecting one. Also: you do not store the information _which_ cargo is connecting. But this is needed, so I appended a param "cargo" to the second method (the one doing the joint) ' - Enganchar / Desenganchar. Method Enganchar() 'set to false in all cases engancha = False gancho1 = False gancho2 = False local connectingCargo:TCargo = null For local cargo:TCargo = EachIn cargos.lista If xEntityDistance (cargo.ganchos[0], gancho ) <= 3.0 gancho1 = True engancha = True connectingCargo = cargo 'exit for loop, we found our gancho to use exit ElseIf xEntityDistance (cargo.ganchos[1], gancho ) <= 3.0 gancho2 = True engancha = True connectingCargo = cargo 'exit for loop, we found our gancho to use exit End If Next 'display the gancho if gancho1 or gancho2 got enabled If unionGancho = 0 and (gancho1 or gancho2) xShowEntity ( gancho ) else xHideEntity ( gancho ) End If If xKeyHit(xKEY_T) JointBisagra( connectingCargo ) End If End Method Ok, now to the method doing the "connecting": This time you do not allow multiple cargos to connect to the same gancho. As you disconnect a previously connected one if it "unionGancho" is "false". But there is still a flaw: you loop over all of them and connect-disconnect-connect ... because "gancho1" or "gancho2" are true ... and they keep being "true" in the whole loop. And there is this BIG logical bug: you connect to the first cargo you find - even if this is NOT the one within <3.0 distance. You just do not store that information! As we now added the cargo to join, we do not need to loop over all cargos in the list. Here is your code reformatted (with still the flaw being in): ' - Unión Bisagra. Method JointBisagra() Local cargos:TCargo = Null For cargos:TCargo = EachIn cargos.lista If unionGancho = False If gancho1 = True unionGancho = xCreateD6SpringJoint(chassis.malla, cargos.chassis.malla, 0, 4, -19.5, 0, 0.5, -21, 0, 0) ElseIf gancho2 = True unionGancho = xCreateD6SpringJoint(chassis.malla, cargos.chassis.malla, 0, 4, -19.5, 0, 0.5, 21, 0, 0) End If Else xFreeJoint( unionGancho ) unionGancho = 0 End If Next End Method Now we do the following: - check if there is a cargo who unions, if not, remove the union - create a union for the first cargo on gancho1 or gancho2 To enable "both unions" simultaneously, "unionGancho1" and "unionGancho2" need to get introduced instead of "unionGancho" ' - Unión Bisagra. Method JointBisagra( cargo:TCargo = null ) 'having no gancho used? 'no cargos to join means "remove current join" ? '-> remove the joint if not cargo or not(gancho1 or gancho2) if unionGancho xFreeJoint( unionGancho ) unionGancho = 0 endif 'no need to do the join-code as we do not want to join something return endif 'connect to the given cargo If gancho1 = True unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, -21, 0, 0) ElseIf gancho2 = True unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, 21, 0, 0) End If End Method _I_ would do it a bit different. To make "JointBisagra" something you could call to freely join/disconnect a cargo, that function should check too, which "gancho" to use. This then would make a "field gancho1:int = false" (and gancho2 too) obsolete/unneeded. Also "engancha" should not be set by the first method but should be updated in "JointBisagra" as this is defining whether it is joined or not. So here is my complete suggestion: ' - Enganchar / Desenganchar. Method Enganchar() '=== find a cargo to connect === local connectingCargo:TCargo = null 'store the used gancho here, so "xEntityDistance()" is not called 'again in JointBisagra() local useGancho:int = 0 For local cargo:TCargo = EachIn cargos.lista If xEntityDistance (cargo.ganchos[0], gancho ) <= 3.0 connectingCargo = cargo useGancho = 1 'exit for loop, we found our gancho to use exit ElseIf xEntityDistance (cargo.ganchos[1], gancho ) <= 3.0 connectingCargo = cargo useGancho = 2 'exit for loop, we found our gancho to use exit End If Next 'connect/disconnect If xKeyHit(xKEY_T) JointBisagra( connectingCargo, useGancho ) End If 'display the gancho? If unionGancho = 0 xShowEntity ( gancho ) else xHideEntity ( gancho ) End If End Method ' - Unión Bisagra. Method JointBisagra( cargo:TCargo = null, useGancho:int=0 ) 'having no gancho used? 'no cargos to join means "remove current join" ? '-> remove the joint if not cargo if unionGancho xFreeJoint( unionGancho ) unionGancho = 0 endif engancha = False 'no need to do the join-code as we do not want to join something return endif 'find gancho to use - if not already defined as param if useGancho = 0 if xEntityDistance (cargo.ganchos[0], gancho ) <= 3.0 useGancho = 1 elseif xEntityDistance (cargo.ganchos[1], gancho ) <= 3.0 useGancho = 2 else 'here you could define a default - so you could force a connection 'useGancho = 1 ?? endif endif 'connect to the given cargo using the given gancho 'also mark "engancha" to be connected Select useGancho case 1 unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, -21, 0, 0) engancha = True case 2 unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, 21, 0, 0) engancha = True default 'you could add a default union spot if no gancho was found End Select End Method Code might contain errors, as I just wrote it without syntax check. bye Ron |
| ||
Regardless of above, I am not really satisfied with the code at all. - you check for a pressed key within a method, better do this within your main loop (splitting "logic" and "input" apart) 'somewere in your update-loop: 'connect/disconnect If xKeyHit(xKEY_T) if yourCar.connectedCargo yourCar.DisconnectCargo() else 'THIS could be done also without "xKeyHit" 'so it automatically connects if someone is in range '- only do this "if yourCar.connectedCargo = null" local cargoInRange:TCargo = yourCar.FindCargoInRange( 3.0 ) if cargoInRange yourCar.ConnectCargo( cargoInRange ) endif endif End If 'In your type 'REMOVE "Field engancha:int" 'REMOVE method "Enganchar()" 'ADD: Field connectedCargo:TCargo = null Method FindCargoInRange:TCargo( range:Float = 3.0 ) For local cargo:TCargo = EachIn cargos.lista local cargoGancho:int = FindNextCargoGancho( cargo, range ) For local cargoGancho:int = EachIn cargo.ganchos if xEntityDistance (cargoGancho, gancho ) <= range return cargo endif Next Next return null End Method Method FindGanchoInRange:int( range:Float = 3.0 ) For local cargo:TCargo = EachIn cargos.lista local cargoGancho:int = FindNextCargoGancho( cargo, range ) 'found a useful gancho if cargoGancho<>0 then return cargoGancho Next return 0 End Method Method FindNextCargoGancho:int( cargo:TCargo, range:Float = 3.0 ) if not cargo then return 0 For local cargoGancho:int = EachIn cargo.ganchos if xEntityDistance (cargoGancho, gancho ) <= range return gancho endif Next return 0 End Method Method DisconnectCargo() ConnectCargo( null, 0) End Method Method ConnectCargo( cargo:TCargo = null, useGancho:int=0 ) 'having no gancho used? 'no cargos to join means "remove current join" ? '-> remove the joint if not cargo if unionGancho xFreeJoint( unionGancho ) unionGancho = 0 endif connectedCargo = null endif if cargo 'find gancho to use - if not already defined as param if useGancho = 0 if xEntityDistance (cargo.ganchos[0], gancho ) <= 3.0 useGancho = 1 elseif xEntityDistance (cargo.ganchos[1], gancho ) <= 3.0 useGancho = 2 else 'here you could define a default - so you could force a connection 'useGancho = 1 ?? endif endif 'connect to the given cargo using the given gancho 'also mark "engancha" to be connected Select useGancho case 1 unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, -21, 0, 0) connectedCargo = cargo case 2 unionGancho = xCreateD6SpringJoint(chassis.malla, cargo.chassis.malla, 0, 4, -19.5, 0, 0.5, 21, 0, 0) connectedCargo = cargo default 'you could add a default union spot if no gancho was found End Select endif 'display the gancho? If connectedCargo xShowEntity ( gancho ) else xHideEntity ( gancho ) End If End Method - put that xKeyHit within your update loop - remove the Field and the method I wrote in the comment - if you have somewhere checks for "engacha", replace them with "if connectedCargo" What benefit do you get from this approach: - you can freely call "mycar.DisconnectCargo()" to ... disconnect the cargo ;-) - you can freely call "mycar.ConnectCargo( cargo, ganchoToUse )" even when not in range - you can call "mycar.FindCargoInRange(123.0)" which returns the first cargo within range (here as example "123.0") - you can call "mycar.FindGanchoInRange(123.0)" which returns the first gancho (of all cargos) in range - you can call "mycar.FindNextCargoGancho(cargo, range)" to return the nearest gancho of a cargo within range For now you might not need all of these functions but they add a bit of convenience. So it is easier to retrieve which cargo is the nearest, which gancho is the nearest ... bye Ron |
| ||
Hi Derron. I'm progressing. If it was a few years ago, I would think that I would create the algorithm for each freight wagon, however, doing it once and running 100 wagons or whatever number is very rewarding. In this case I have already managed to show the hitch indicator regardless of the wagon to which the tractor hook and the hook of the wagon approaches. I continue to hook and unhook. |
| ||
My suggested code already should handle hooking unhooking. This is why the code is longer than yours...it added flexibility. Please at least have a look at it...as your coxe contained logical flaws and my code shows ways to circumvent that. Bye Ron |
| ||
The advances are thanks to your code, I am moving to the phase to correctly implement the hitch. And unhooking :) |
| ||
Okay, Derron, this is already perfect. I'm uploading a video to youtube. But this is a nightmare, some video implements of 60 megs hard to climb two and a half hours. :( The fact is that I can create a lot of wagons and when approaching the tractor can hook them by any of its two points of engagement. :) |
| ||
You do not need to upload every new piece of functionality as a youtube video...save your bandwidth. With my functions you could also auto-hook a cargo as soon as you do not have a connectedCargo in that moment and are having a CargoGancho in Range.so it becomes like "snapping". ou could even do a little game out of it... Cargo with different colors need to get driven to places with colored grounds. Soundsike a little fun arcade game. If interested we could think about additional twists to the gameplay. Bye Ron |
| ||
Ok, Vědeo finish uploading. I'm really interested in making a game, I think I've learned enough but not everything. What worries me is that I do not know anything about shaders. And this is necessary for advanced effects like mapping protrusions and things like that. What turns could this game have ?, good ideas would help me a lot. :) Gretins. |
| ||
- sort cargos (either colorized cargos, or cargo of different designs - with barrels, with suitcases/bags, ...) - cargo-bowling (see showcase-thread) You might mix your fork-lift-game-idea in - multiple cars in one game (forklift, cargo-lifter ...) For all cars: - have narrow paths on which you need to drive, so it is like "do not hit the walls" games. These paths/ways of course need to get more and more difficult (curves, bridges, obstacles...). And time is running out ;-) But: As a first step we should "brainstorm" about whether it would be better to use just one of the ideas - and then improve it (or split it into multiple "variants"). Then use these ideas to do a first "game mode" (but already prepare your code to allow for more levels). Then at a later stage you could code the next "game mode" - and once this is working, you could bring in the new code to the other game (with the first "game mode"). bye ron |