Simple Ball Game

Hello,

i want to make a simple game, but i need some help. I can explain you what i want to do:

  • Create a circle in the middle of the screen. The radius depends on the screen resolution.
  • When i tap the screen the ball should move around, but only inside the screen. So it should bounce off the screen.

Can someone help me? It would be really awsome.
Thank you,

Lukas

1 Like

I would suggest first going through the tutorials on the site.

The walking astronaut tutorial shows how to get a sprite moving on the screen.

Then check out britzl’s amazing grab bag of examples:

https://britzl.github.io/publicexamples/

There is also a pong game here which would be a big help:

Good luck and welcome to the forum.

4 Likes

My recommendation is to use a sprite component from an atlas. The default render script will scale the game view with the screen resolution. You can see this in an example as well (the sprite is animated using a flipbook animation as well)

You should read the input manual

You could use the built in physics system and apply a force to get realistic movement. Here’s also an example. Or use kinematic collisions and check my Pong example.

4 Likes

@britzl Thank you for your fast answer!
It really helped me, but i got some more questions now.

  • I set the physics scale to -1 and applied a force to the body and all looked good, but then i saw that sometimes the ball gets stucked to the wall. Then i read that i have to set the scale to 1 but with 1 i cant apply a “fast” force.

  • I dont really get it how to get the circle “round” on all devices.

Maybe you can help me. I attach my Project as a .zip File

Best Regards,
Lukas
12345_Test.zip (1.2 MB)

My recommendation would be to set the physics scale to maybe 0.02 and apply a fairly large force over multiple frames. A single apply_force over 1/60 of a second will not amount to much.

You can change from the default projection (which stretches content) to a fixed fit projection. See https://www.defold.com/manuals/render/#_default_view_projection

1 Like

Thank you @britzl, it works much better now.

But i dont really get it with the fixed fit projection.
When i change it, the ball looks great on all devices. :+1:
But how can i handle it that the walls are always the screen edges?

Best Regards,
Lukas

You need to have four game objects, one per edge and one collision object per edge. Make the collision objects wider than the edges to accommodate for different aspect ratios.

Next step is to move them at run-time based on the screen size to keep them along the edges. You can get the screen size from the render script using the render.get_window_width/height(). These functions can only be called from the render script though. The easiest solution to this is to make a copy of the default render script and use that instead. In your copy you could add a message to query for window size:

function on_message(self, message_id, message)
    if message_id == hash("query_window_size") then
        msg.post(sender, "window_size", { width = render.get_window_width(), height = render.get_window_height() })
    elseif .... rest of message handlers here

You use it from your script like this:

local function position_edges(width, height)
	-- position edge game objects here
end

function init(self)
	msg.post("@render:", "query_window_size")
end

function on_message(self, message_id, message, sender)
	if message_id == hash("window_size") then
		position_edges(message.width, message.height)
	end
end
3 Likes

Thank you very much! It works great!
But i have one more question.

In my game.project i defined:

  • Width: 640
  • Height: 1136

As you said i made 4 game objects with a collisionobject inside.

  • wallLeft (collsionshape Box with Dimensions W100 and H9000)
  • wallRight (collsionshape Box with Dimensions W100 and H9000)
  • wallUp (collsionshape Box with Dimensions W9000 and H100)
  • wallDown (collsionshape Box with Dimensions W9000 and H100)

in the script for my wallLeft i set the position as you said:

local function position_edges(width, height)
-- position edge game objects here
print("WIDTH", width)
print("Height",height)

pos = vmath.vector3(-50 , height/2, 0)

msg.post("/wallLeft#wallLeft", "disable")
go.set_position(pos,"/wallLeft#wallLeft" )
msg.post("/wallLeft#wallLeft", "enable")
end

When i start the debug mode on windows it prints out:
|DEBUG:SCRIPT: WIDTH|640|
|DEBUG:SCRIPT: Height|1061|
And the walls are not placed right. (I attached a screenshot)

Also when i test it on my Galaxy S9 it doesnt work.

Can you see what i do wrong?

Best Regards,
Lukas

Hmm, hard to tell. Could you please zip the project and share it here?

Thank you @britzl for your fast answer!
Here is my project in a zip.

12345_Test.zip (2.5 MB)

Ok, so I would change the wall edges from static to kinematic to make them easier to move (you don’t have to disable and enable the collision objects). Next, I’d move all four edges in the same script, instead of spread out over four scripts (one per edge). Since you use fixed fit projection you need to basically do the same calculations as in the render script to calculate the projected width and height as well as the horizontal and vertical offset. This is the final main.script:

local WIDTH = tonumber(sys.get_config("display.width"))
local HEIGHT = tonumber(sys.get_config("display.height"))

function init(self)
	msg.post("@render:", "query_window_size")
	window.set_listener(function()
		msg.post("@render:", "query_window_size")
	end)
end

function on_message(self, message_id, message, sender)
	if message_id == hash("window_size") then
		local window_width = message.width
		local window_height = message.height
		local zoom = math.min(window_width / WIDTH, window_height / HEIGHT)
		local projected_width = window_width / zoom
		local projected_height = window_height / zoom
		local xoffset = -(projected_width - WIDTH) / 2
		local yoffset = -(projected_height - HEIGHT) / 2
		go.set_position(vmath.vector3(xoffset - 50, projected_height / 2, 0), "/wallLeft")
		go.set_position(vmath.vector3(xoffset + projected_width + 50, projected_height / 2, 0), "/wallRight")
		go.set_position(vmath.vector3(projected_width / 2, yoffset - 50, 0), "/wallDown")
		go.set_position(vmath.vector3(projected_width / 2, yoffset + projected_height + 50, 0), "/wallUp")
	end
end
2 Likes

Thank you very much @britzl

It works perfect! Thank you very much.

I tried that, but the problem is that with physics scale of 0.02 the ball also gets stucked on the wall.
In this topic -> How to make dynamic objects bounce SLOWLY (DEF-2488) you sent a “.gif” with the same behaviour like in my game and your answer was:

“If you increase the physics scale from the default value of 0.02 up to 1.0 (maximum value) you will see that collisions are resolved correctly even at very low speeds.”

I tried to set the scale to 1.0 but i dont know how i can give that ball a bigger speed then. I tried to apply a force multiple times but for me i dont see any difference.

Would be great if you can help me again.
And thank you very much for your fast help again! :+1: