Jump to content

Recommended Posts

Posted
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.
  • Like 3
Posted (edited)

image.thumb.png.4c74ca79c5c058ddf5e211fb94f693ed.png

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 by Sweetgebus
  • Upvote 1
Posted (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 by Sweetgebus
Posted (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 by Sweetgebus
Posted
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

 

Posted

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?

Let's build cool stuff and have fun. :)

Posted
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.

Posted
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

 

Posted
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?

Let's build cool stuff and have fun. :)

Posted

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. image.thumb.png.ec504152922cd17ec6f1b730d0f2c373.png

Posted

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.

Let's build cool stuff and have fun. :)

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...