Home Tutorials Download Beta Store Forum Documentation KnowledgeBase Wiki Blog

ShiVa3D

Return to Game programming

Noob 2D Movement Question?

All about the StoneScript

Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 09:26

Hello!
So i'm new to Shiva and i've been working on a 2D game. Up until this point i've managed to do most things by myself or by following tutorials.
Now this may seem like a silly question but:
How do I make my character move using WASD. I understand the Handler > OnKeyboardKeyDown and i've got the following code
Code: Select all
--------------------------------------------------------------------------------
function char_AI.onKeyboardKeyDown ( kKeyCode )
--------------------------------------------------------------------------------
   
if      ( kKeyCode == input.kKeyD ) then
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------


So what is it I put after 'then' to allow the character to move let's say 10 pixels to the right (According to a camera placed on the Z axis. So it would travel along the X axis)
Or is there another way?
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby gamescorpion » 24 Mar 2012, 10:01

Guinner wrote:Hello!
So i'm new to Shiva and i've been working on a 2D game. Up until this point i've managed to do most things by myself or by following tutorials.
Now this may seem like a silly question but:
How do I make my character move using WASD. I understand the Handler > OnKeyboardKeyDown and i've got the following code
Code: Select all
--------------------------------------------------------------------------------
function char_AI.onKeyboardKeyDown ( kKeyCode )
--------------------------------------------------------------------------------
   
if      ( kKeyCode == input.kKeyD ) then
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------


So what is it I put after 'then' to allow the character to move let's say 10 pixels to the right (According to a camera placed on the Z axis. So it would travel along the X axis)
Or is there another way?


Hello Guinner,

Ok, first in your scene you need to tag your player object. Lets assume you put a tag called "player" on your player object in the scene and save it, the following in the keydown code should do the trick:

Code: Select all
--------------------------------------------------------------------------------
function char_AI.onKeyboardKeyDown ( kKeyCode )
--------------------------------------------------------------------------------
   
if      ( kKeyCode == input.kKeyD ) then

       -- Get player object
       local hPlayer = application.getCurrentUserSceneTaggedObject ( "player" )

       -- Move player FORWARD in Z direction
       object.translate ( hPlayer, 0, 0, 1, object.kGlobalSpace )

elseif ( kKeyCode == input.kKeyA ) then

       -- Get player object
       local hPlayer = application.getCurrentUserSceneTaggedObject ( "player" )

       -- Move player LEFT in X direction
       object.translate ( hPlayer, -1, 0, 0, object.kGlobalSpace )

elseif ( kKeyCode == input.kKeyS ) then

       -- Get player object
       local hPlayer = application.getCurrentUserSceneTaggedObject ( "player" )

       -- Move player BACKWARD in Z direction
       object.translate ( hPlayer, 0, 0, -1, object.kGlobalSpace )

elseif ( kKeyCode == input.kKeyD ) then

       -- Get player object
       local hPlayer = application.getCurrentUserSceneTaggedObject ( "player" )

       -- Move player RIGHT in X direction
       object.translate ( hPlayer, 1, 0, 0, object.kGlobalSpace )

end   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------


Hope that helps, I havent tested the code, but should be pretty much correct :)

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: Noob 2D Movement Question?

Postby broozar » 24 Mar 2012, 10:04

hello guinner,

movement in shiva can be achieved in 2 ways: object.setTranslation/translateTo (movement without collision detection) and dynamics.addForce (given that the object has a dynamics controller applied). either way, you need a direction in which the character moves. as your camera is on the (+) z axis (a better choice would have been the x-axis btw, since you will get in trouble iow if you intend to use functions like object.lookAt, those are deigned to work with the -z axis), your direction vector would be (x,y,z) 1,0,0 or -1,0,0 and 0,1,0 for a jump. finally, you need to know in which spce the character's movement should be related to, either global (origin at world coordinates 0,0,0) or local (0,0,0 is wherever your model currently stands).

finally, onKeyboardKeyDown is a User event, not an object event. if you try to run this code in your char_ai, it will not work. you need to query this event in your main AI (the one you drag into the Game Editor module) and then object.sendEvent it to your character.

examples:
main_ai, the onKeyboardKeyDown handler:
Code: Select all
if kKeyCode == input.kKeyW then
    object.sendEvent (hPlayer, "char_ai", "onMoveForward", 1 ) --1 forward, 0 stand still, -1 backward
end

char ai, onMoveForward custom event:
Code: Select all
function char_ai.onMoveForward ( direction )
this.direction( direction) --this.direction() is a member variable defined in the AI Model on the left
end

char_ai, onEnterFrame:
Code: Select all
--here comes your movement code, for example:
local speedfactor = 0.5
local dt = application.getLastFrameTime ()*60 --make your movement framerate independent, aligned to 60 fps
object.translateTo(this.getObject(), this.direction()*speedfactor*dt, 0,0, object.kLocalSpace, 1) --assuming your model looks down its own x-axis

now, if you want to use dynamics (the physics engine), your model needs a dynamics controller and your level needs to be set as a collider. dynamics are frame rate independent, so no dt. i recommend dynamics.

dynamics.addForce(this.getObject(), this.direction()*speedfactor, 0,0, object.kGlobalSpace) --global space for the x-axis
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 10:20

Hey Gamescorpion I tried your idea, there were no compiling errors but the character did not move at all :/

Boozar I have tried your idea and it comes up with the following errors:
Main_AI_Handler_onKeyboardKeyDown.lua:12: undeclared variable : hPlayer
char_AI_Handler_onMoveForward.lua:11: undeclared variable : direction
Now I created direction as a variable (Number) is this the correct thing? I don't know what the hPlayer is however.
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby broozar » 24 Mar 2012, 10:45

well of course you need to declare hPlayer, but i did not know the setup of your scene, therefor i left it for you to declare.
you could either use local hPlayer = scene.getTaggedObject (application.getCurrentUserScene(), "player") if your player is tagged "player", or send an object handle to your Main_ai onInit of the object that has char_ai attached it.

for "direction", you need to write that parameter in the "()" of the function/handler:
function char_ai.onMoveForward ( direction )

gamescorpion's code does not work primarily because he is calling a user event (keyboard stuff) from within an object ai.
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 11:48

I did it! Well that was a learning experience; mainly remembering that ShiVa is case-sensitive >.<
I've done left and right movement, now how would I make it jump? So move up the y-axis?

Thank you guys, you have been brilliant and i've learnt so much! If you would be as kind as to help me on jumping i'd be very happy!
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby broozar » 24 Mar 2012, 13:24

you are welcome! jumping works along the y-axis, yes.

if you used physics, you now need http://www.stonetrip.com/developer/doc/api/dynamics-addLinearImpulse, the gravity will get your model back on the ground. just make sure addLinearImpulse is applied only once, therefor i would not use it in onEnterFrame, but a separate custom handler: onJump, that is executed when you hit your jump button.

advanced tip: if you do not want your model to be able to jump in mid-air again, you need to use a raycast to detect if there is a collider under your feet: http://www.stonetrip.com/developer/doc/api/scene-getFirstHitCollider

so your onJump would look sth like that:

Code: Select all
--------------------------------------------------------------------------------
function char_AI.onJump ( )
--------------------------------------------------------------------------------
local height = 1 --change this to a number that suits you
local x,y,z = object.getTranslation (this.getObject(), object.kGlobalSpace) --get object coordinates in global space
local hHitObject, nHitDist, nHitSurfaceID = scene.getFirstHitCollider ( application.getCurrentUserScene(), x, y, z, 0, -1, 0, height )

local upforce = 50 --change to a number that suits you
if not hHitObject then
    dynamics.addLinearImpulse ( this.getObject(), 0, upforce, 0, object.kLocalSpace )
end
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 15:29

So i've added that under char_AI and then i've put the following under UponKeyPress under main_AI
Code: Select all
else if kKeyCode == input.kKeyW then
    object.sendEvent (hPlayer, "char_AI", "onJump")

This doesn't seem to work, should I be declaring it somewhere else or in a different way?
I apologise for the noob questions, but we all have to start from somewhere huh.
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby gamescorpion » 24 Mar 2012, 16:23

lol yep broozar is correct, sorry about that, as I said I just wrote the code here, I didnt really test anything in the editor and forgot the user vs. object code which normally i would have figured out in ShiVa.

Jumping as broozar said is in the Y axis.

As for your code in the last part, have you declared the Handler onJump in your AI code??

Check to see if you have that or else it wont work.

Nav
Game Scorpion Inc. http://www.gamescorpion.com
Armies of Riddle Collectible Card Game: http://www.ArmiesOfRiddle.com
User avatar
gamescorpion
Platinum Boarder
Platinum Boarder
 
Posts: 667
Location: Ontario, Canada

Re: Noob 2D Movement Question?

Postby broozar » 24 Mar 2012, 16:28

looks good to me, scratch the "else", maybe it already works then.

if not, here's a small bugfixing tip: you can add a log.message ("log me!") in various points (1. after the sendEvent, 2. after the jump code in onJump) to see if the message is received at all. the log is displayed in the log reporter module (the black terminal-like icon).
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 16:34

I've got the following errors when I goto play:
[+ Warning ] {Scripting }AI Runtime error : dynamics.addLinearImpulse : object has no dynamics controller.
[+ Warning ] {Scripting }AI Stack Traceback :
[+ Warning ] {Scripting } [Internal] : Function 'addLinearImpulse'
[+ Warning ] {Scripting } [Line 16] : Handler 'onJump'
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby broozar » 24 Mar 2012, 16:41

well then. how could it work ;)
for this code to work, you need to apply a dynamics controller to your object.
watch http://www.youtube.com/watch?v=hKDGX8UBIdE&list=PL0393FBA47565069A

if you do not want to use dynamics, well, you'd have to come up with some nice math to do some smooth jumping yourself. try dynamics first though. how did you move the character in the fist place though, if it has no dynamics controller, only translateTo/setTranslation? how do you handle collisions with level objects then...
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Re: Noob 2D Movement Question?

Postby Guinner » 24 Mar 2012, 17:48

Gosh this is confusing! I've added the dynamics, however the jump still does not work, although there is no error messages? What could possibly be going on there?
EDIT: Never mind! It was jumping, it was just jumping at such a small distance I didn't notice!
Guinner
Junior Boarder
Junior Boarder
 
Posts: 36

Re: Noob 2D Movement Question?

Postby Rotundjere2 » 01 Apr 2012, 04:46

broozar wrote:you are welcome! jumping works along the y-axis, yes.

if you used physics, you now need http://www.stonetrip.com/developer/doc/api/dynamics-addLinearImpulse, the gravity will get your model back on the ground. just make sure addLinearImpulse is applied only once, therefor i would not use it in onEnterFrame, but a separate custom handler: onJump, that is executed when you hit your jump button.

advanced tip: if you do not want your model to be able to jump in mid-air again, you need to use a raycast to detect if there is a collider under your feet: http://www.stonetrip.com/developer/doc/api/scene-getFirstHitCollider

so your onJump would look sth like that:

Code: Select all
--------------------------------------------------------------------------------
function char_AI.onJump ( )
--------------------------------------------------------------------------------
local height = 1 --change this to a number that suits you
local x,y,z = object.getTranslation (this.getObject(), object.kGlobalSpace) --get object coordinates in global space
local hHitObject, nHitDist, nHitSurfaceID = scene.getFirstHitCollider ( application.getCurrentUserScene(), x, y, z, 0, -1, 0, height )

local upforce = 50 --change to a number that suits you
if not hHitObject then
    dynamics.addLinearImpulse ( this.getObject(), 0, upforce, 0, object.kLocalSpace )
end
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------



this code is working, but sometimes the object will fly ?
User avatar
Rotundjere2
Junior Boarder
Junior Boarder
 
Posts: 31

Re: Noob 2D Movement Question?

Postby broozar » 01 Apr 2012, 11:21

fly as in move upwards, or hover?
when do you call onJump? it works best if you either call it onKeyboardKeyUp, or if you need a snappy response, use a control variable, for example:

Code: Select all
--------------------------------------------------------------------------------
function char_AI.onKeyboardKeyDown ( )
--------------------------------------------------------------------------------

--replace hChar with your player object handle
object.setAIVariable ( hChar, "char_AI", "jumping", true )
object.sendEvent(hChar, "char_AI", "onJump")

--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------


add a member variable "jumping" (boolean) to your char, and modify the jump code:

Code: Select all
--------------------------------------------------------------------------------
function char_AI.onJump ( )
--------------------------------------------------------------------------------
local height = 0.3 --change this to a number that suits you
local x,y,z = object.getTranslation (this.getObject(), object.kGlobalSpace) --get object coordinates in global space
local hHitObject, nHitDist, nHitSurfaceID = scene.getFirstHitCollider ( application.getCurrentUserScene(), x, y, z, 0, -1, 0, height )

local upforce = 50 --change to a number that suits you
if (this.jumping() == true) and hHitObject then
    dynamics.addLinearImpulse ( this.getObject(), 0, upforce, 0, object.kLocalSpace )
    this.jumping(false)
end
   
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------
Last edited by broozar on 01 Apr 2012, 18:12, edited 1 time in total.
User avatar
broozar
Platinum Boarder
Platinum Boarder
 
Posts: 3570
Location: Berlin - Germany

Next

Return to Game programming