Mobile Adventure RPG (Open Sourced)

Hello (again). I was active here for a while and then took a break. I still find learning how to program games using Lua and Defold to be both exciting and challenging, so I’m taking some ideas I have into a game. The idea is to make a game like the original Zelda with a compelling story and fun gameplay.

8 Likes

Because the Legend of Zelda is a classic, there are a lot of resources available online.

Such as:

Another very useful case study of Zelda. Referencing this often when building this game.

Definitely looking forward to learning from these and implementing the mechanics in Defold.

7 Likes

Got the directions working and now I’m working on the animations. I also got a deflect system to work. I found another article that breaks down the mechanics of Zelda and that’s been helpful for setting up my game.

I’m making the sprites myself. They’ll be 16x16. I’m thinking of having different sprites for in/out of town.

3 Likes

There’s probably many ways to solve the direction issue.

I’d have a variable (e.g. self.animation_direction) that I would only update in input. For example:

if action_id == hash("w") then
		self.input.y = 1
		self.input.x = 0
		if action.pressed then
			self.animation_direction = hash("north")
			sprite.play_flipbook("#sprite", hash("player_walking_north"))
		elseif action.released then
		end
	end

Set it accordingly for each other direction.

Then when it’s time to set the idle animation:

    if self.moving then
		go.set_position(go.get_position() + self.dir * self.speed * dt)
    elseif self.animation_direction == hash("north") then

        --animation here

    --elseif self.animation_direction == hash("south") then

        --other animations here etc

	else
		sprite.play_flipbook("#sprite", hash("player_idle"))
	end

Does that make sense or have I misunderstood your issue? Nested ifs like the above would work and are probably a good way to start out, but for more elegance I’d be storing animation references in tables something like:

 sprite.play_flipbook("#sprite", idle_animations[self.animation_direction])
3 Likes

Need to touch up my art, but the animations are working. Thanks again.

3 Likes

Back to work on this.

Cleaned up the movement by having the player align itself to a grid during movement.

When the player moves along the x axis, it realigns along the y axis.

if state.is_pressed(hash("a")) then
	if not self.blocked.west then
		local pos = go.get_position()
		local dir = vmath.vector3(1, 0, 0)
		local new_pos = pos - dir

		new_pos.y = round(new_pos.y/8) * 8
		
		go.set_position(new_pos)
		
		sprite.set_hflip(".", true)
		play_animation(self, hash("player_walking"))	
		self.facing_dir = "west"			
	end
end

And vice versa.

elseif state.is_pressed(hash("w")) then
	if not self.blocked.north then
		local pos = go.get_position()
		local dir = vmath.vector3(0, 1, 0)
		local new_pos = pos + dir

		new_pos.x = round(new_pos.x/8) * 8
		go.set_position(new_pos)
		
		play_animation(self, hash("player_walking_north"))
		
		self.facing_dir = "north"

The round function:

local function round(n)
	return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
end

This method prevents the player from getting snagged on obstacles as well as makes it easier for them to position themselves to enter tight spaces.

Example:
(Notice how when the character is unable to enter a passage, the player doesn’t have to “fight” to find the pixel perfect vector to enter, because the game aligns the player to the grid)

To prevent movement across tiles, I’m using tile map collisions. The player has 4 collisions that use triggers to block the movement.

Adventure Game - Defold Editor 2.0 2022-01-04 12-30-04

if message_id == hash("trigger_response") then
		if sender.fragment == hash("player_north") then
			if message.enter then
				self.blocked.north = true
			else
				self.blocked.north = false
			end
		elseif sender.fragment == hash("player_south") then
			if message.enter then
				self.blocked.south = true
			else
				self.blocked.south = false
			end
		elseif sender.fragment == hash("player_east") then
			if message.enter then
				self.blocked.east = true
			else
				self.blocked.east = false
			end
		elseif sender.fragment == hash("player_west") then
			if message.enter then
				self.blocked.west = true
			else
				self.blocked.west = false
			end
		end
	end

The following info was helpful for doing this:

4 Likes

Hey Raymond, its nice to know my grid workaround was useful to you. Good luck with the project!

Thanks for sharing! :smiley: this is what i was looking for

Hey @rayraytime, this case is very interesting :+1: Did you delete the repo for the project? The GitHub link seems to not lead anywhere now.

I believe I did. I cleaned up my GH since I never got used to using it (I know, I know). I should take the time to understand GH. I know it’s important. But as someone who programs as a hobby, it felt like extra work and I didn’t see the benefit.

1 Like

Well, it’s hard to blame you :sweat_smile: But anyway, if by any chance you have your experiments saved somewhere, I would really appreciate if you could shared them. Learning the same way with my son now, playing with Defold and Lua.

Hi @fyodorio !
Not sure if you’ve seen these, you can probably look at examples from @britzl and some more complete games by @benjames171 here. I’m sure you’ll find some goos inspiration there:

http://britzl.github.io/publicexamples/

2 Likes

I’d highly recommend going through the samples, tutorials, and projects from other members. Figure out what you want to do, find someone who’s done it, and replicate the code.

Also, start with simple games. Take pleasure in the basics. Learn how to go from idea to basic game as fast as possible. Maybe even practice launching it on the app store or itch/poki.

2 Likes

Nice, but link in github is dead

Yes, I removed the project. I will delete it from the main post to avoid confusion.