Sweetgebus Posted Friday at 10:19 AM Posted Friday at 10:19 AM Hello all, in my attempt to learn scripting in Leadwerks 5, I figured I could start a thread here and update my progress. I have a small understanding of some things so far. I’ve been working on a learning project for the past week. The idea is a Flappy Bird-style game, or an old-school helicopter game if any of you are old enough to remember that game. The player, “Cube,” flies forward at a constant velocity without player input. When the player hits the space key, the cube will jump. If the player hits the ground or any object, they reset to the beginning. Learns goals for this project include Storing the distance traveled by the player. Saving the highest distance traveled as a high score. Adding power-ups, such as momentarily slowed movement, that the player can use for difficult sections. Said power-ups, when collided with, would be stored rather than immediately executed, so the player can use them when they need them. I figured this would be a good starting point for learning. I will post screenshots and code throughout the game's progress, along with the current goal I’m working on. Any help and advice would be greatly appreciated. I’ve always wanted to learn scripting, and once I found Leadwerks, I knew it would be my engine of choice. 3 Quote
Sweetgebus Posted Friday at 10:27 AM Author Posted Friday at 10:27 AM (edited) So far, I’ve achieved basic player control. The player flies forward at a constant speed. I’ve set the player's starting point via script, and the player successfully resets to that point when it makes contact with the ground or other game objects. I achieved collision detection by checking the struck entity's collision type. This works in this case, but perhaps there is a better way? Utilizing a timer, I’ve successfully added a 3-second delay after opening the game, before the player starts moving forward. This has caused an issue that I’m currently trying to overcome. Gravity still acts even when the timer is active. I thought maybe setting self:SetGravity(0) from the start and calling self:SetGravity(1) after checking if the game has started would be the key, but this has a logic error. Perhaps someone here can offer some advice? -- create start timer gracetimer = CreateTimer(3000) ListenEvent(EVENT_TIMERTICK,gracetimer,OnGraceTimer) -- Enable physics self:SetPhysicsMode(PHYSICS_RIGIDBODY) self:SetCollisionType(COLLISION_PLAYER) self:SetMass(1) -- Create camera self.camera = CreateCamera(self.world) self.camera:SetPosition(self.entity:GetPosition()) --we need to save the position of the entity so that we can reset to it startpos = self:GetPosition() end --timer callbacks function OnGraceTimer() Print("timer Worked") gracetimer:Stop() gamestarted = true end function myPlayer:Sound() hit = LoadSound("Sound/Music/hit.mp3") end -- collision function myPlayer:Collide(entity) if entity:GetCollisionType() == COLLISION_SCENE then hit = LoadSound("Sound/Music/hit.mp3") hit:Play() Print("Game Over!") isgameover = true end end --player movement function myPlayer:Update() local vel = self:GetVelocity() if gamestarted == true then vel.z = self.speed end vel.x = 0 self.entity:SetRotation(0,0,0) if self.window:KeyDown(KEY_SPACE) then vel.y = self.jumpforce end self:SetVelocity(vel) -- Game is over, so lets reset the player back to the starting position and resume after 3 seconds if isgameover == true then self:SetPosition(startpos) isgameover = false end -- Update camera self.camera:SetPosition(self.entity:GetPosition()) self.camera:Move(0,1,-3) end Edited Friday at 10:28 AM by Sweetgebus 1 Quote
Sweetgebus Posted Saturday at 02:55 PM Author Posted Saturday at 02:55 PM (edited) I'm convinced that I'm using Self:SetGravity() incorrectly. With gravity disabled in the editor, I thought that self:SetGravity(-10) would add the gravity to the player, but it doesn't. Scratch that, SetGravity doesn't seem to enable gravity, it modifies its value. Edited Saturday at 03:01 PM by Sweetgebus Quote
Sweetgebus Posted Saturday at 06:29 PM Author Posted Saturday at 06:29 PM (edited) Ok, working code bellow. I have my 3 second delayed start, with the gravity issue solved. I also implemented a max jump height to prevent the player from just going over top of the game objects. This code works, but if anyone would care to look over it and tell me if things are wrong, or if I should have done something else, I'd really appreciate it. I don't want to create bad habits from the start. myPlayer = { name = player } myPlayer.name = "myPlayer" myPlayer.speed = 10 myPlayer.jumpforce = 5 myPlayer.maxheight = 10 function myPlayer:Start() self.window = ActiveWindow() -- create start timer gracetimer = CreateTimer(3000) ListenEvent(EVENT_TIMERTICK,gracetimer,OnGraceTimer) -- Enable physics self:SetPhysicsMode(PHYSICS_RIGIDBODY) self:SetCollisionType(COLLISION_PLAYER) self:SetMass(1) self:SetGravity(0) -- Create camera self.camera = CreateCamera(self.world) self.camera:SetPosition(self.entity:GetPosition()) --we need to save the position of the entity so that we can reset to it startpos = self:GetPosition() end --timer callbacks function OnGraceTimer() Print("timer Worked") gracetimer:Stop() gamestarted = true gravity = -10 end function myPlayer:Sound() hit = LoadSound("Sound/Music/hit.mp3") end -- collision function myPlayer:Collide(entity) if entity:GetCollisionType() == COLLISION_SCENE then hit = LoadSound("Sound/Music/hit.mp3") hit:Play() Print("Game Over!") isgameover = true end end --player movement function myPlayer:Update() local pos = self:GetPosition() local vel = self:GetVelocity() if gamestarted == true then self:SetGravity(-10) vel.z = self.speed end vel.x = 0 self.entity:SetRotation(0,0,0) if pos.y > self.maxheight then pos.y = self.maxheight self:SetPosition(pos) end if self.window:KeyDown(KEY_SPACE) then vel.y = self.jumpforce end self:SetVelocity(vel) -- Game is over, so lets reset the player back to the starting position and resume after 3 seconds if isgameover == true then self:SetPosition(startpos) isgameover = false end -- Update camera self.camera:SetPosition(self.entity:GetPosition()) self.camera:Move(0,1,-3) end Edited Saturday at 06:30 PM by Sweetgebus Quote
Sweetgebus Posted yesterday at 02:27 AM Author Posted yesterday at 02:27 AM I'm attempting to set up a gui item for distance traveled. I'm not sure what I'm doing wrong here. When I run the game, it just crashed immediately without any errors. Any ideas? Quote
Sweetgebus Posted yesterday at 04:28 AM Author Posted yesterday at 04:28 AM myPlayer = { name = player } myPlayer.name = "myPlayer" myPlayer.speed = 10 myPlayer.jumpforce = 5 myPlayer.maxheight = 10 function myPlayer:Start() self.window = ActiveWindow() self.maxdist = 0 -- create start timer gracetimer = CreateTimer(3000) ListenEvent(EVENT_TIMERTICK,gracetimer,OnGraceTimer) --create gui local font = LoadFont("Fonts/arial.ttf") scoretile = CreateTile(world, font, "Score: 0", 32, TEXT_LEFT) -- Enable physics self:SetPhysicsMode(PHYSICS_RIGIDBODY) self:SetCollisionType(COLLISION_PLAYER) self:SetMass(1) self:SetGravity(0) -- Create camera self.camera = CreateCamera(self.world) self.camera:SetPosition(self.entity:GetPosition()) --we need to save the position of the entity so that we can reset to it self.startpos = self:GetPosition() end --timer callbacks function OnGraceTimer() Print("timer Worked") gracetimer:Stop() gamestarted = true gravity = -10 end --I set up sound in this funciton, I'm not entirely sure if it needs it own function or not function myPlayer:Sound() hit = LoadSound("Sound/Music/hit.mp3") end -- collision function myPlayer:Collide(entity) if entity:GetCollisionType() == COLLISION_SCENE then hit = LoadSound("Sound/Music/hit.mp3") hit:Play() Print("Game Over!") isgameover = true end end --player movement function myPlayer:Update() local pos = self:GetPosition() local vel = self:GetVelocity() --keep track of distance traveled --local dist = pos.z - self.startpos.z --if the game is started, we apply movement and gravity if gamestarted == true then self:SetGravity(-10) vel.z = self.speed end vel.x = 0 self.entity:SetRotation(0,0,0) -- Set a max jump height so that the player can't cheat if pos.y > self.maxheight then pos.y = self.maxheight self:SetPosition(pos) end --added jumping using the spacebar if self.window:KeyDown(KEY_SPACE) and gamestarted == true then vel.y = self.jumpforce end Current code, attempting to set up gui to show total distanced traveled by the player. self:SetVelocity(vel) -- Game is over, so lets reset the player back to the starting position and resume after 3 seconds if isgameover == true then self:SetPosition(self.startpos) isgameover = false end -- Update camera self.camera:SetPosition(self.entity:GetPosition()) self.camera:Move(0,1,-3) end Quote
Josh Posted yesterday at 04:31 AM Posted yesterday at 04:31 AM I would use table fields instead of global variables: -- create start timer self.gracetimer = CreateTimer(3000) ListenEvent(EVENT_TIMERTICK,self.gracetimer,OnGraceTimer) --create gui local font = LoadFont("Fonts/arial.ttf") self.scoretile = CreateTile(world, font, "Score: 0", 32, TEXT_LEFT) Other than that, what is the problem with this code? Quote Let's build cool stuff and have fun.
Sweetgebus Posted yesterday at 04:33 AM Author Posted yesterday at 04:33 AM 1 minute ago, Josh said: I would use table fields instead of global variables: -- create start timer self.gracetimer = CreateTimer(3000) ListenEvent(EVENT_TIMERTICK,self.gracetimer,OnGraceTimer) --create gui local font = LoadFont("Fonts/arial.ttf") self.scoretile = CreateTile(world, font, "Score: 0", 32, TEXT_LEFT) Other than that, what is the problem with this code? I'll read on tables, but when I run this code, the game opens and closes immediately. No errors given. Quote
Josh Posted yesterday at 04:34 AM Posted yesterday at 04:34 AM Run in debug or fast debug mode. If there is still no error, set a breakpoint to figure out where the problem is. Quote Let's build cool stuff and have fun.
Sweetgebus Posted yesterday at 04:35 AM Author Posted yesterday at 04:35 AM Just now, Josh said: Run in debug or fast debug mode. If there is still no error, set a breakpoint to figure out where the problem is. I'm use the integrated code editor, does it work in that? The code runs fine if I comment out the CreateTile() line Quote
Josh Posted yesterday at 04:35 AM Posted yesterday at 04:35 AM Just now, Sweetgebus said: I'm use the integrated code editor, does it work in that? The code runs fine if I comment out the CreateTile() line I don't understand this statement? Quote Let's build cool stuff and have fun.
Sweetgebus Posted yesterday at 04:37 AM Author Posted yesterday at 04:37 AM Sorry, I'm not using visual studio. I actually didn't know how to do breakpoints in the leadwerks script editor. Quote
Josh Posted yesterday at 04:39 AM Posted yesterday at 04:39 AM I think you will have a very difficult time without it!: https://www.leadwerks.com/learn/Debugging?lang=lua&nocpp=1 Quote Let's build cool stuff and have fun.
Sweetgebus Posted yesterday at 04:40 AM Author Posted yesterday at 04:40 AM Oh boy, that just opened up a whole new chapter of confusion for me. I don't know how to decipher what I'm looking at. Quote
Josh Posted yesterday at 04:42 AM Posted yesterday at 04:42 AM Really? What are you confused about? Quote Let's build cool stuff and have fun.
Josh Posted yesterday at 04:42 AM Posted yesterday at 04:42 AM Maybe start here. This explains from the beginning how the script editor works: https://www.leadwerks.com/learn/Programming?lang=lua Quote Let's build cool stuff and have fun.
Josh Posted yesterday at 04:45 AM Posted yesterday at 04:45 AM I must go to sleep, but I will remain with you in the videos. I think the Lua programming series will help you. Quote Let's build cool stuff and have fun.
Sweetgebus Posted 5 hours ago Author Posted 5 hours ago Only TEXT_LEFT is in view for me. Anything else doesn't show. I have self.window = ActiveWindow(), is there something else I'm missing? Quote
Sweetgebus Posted 56 minutes ago Author Posted 56 minutes ago Disregard, searching through discord I found the answer. Apparently I need to add a variable, framebuffer = self.window:GetFramebuffer(). And set the postion of the tile. Quote
Josh Posted 17 minutes ago Posted 17 minutes ago It would be better to declare it as a local variable: local framebuffer In this case, it probably won't matter, but in the future it's a good idea to declare local variables whenever possible. Quote Let's build cool stuff and have fun.
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.