WazMeister Posted July 18, 2023 Share Posted July 18, 2023 Hi All, I'm still trying and still failing to get a nice Top Down Shooter PlayerCharacter with mouse aiming. So I've managed to get Top Down view, some nice animations and movements with help of @Alienhead. My current situation is mouse pointer is locked to center of screen and clamped, I've messed around with code for countless hours and can not seem to get the mouse unlocked without the angle of player spinning at 10000mph! What I would like to understand and achieve, is having mouse unlocked so it moves freely around the screen (possibly clamping it again at a later date but not so restrictive to center of screen), maintain character direction facing where mouse is and finally having mouse cursor be a cross hair. Please can someone help me, racking my brains and ripping out (the little I have left) of my hair, I've also hit my head with my fresh new Lua Programming by Roberto Ierusalimschy book!. I just need bit of guidance in a real beginner / understandable way. Thanks in advanced for any assistance you can provide. A video of what I'm currently left with... to help local runmultiplier = 0.8 --Set Script properties in Editor / define variables Script.lookSpeed = 0.2--float "Look Speed" Script.lookSmoothing = 5--float "Look Smoothing" Script.cameraDistance = 6--float "Camera Distance" Script.cameraRadius = 0 Script.jumpStrength = 8--float "Jump Strength" Script.walkSpeed = 2.5--float "Walk Speed" Script.runSpeed = 5--float "Run Speed" Script.cameraPitch = 35--float "Camera Pitch" Script.lockCameraAngle = false--bool "Lock Camera" Script.cameraCollision = true--bool "Camera Collision" --==================================================================================================== function Script:Start() --Set the type to player, keyvalue is string value associated with a key name self.entity:SetKeyValue("type", "player") --Create variable for player Mass self.mass = 10 --check and set the mass of player for physics. if self.entity:GetMass() == 0 then self.entity:SetMass(10) end --Set player physics mode - as a Character Controller Physics. self.entity:SetPhysicsMode(Entity.CharacterPhysics) -- Create a Camera to see the game! self.camera = Camera:Create() --Listener for spatial sound (location of sound) self.listener = Listener:Create(self.entity) --Get the player angle (rotation) of y axis and store in variable angle self.angle = self.entity:GetRotation().y --Set camereaAngle varible to players current y axis/angle + character controller angle. self.cameraAngle = self.angle + self.entity:GetCharacterControllerAngle() --Set Field Of View (FOV) for camera. Default is 90 self.camera:SetFOV(80) camera = self.camera --Create Table named 'player' and set it's fields / data player = {} player.ent = self.entity player.state = 1 player.animationMode = "" player.holdAngle = self.angle player.timer_afk = Time:Millisecs() + 30000 player.timer_jump = 0 player.afk = true player.doublejump = 0 player.stamina = 100 player.staminaTotal = 100 player.health = 100 player.healthTotal = 100 self.timer_rolled = 0 self.timer_duringRoll = 0 self.timer_rollLeft = 0 self.timer_rollRight = 0 self.timer_rollForward = 0 self.timer_rollBackward = 0 self.tick_firingRock = 0 self.timer_tick = 0 self.hKeyHit_firing = false self.timer_playerFired = 0 self.releasePower = 0 self.sndBreathPlaying = false --Player states (Setup in a lua table with fields) state = {} --Table called state --Add fields to table state.idle = 0 state.walk = 1 state.run = 2 state.carry = 3 state.dead = 4 -- Timer Variable for animations (see States further below) player.timer_dontChangeAnim = 0 -- Create pivot point for player player.infrontMarker = Pivot:Create() end --==================================================================================================== function Script:UpdateWorld() local playerPos = self.entity:GetPosition(true) local aabb = self.entity:GetAABB(Entity.GlobalAABB) playerPos.y = aabb.center.y self.camera:SetPosition(playerPos) context:DrawText("AABB: "..aabb:ToString(), 20, 20) context:DrawText("Camrea Pitch: "..self.cameraPitch, 40, 40) --Returns a value interpolated between a current and target angle for smooth movement. <Target (being moved towards in degrees, current value in degrees, the number to divide the diffrence by> self.cameraAngle = Math:CurveAngle(self.angle + self.entity:GetCharacterControllerAngle(), self.cameraAngle, self.lookSmoothing / Time:GetSpeed()) --Set Camera intitial position (rotation and turn) if self.lockCameraAngle == false then self.camera:SetRotation(0, self.cameraAngle+180, 0) self.camera:Turn(90, 0, 0) else --If camera locked, set it to just camerapitch. self.camera:SetRotation(self.cameraPitch, 0, 0) end --Transform geomtry from one space to another. (x, y, z, entity source, entity destination) local cameraPos = Transform:Point(0, 0, -self.cameraDistance, self.camera, nil) --Set pick mode for camera collide local pickMode = self.entity:GetPickMode() self.entity:SetPickMode(0) if self.camereaCollision then local pickInfo = PickInfo() --[[A world pick, perform pick on all entities in a world that intersect, the specified line. Pick(origin of ray, end of ray, pick info container, radius, closet, col type)]]-- if self.entity.world:Pick(playerPos, CameraPos, pickInfo, self.cameraRadius) then self.camera:SetPosition(pickInfo.position, true) else self.camera:SetPosition(cameraPos, true) end else self.camera:SetPosition(cameraPos, true) end self.camera:Move(0, 2, 0) -- Height adjust self.entity:SetPickMode(pickMode) end --==================================================================================================== function Script:UpdatePhysics() --use current window and context render surface local window = Window:GetCurrent() local context = Context:GetCurrent() -- Setup / start local time = Time:Millisecs() --Time class for keeping track of application time. Millisecs returns system time in milliseconds local animationState = "" --Move the player pivot (front marker) to current entity (player) position in local space (not global) player.infrontMarker:SetPosition(self.entity:GetPosition(true)) --Set position of pivot to player each frame/update local rot = self.camera:GetRotation(true) player.infrontMarker:SetRotation(0, rot.y, 0) -- set pivot angle/rotation to cameras current y angle (yaw). player.infrontMarker:Move(0, 0, 2) -- Move pivot on Z axis -- Define variables --Get the enter position of screen / surface (context) and hold it in varibles cx and cy local cx = context:GetWidth()/2 local cy = context:GetHeight()/2 -- Camera Angle --If camera is not locked then set mouse to center and clamp it if self.lockCameraAngle == false then local mousePos = window:GetMousePosition() window:SetMousePosition(cx, cy) local mx = Math:Clamp(mousePos.x - cx, -90, 90) local my = Math:Clamp(mousePos.y - cy, -45, 45) - .5 --Setup rotate (angle) to mouse movement for player. if self.smoothedMouseMovement ~= nil then self.angle = self.angle + mx * self.lookSpeed --angle of entity + mouse X & a speed. enty faces mouse movement on X else self.smoothedMouseMovement = Vec2(0) end --Returns a value interpolated between a current and target value. <Target (the value being moved towards, current (the current value), division (number to divide diffrent by) self.smoothedMouseMovement.x = Math:Curve(mx, self.smoothedMouseMovement.x, self.lookSmoothing) self.smoothedMouseMovement.y = Math:Curve(my, self.smoothedMouseMovement.y, self.lookSmoothing) --up and down adjust of mouse movement (turning X) and limit it if self.cameraPitch < -5 then self.cameraPitch = -5 end if self.cameraPitch > 65 then self.cameraPitch = 65 end --[[Apply mouse movement (up & down) via smooth movement.y, based on cameraPitch set to camrea turn]] self.cameraPitch = self.cameraPitch + (self.smoothedMouseMovement.y) * .1 --player.cameraPitch = self.cameraPitch --self.entity:SetInput(self.angle, 0, 0, 0) end window:ShowMouse() --Set key button varibles local move = 0 local strafe = 0 local keyHit_forward = false local keyHit_backward = false local keyHit_left = false local keyHit_right = false --Player Movement Variables keyHit_forward = window:KeyDown(Key.W) keyHit_backward = window:KeyDown(Key.S) keyHit_left = window:KeyDown(Key.A) keyHit_right = window:KeyDown(Key.D) --Reset player to IDLE STATE if move == 0 or strafe == 0 then player.state = 1 end --Key Actions --::rescanactions:: if keyHit_forward and keyHit_backward then player.state = 1 else if keyHit_forward then move = -self.walkSpeed player.state = 2 elseif keyHit_backward then move = self.walkSpeed player.state = 3 end end if keyHit_right and keyHit_left then player.state = 1 else if keyHit_left then strafe = self.walkSpeed player.state = 4 elseif keyHit_right then strafe = -self.walkSpeed player.state = 5 end end --============================================================================================================= --Player States --============================================================================================================= --IDLE STATE (1) if player.state == 1 then if player.timer_dontChangeAnim < time then --time_dontChangeAnim is intitalise to 0 so will always be less than time...? --Determine which idle animation to play --if player.stamina < 60 then --animationState = "Exhausted" --else animationState = "Idle" --end if player.animationState ~= animationState then --If the player.animationState does not hold or match a animation, then set the player.animationState field to current animation (held in variable) player.animationState = animationState player.ent:PlayAnimation(player.animationState, .03, 250, 0)--Play the animation. player.ent table/field basically replaces self.entity. end end self.entity:SetInput(player.holdAngle, 0, 0, 0) end --------------------------------------------------------------------- --WALK STATE (2) if player.state == 2 then if player.timer_dontChangeAnim < time then animationState = "Walk" if player.animationState ~= animationState then player.animationState = animationState player.ent:PlayAnimation(player.animationState, .06, 250, 0) --add sound end end self.entity:SetInput(self.angle, move, strafe, 0) player.holdAngle = self.angle end --------------------------------------------------------------------- --WALKBACKWARDS STATE (3) if player.state == 3 then if player.timer_dontChangeAnim < time then animationState = "Walkbackwards" if player.animationState ~= animationState then player.animationState = animationState player.ent:PlayAnimation(player.animationState, .05, 250, 0) end end self.entity:SetInput(self.angle, move, strafe, 0) player.holdAngle = self.angle end --------------------------------------------------------------------- --STRAFE LEFT STATE (4) if player.state == 4 then if player.timer_dontChangeAnim < time then animationState = "StrafeLeft" if player.animationState ~= animationState then player.animationState = animationState player.ent:PlayAnimation(player.animationState, .04, 250, 0) --add sound end end self.entity:SetInput(self.angle, move, strafe, 0) player.holdAngle = self.angle end --------------------------------------------------------------------- --STRAFE RIGHT STATE (5) if player.state == 5 then if player.timer_dontChangeAnim < time then animationState = "StrafeRight" if player.animationState ~= animationState then player.animationState = animationState player.ent:PlayAnimation(player.animationState, .04, 250, 0) --add sound end end self.entity:SetInput(self.angle, move, strafe, 0) player.holdAngle = self.angle end --------------------------------------------------------------------- --STRAFE RIGHT STATE (5) if player.state == 6 then if player.timer_dontChangeAnim < time then animationState = "StrafeRight" if player.animationState ~= animationState then player.animationState = animationState player.ent:PlayAnimation(player.animationState, .04, 150, 0) --add sound end end self.entity:SetInput(self.angle, move, strafe, 0) player.holdAngle = self.angle end --------------------------------------------------------------------- end Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
Alienhead Posted July 18, 2023 Share Posted July 18, 2023 I'm not 100% sure what your trying to do there.. Traditionally there is no looked-mouse support for town down game. Are you trying to install point and click-walk ability? That would be pretty easy to without a controller just using LE's homebrew pathfinding class.. which by the way works pretty damn awesomally I might add. Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
WazMeister Posted July 19, 2023 Author Share Posted July 19, 2023 Hi Alien, I would like to get similair player control as these examples. Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
WazMeister Posted July 19, 2023 Author Share Posted July 19, 2023 Did them videos make it any clearer? Anyone able to assist me in the right direction? Just need a little helping hand to guide me through this dark tunnel. Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
Thirsty Panther Posted July 20, 2023 Share Posted July 20, 2023 I haven't made a game like this but this is how I would go about it. Split your main character into 2 parts. Part 1 is the legs which will be controlled by the WASD keys. the animation for them determined by which way the player wants to go. Keep the "legs" in the center of the screen and move the map in the opposite direction to which the player wants to move. Part 2 will be the torso, weapon and head of the character. Parent this part to the legs. Animation of this part is determined by the position of the mouse pointer. With the mouse pointer you will need to hide the default pointer and replace it with a suitable crosshair. In this post Macklebee describes the process. You will need to constrain the "mouse" so that it does not leave the screen. Hope this helps and good luck. 1 Quote Link to comment Share on other sites More sharing options...
WazMeister Posted July 20, 2023 Author Share Posted July 20, 2023 Thanks, that really insightful and helpful. Not sure the proposal is the solution I need. It must be something Leadwerks can acheive, its basically top down view, rotation/math curve for model towards mouse location and then mouse icon being a cross hair that use used to aim and shoot etc.... Just not sure how to piece it all together in Lua. Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
Alienhead Posted July 20, 2023 Share Posted July 20, 2023 You'll need an unlocked mouse pointer.. preform a simple Pick to get the location the mouse is at and rotate the player to that position. leadwerks is a full blown game engine, it can do most likely anything you wish for it to do but you'll need to know the commands and their outcome in order to select the appropriate method. https://www.leadwerks.com/learn?page=API-Reference_Object_Entity_Camera_Pick pickinfo.position will contain the location you want, you could then place a pivot or whatever there then Point() the player towards it ( on Y axis only ) . Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Alienhead Posted July 21, 2023 Share Posted July 21, 2023 I'm actually working on a 5-day game jam right now which does close to what your wanting to do.. if you haven't figured it out in a day or two then I should have some code finished that you could try out. Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Alienhead Posted July 21, 2023 Share Posted July 21, 2023 Okay I went ahead and did that part of my code. Is this kinda what your looking to do ? -- do a pick local pickinfo = PickInfo() local pickradius = .1 local p = window:GetMousePosition() if (cam:Pick(p.x,p.y,pickinfo,pickradius,true)) then enginepiv:SetPosition(pickinfo.position) self.player:Point(enginepiv) self.player:SetRotation(0, self.player:GetRotation().y-180, 0) end if your using a physics controller on your player you'll need to set the self.angle to Y rotation ( SetInput() ) and not use the Point() method as shown above. I have no physics on the ant so I used the Point() method but in theory it's the same practice. 1 1 1 Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Paul Thomas Posted July 21, 2023 Share Posted July 21, 2023 You are setting the mouse position to center with this line: window:SetMousePosition(cx, cy) If you have game logic that needs to stop the mouse from being forced to center, then you need to encapsulate this line with that logic. Quote Link to comment Share on other sites More sharing options...
WazMeister Posted July 21, 2023 Author Share Posted July 21, 2023 5 hours ago, Alienhead said: Okay I went ahead and did that part of my code. Is this kinda what your looking to do ? -- do a pick local pickinfo = PickInfo() local pickradius = .1 local p = window:GetMousePosition() if (cam:Pick(p.x,p.y,pickinfo,pickradius,true)) then enginepiv:SetPosition(pickinfo.position) self.player:Point(enginepiv) self.player:SetRotation(0, self.player:GetRotation().y-180, 0) end if your using a physics controller on your player you'll need to set the self.angle to Y rotation ( SetInput() ) and not use the Point() method as shown above. I have no physics on the ant so I used the Point() method but in theory it's the same practice. I'll have to finish work to look at this in detaill.. but wow! That is amazing, not just the response but the time and effort shown to help me. Really geninue and touching, you're amazing Ronnie - Reminds me all humans are not bad! It's not exactly what I am after, I want as you shown, but player does not follow where mouse is, just the angle and when shooting with mouse it shoots at location (hence the mouse cursor I will eventually turn to a 2D crosshair as if its looking down from above as well.. Top Down Shooter). I should be able to review the above and amend it so the W,A,S,D keys move player around and not follow the mouse pointer.. but mouse hopefully to be free as you've shown and player angle look at it. 1 Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
WazMeister Posted July 21, 2023 Author Share Posted July 21, 2023 10 hours ago, Alienhead said: Okay I went ahead and did that part of my code. Is this kinda what your looking to do ? -- do a pick local pickinfo = PickInfo() local pickradius = .1 local p = window:GetMousePosition() if (cam:Pick(p.x,p.y,pickinfo,pickradius,true)) then enginepiv:SetPosition(pickinfo.position) self.player:Point(enginepiv) self.player:SetRotation(0, self.player:GetRotation().y-180, 0) end if your using a physics controller on your player you'll need to set the self.angle to Y rotation ( SetInput() ) and not use the Point() method as shown above. I have no physics on the ant so I used the Point() method but in theory it's the same practice. Sorry Ron, I've had a look but even more confused. Not sure what Point() you reference to in my code? Am I to use/edit the code you detailed or just set self.angle of player to my camera rotation in setinput? Many Thanks again Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
Alienhead Posted July 21, 2023 Share Posted July 21, 2023 I'm out of town for a few days and I don't install Steam on my work laptop so won't be able to do anything until I get back, but I'll be glad to help ya on my return. 1 1 Quote I'm only happy when I'm coding, I'm only coding when I'm happy. Link to comment Share on other sites More sharing options...
Yue Posted July 21, 2023 Share Posted July 21, 2023 It's amazing that when I see things like this, I am reminded that the Leadwerks engine is very complete and that I am the bad programmer. I'm still learning. Quote Link to comment Share on other sites More sharing options...
WazMeister Posted July 21, 2023 Author Share Posted July 21, 2023 100% agree, but also noticed you reminisce a lot. Quote Dream since child of making games! From Game Programming Starter Kit 3.0, Blitz Basic, Map Creation since Duke 3D, Game Maker, Blitz3D (of recent..2023) and many other engines and years..... never really sticking to it with inner struggles that I've had to fight along with pushing to learn and acheive. 40 years old.. came across Leadwerks on Steam... Learning slowly but surely and loving it! Learn with me or just watch me fail! at my random Youtube Channel, as I stream adhoc while learning and using LeadWerks and other game creating tools. https://www.youtube.com/@wazmeister3151/featured Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.