Hey guys so after about 3 weeks I decided to start making a simple infinite jumper game I have it fully working so far but I have a rocket boost that spawns every couple points. and the issue is whenever the user collects the powerup everything works as plan; disable gravity and set his Y velocity to max_booster_speed. Thing is the the player “transforms” into a rocket and flies upward for a few second before resetting but the player is twitching during that time I notice that if a set the max_booster_speed to something really low it doesnt happen. Im thinking its something to do with the physics update time and the gravity being ignored. Here is my entire player.script file if you guys could help me out.
local gravity = -20
local jump_takeoff_speed = 1100
--set gravity to zero when boosting
local max_booster_speed = 1300
local booster_points_giver
local booster_timer --10 seconds
local move_speed = 400
local current_height = 0
local allowupdate
local boosterAnimplayed
local player_dead
local currentAnimation
-- 0 player normal, 1 playerdead, 2 player boosted
local playerstate
local other_id = "null"
function init(self)
-- this tells the engine to send input to on_input() in this script
msg.post(".", "acquire_input_focus")
-- save the starting position
self.position = go.get_position()
msg.post("#", "reset")
--set the height to send to camera for implementation
current_height = go.get_position().y
-- keep track of movement vector and if there is ground contact
self.velocity = vmath.vector3(0, 0, 0)
self.ground_contact = false
playerstate = 0
booster_points_giver = 0
player_dead = false
allowupdate = true
currentAnimation = 0
boosterAnimplayed = false
booster_timer = 6
end
function final(self)
-- Add finalization code here
-- Remove this function if not needed
end
local function playanimationstate(self)
if playerstate == 0 then
if boosterAnimplayed then
boosterAnimplayed = false
end
if self.velocity.y > 0 and currentAnimation == 1 then
msg.post("#playersprt","play_animation",{ id = hash("jump")})
currentAnimation = 0
elseif self.velocity.y < 0 and currentAnimation == 0 then
msg.post("#playersprt","play_animation",{ id = hash("fall")})
currentAnimation = 1
end
elseif playerstate == 2 and boosterAnimplayed == false then
msg.post("#playersprt","play_animation",{ id = hash("booster")})
boosterAnimplayed =true
currentAnimation = 2
end
end
function update(self, dt)
if allowupdate then
--set the gravity to a vec3 variable
--increase current position if player is higher
if(current_height < go.get_position().y) then
current_height = go.get_position().y
end
self.position = go.get_position()
--if there is no contact apply gravity and if the player is not in booster state
if not self.ground_contact and playerstate ~= 2 then
self.velocity.y = self.velocity.y + gravity
end
--clamp velocity
--[[if self.velocity.y >= max_booster_speed then
self.velocity.y = max_booster_speed
end]]
--sets the player position every frame based on velocity and deltaTime
go.set_position(go.get_position() + self.velocity *dt)
--create a 3vector correction at 0,0,0
self.correction = vmath.vector3()
--ground contact initailly false
self.ground_contact = false
--if player at the left most part of the view teleport him to the right side vice versa
if self.position.x < -10 then
self.position.x = 730
go.set_position(vmath.vector3(self.position.x,self.position.y,0))
elseif self.position.x > 730 then
self.position.x = -10
go.set_position(vmath.vector3(self.position.x,self.position.y,0))
end
--send a message to the camera giving the players position
msg.post("game_camera","player_position",{position = go.get_position(), velocity = self.velocity})
--msg.post("small_cloud","player_position",{position = go.get_position(), velocity = self.velocity})
if playerstate == 2 then
self.velocity.y = max_booster_speed
booster_timer = booster_timer - 1 * dt
booster_points_giver = booster_points_giver + 1 * dt
if(booster_points_giver > 0.3) then
msg.post("game_ui","add_score",{amount = 1})
booster_points_giver = 0
end
end
if booster_timer < 0 then
particlefx.stop("#booster_flame")
playerstate = 0
currentAnimation = 0
gravity = -20
self.ground_contact = false
booster_timer = 10
booster_points_giver = 0
end
playanimationstate(self)
end
end
local function handle_geometry_contact(self, normal, distance)
-- project the correction vector onto the contact normal
-- correction vector is the 0-vector for the first contact point
local proj = vmath.dot(self.correction, normal)
-- calculate the compensation we need to make for this contact point
local comp = (distance - proj) * normal
--apply the compensation to the player character
go.set_position(go.get_position()+comp)
--check if the normal points enough up to consider the player standing on the ground
--(o.7 is roughly equal to 45 degree deviation from pure vertical direction)
if normal.y > 0.7 then
self.ground_contact = true
end
--project to velocity onto the normal
proj = vmath.dot(self.velocity, normal)
--if the projection is negative, it means that some of the velocity points towards the contact point
if proj < 0 then
--remove that component in that case
self.velocity = self.velocity - proj * normal
end
end
local function jump(self)
--only allow jump from platform
if self.ground_contact then
--set take-off speed
particlefx.play("#pfx")
self.velocity.y = jump_takeoff_speed
self.ground_contact = false
end
end
function on_message(self, message_id, message, sender)
--check if player made contact with an object
if message_id == hash("contact_point_response") then
--if velocity less than 0 allow contact with platform and jump
if self.velocity.y < 0 then
if message.group == hash("platform") then
handle_geometry_contact(self, message.normal, message.distance)
jump(self)
--give player only one point per platform
if other_id ~= message.other_id then
msg.post("game_ui","add_score",{amount = 1})
other_id = message.other_id
end
end
--ground
if message.group == hash("ground") then
handle_geometry_contact(self, message.normal, message.distance)
jump(self)
end
end
if message.group == hash("booster") then
playerstate = 2
particlefx.play("#booster_flame")
self.velocity.y = max_booster_speed
end
end
--check if player too far below camera position then call game over
if message_id == hash("camera_position") then
if go.get_position().y < message.position.y - message.offset then
player_dead = true;
msg.post("game_camera","player_dead")
msg.post("game_ui", "player_dead")
end
end
if message_id == hash("game_paused") then
allowupdate = false
elseif message_id == hash("game_resumed") then
allowupdate= true
end
end
function on_input(self, action_id, action)
if allowupdate then
if action_id == hash("MOVE_LEFT") and action.pressed then
self.velocity.x = -move_speed
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),-50))
elseif action_id == hash("MOVE_RIGHT") and action.pressed then
self.velocity.x = move_speed
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),50))
end
if action_id == hash("MOVE_LEFT") and action.released or action_id == hash("MOVE_RIGHT") and action.released then
self.velocity.x = 0;
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),0))
end
--mobile/pc
if action_id==hash("LEFT_CLICK") and action.pressed then
--left side of screen
if action.x < 360 then
self.velocity.x = -move_speed
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),-50))
elseif action.x > 360 then
--right side
self.velocity.x = move_speed
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),50))
end
elseif action_id==hash("LEFT_CLICK") and action.released then
self.velocity.x = 0;
go.set_rotation(vmath.quat_axis_angle(vmath.vector3(0,0,1),0))
end
end
end
function on_reload(self)
-- Add reload-handling code here
-- Remove this function if not needed
end