Create Pong with GDNative C++ demo

This commit is contained in:
Aaron Franke
2021-07-08 21:55:16 -04:00
parent 798fc4fe34
commit 6f6230b899
31 changed files with 738 additions and 0 deletions

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[submodule "cpp/simple/godot-cpp"]
path = cpp/simple/godot-cpp
url = https://github.com/godotengine/godot-cpp.git
[submodule "cpp/pong/godot-cpp"]
path = cpp/pong/godot-cpp
url = https://github.com/godotengine/godot-cpp.git

44
cpp/pong/README.md Normal file
View File

@@ -0,0 +1,44 @@
# Pong with GDNative C++
A simple Pong game, made with GDNative C++. This demo shows best practices
for game development in Godot, including
[signals](https://docs.godotengine.org/en/latest/getting_started/step_by_step/signals.html).
Language: C++
Renderer: GLES 2
Note: There is a GDScript version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/2d/pong).
Note: There is a C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/pong).
Note: There is a VisualScript version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/visual_script/pong).
## Compiling
You can use SCons to compile the library:
```
scons platform=PLATFORM
```
Where PLATFORM is: `windows`, `linux`, or `osx`.
This creates the file `libsimple` in the respective
subfolders in the `project/gdnative` directory.
Dependencies:
* You need [godot-cpp](https://github.com/godotengine/godot-cpp),
this is now a Git submodule of this repo.
* `clang`, `gcc`, or any decent C compiler that's C++14 compatible.
## How does it work?
The walls, paddle, and ball are all
[`Area2D`](https://docs.godotengine.org/en/latest/classes/class_area2d.html)
nodes. When the ball touches the walls or the paddles,
they emit signals and modify the ball.
## Screenshots
![Screenshot](screenshots/pong.png)

111
cpp/pong/SConstruct Normal file
View File

@@ -0,0 +1,111 @@
#!python
import os
opts = Variables([], ARGUMENTS)
# Gets the standard flags CC, CCX, etc.
env = DefaultEnvironment()
godot_headers_path = "godot-cpp/godot-headers"
godot_bindings_path = "godot-cpp"
# Define our options. Use future-proofed names for platforms.
platform_array = ["", "windows", "linuxbsd", "macos", "x11", "linux", "osx"]
opts.Add(EnumVariable("target", "Compilation target", "debug", ["d", "debug", "r", "release"]))
opts.Add(EnumVariable("platform", "Compilation platform", "", platform_array))
opts.Add(EnumVariable("p", "Alias for 'platform'", "", platform_array))
opts.Add(BoolVariable("use_llvm", "Use the LLVM / Clang compiler", "no"))
opts.Add(PathVariable("target_path", "The path where the lib is installed.", "project/gdnative/"))
opts.Add(PathVariable("target_name", "The library name.", "libpong", PathVariable.PathAccept))
# Updates the environment with the option variables.
opts.Update(env)
# Process platform arguments. Here we use the same names as GDNative.
if env["p"] != "":
env["platform"] = env["p"]
if env["platform"] == "macos":
env["platform"] = "osx"
elif env["platform"] in ("x11", "linuxbsd"):
env["platform"] = "linux"
elif env["platform"] == "bsd":
env["platform"] = "freebsd"
if env["platform"] == "":
print("No valid target platform selected.")
quit()
platform = env["platform"]
# Process other arguments.
if env["platform"] == "osx" and not env["use_llvm"]:
env["use_llvm"] = "yes"
if env["use_llvm"] == "yes":
env["CC"] = "clang"
env["CXX"] = "clang++"
# put stuff that is the same for all first, saves duplication
if env["platform"] == "osx":
if env["target"] in ("debug", "d"):
env.Append(CCFLAGS=["-g", "-O2", "-arch", "x86_64", "-std=c++14"])
env.Append(LINKFLAGS=["-arch", "x86_64"])
else:
env.Append(CCFLAGS=["-g", "-O3", "-arch", "x86_64", "-std=c++14"])
env.Append(LINKFLAGS=["-arch", "x86_64"])
elif env["platform"] == "linux":
if env["target"] in ("debug", "d"):
env.Append(CCFLAGS=["-fPIC", "-g3", "-Og"])
else:
env.Append(CCFLAGS=["-fPIC", "-g", "-O3"])
elif env["platform"] == "windows":
# This makes sure to keep the session environment variables
# on Windows, so that you can run scons in a VS 2017 prompt
# and it will find all the required tools.
env = Environment(ENV=os.environ)
opts.Update(env)
env.Append(CCFLAGS=["-DWIN32", "-D_WIN32", "-D_WINDOWS", "-W3", "-GR", "-D_CRT_SECURE_NO_WARNINGS"])
if env["target"] in ("debug", "d"):
env.Append(CCFLAGS=["-EHsc", "-D_DEBUG", "-MDd"])
else:
env.Append(CCFLAGS=["-O2", "-EHsc", "-DNDEBUG", "-MD"])
SConscript("godot-cpp/SConstruct")
def add_sources(sources, dir):
for f in os.listdir(dir):
if f.endswith(".cpp"):
sources.append(dir + "/" + f)
env.Append(
CPPPATH=[
godot_headers_path,
godot_bindings_path + "/include",
godot_bindings_path + "/include/gen/",
godot_bindings_path + "/include/core/",
]
)
env.Append(
LIBS=[
env.File(
os.path.join(
"godot-cpp/bin", "libgodot-cpp.%s.%s.64%s" % (env["platform"], env["target"], env["LIBSUFFIX"])
)
)
]
)
env.Append(LIBPATH=[godot_bindings_path + "/bin/"])
sources = []
add_sources(sources, "src")
library = env.SharedLibrary(
target=env["target_path"] + "/" + env["platform"] + "/" + env["target_name"], source=sources
)
Default(library)

BIN
cpp/pong/project/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/ball.png-9a4ca347acb7532f6ae347744a6b04f7.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://ball.png"
dest_files=[ "res://.import/ball.png-9a4ca347acb7532f6ae347744a6b04f7.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,18 @@
[general]
singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=true
[entry]
Windows.64="res://gdnative/windows/libpong.dll"
X11.64="res://gdnative/linux/libpong.so"
OSX.64="res://gdnative/osx/libpong.dylib"
[dependencies]
Windows.64=[ ]
X11.64=[ ]
OSX.64=[ ]

View File

@@ -0,0 +1,2 @@
*
!.gitignore

BIN
cpp/pong/project/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/pong.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "Ball"
class_name = "Ball"
library = ExtResource( 1 )

View File

@@ -0,0 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/pong.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "CeilingFloor"
class_name = "CeilingFloor"
library = ExtResource( 1 )

View File

@@ -0,0 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/pong.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "Paddle"
class_name = "Paddle"
library = ExtResource( 1 )

View File

@@ -0,0 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://gdnative/pong.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "Wall"
class_name = "Wall"
library = ExtResource( 1 )

BIN
cpp/pong/project/paddle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/paddle.png-0e798fb0912613386507c9904d5cc01a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://paddle.png"
dest_files=[ "res://.import/paddle.png-0e798fb0912613386507c9904d5cc01a.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

107
cpp/pong/project/pong.tscn Normal file
View File

@@ -0,0 +1,107 @@
[gd_scene load_steps=12 format=2]
[ext_resource path="res://logic/paddle.gdns" type="Script" id=1]
[ext_resource path="res://paddle.png" type="Texture" id=2]
[ext_resource path="res://logic/ball.gdns" type="Script" id=4]
[ext_resource path="res://ball.png" type="Texture" id=5]
[ext_resource path="res://separator.png" type="Texture" id=6]
[ext_resource path="res://logic/wall.gdns" type="Script" id=7]
[ext_resource path="res://logic/ceiling_floor.gdns" type="Script" id=8]
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 4, 16 )
[sub_resource type="RectangleShape2D" id=2]
extents = Vector2( 4, 4 )
[sub_resource type="RectangleShape2D" id=3]
extents = Vector2( 10, 200 )
[sub_resource type="RectangleShape2D" id=4]
extents = Vector2( 320, 10 )
[node name="Pong" type="Node2D"]
[node name="Background" type="ColorRect" parent="."]
margin_right = 640.0
margin_bottom = 400.0
color = Color( 0.141176, 0.152941, 0.164706, 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Left" type="Area2D" parent="."]
modulate = Color( 0, 1, 1, 1 )
position = Vector2( 67.6285, 192.594 )
script = ExtResource( 1 )
[node name="Sprite" type="Sprite" parent="Left"]
texture = ExtResource( 2 )
[node name="Collision" type="CollisionShape2D" parent="Left"]
shape = SubResource( 1 )
[node name="Right" type="Area2D" parent="."]
modulate = Color( 1, 0, 1, 1 )
position = Vector2( 563.815, 188.919 )
script = ExtResource( 1 )
[node name="Sprite" type="Sprite" parent="Right"]
texture = ExtResource( 2 )
[node name="Collision" type="CollisionShape2D" parent="Right"]
shape = SubResource( 1 )
[node name="Ball" type="Area2D" parent="."]
position = Vector2( 320.5, 191.124 )
script = ExtResource( 4 )
[node name="Sprite" type="Sprite" parent="Ball"]
texture = ExtResource( 5 )
[node name="Collision" type="CollisionShape2D" parent="Ball"]
shape = SubResource( 2 )
[node name="Separator" type="Sprite" parent="."]
position = Vector2( 320, 200 )
texture = ExtResource( 6 )
[node name="LeftWall" type="Area2D" parent="."]
position = Vector2( -10, 200 )
script = ExtResource( 7 )
[node name="Collision" type="CollisionShape2D" parent="LeftWall"]
shape = SubResource( 3 )
[node name="RightWall" type="Area2D" parent="."]
position = Vector2( 650, 200 )
script = ExtResource( 7 )
[node name="Collision" type="CollisionShape2D" parent="RightWall"]
shape = SubResource( 3 )
[node name="Ceiling" type="Area2D" parent="."]
position = Vector2( 320, -10 )
script = ExtResource( 8 )
[node name="Collision" type="CollisionShape2D" parent="Ceiling"]
shape = SubResource( 4 )
[node name="Floor" type="Area2D" parent="."]
position = Vector2( 320, 410 )
script = ExtResource( 8 )
bounce_direction = -1
[node name="Collision" type="CollisionShape2D" parent="Floor"]
shape = SubResource( 4 )
[node name="Camera2D" type="Camera2D" parent="."]
offset = Vector2( 320, 200 )
current = true
[connection signal="area_entered" from="Left" to="Left" method="_on_area_entered"]
[connection signal="area_entered" from="Right" to="Right" method="_on_area_entered"]
[connection signal="area_entered" from="LeftWall" to="LeftWall" method="_on_wall_area_entered"]
[connection signal="area_entered" from="RightWall" to="RightWall" method="_on_wall_area_entered"]
[connection signal="area_entered" from="Ceiling" to="Ceiling" method="_on_area_entered"]
[connection signal="area_entered" from="Floor" to="Floor" method="_on_area_entered"]

View File

@@ -0,0 +1,72 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
[application]
config/name="Pong with GDNative C++"
config/description="A simple Pong game. This demo shows best practices
for game development in Godot, including signals."
run/main_scene="pong.tscn"
config/icon="res://icon.png"
[display]
window/size/width=640
window/size/height=400
window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/aspect="expand"
stretch_2d=true
[gdnative]
singletons=[ ]
[input]
left_move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
]
}
left_move_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
]
}
right_move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":1.0,"script":null)
]
}
right_move_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":1,"axis":1,"axis_value":-1.0,"script":null)
]
}
[rendering]
quality/driver/driver_name="GLES2"
2d/snapping/use_gpu_pixel_snap=true
vram_compression/import_etc=true
vram_compression/import_etc2=false
quality/2d/use_pixel_snap=true
viewport/default_clear_color=Color( 0, 0, 0, 1 )

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/separator.png-f981c8489b9148e2e1dc63398273da74.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://separator.png"
dest_files=[ "res://.import/separator.png-f981c8489b9148e2e1dc63398273da74.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

24
cpp/pong/src/ball.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include "ball.hpp"
void Ball::_ready() {
_initial_pos = get_position();
}
void Ball::_process(double p_delta) {
_speed += p_delta * 2;
godot::Vector2 position = get_position();
position += _speed * p_delta * direction;
set_position(position);
}
void Ball::reset() {
direction = godot::Vector2(-1, 0);
set_position(_initial_pos);
_speed = DEFAULT_SPEED;
}
void Ball::_register_methods() {
godot::register_method("_ready", &Ball::_ready);
godot::register_method("_process", &Ball::_process);
godot::register_method("reset", &Ball::reset);
}

25
cpp/pong/src/ball.hpp Normal file
View File

@@ -0,0 +1,25 @@
#ifndef BALL_H
#define BALL_H
#include <Area2D.hpp>
#include <Godot.hpp>
class Ball : public godot::Area2D {
GODOT_CLASS(Ball, godot::Area2D)
const int DEFAULT_SPEED = 100;
real_t _speed = DEFAULT_SPEED;
godot::Vector2 _initial_pos;
public:
godot::Vector2 direction = godot::Vector2(-1, 0);
void _init() {}
void _ready();
void _process(double p_delta);
void reset();
static void _register_methods();
};
#endif // BALL_H

View File

@@ -0,0 +1,12 @@
#include "ceiling_floor.hpp"
void CeilingFloor::_on_area_entered(Ball *p_ball) {
if (p_ball->get_name() == "Ball") {
p_ball->direction = (p_ball->direction + godot::Vector2(0, bounce_direction)).normalized();
}
}
void CeilingFloor::_register_methods() {
godot::register_method("_on_area_entered", &CeilingFloor::_on_area_entered);
godot::register_property("bounce_direction", &CeilingFloor::bounce_direction, 1);
}

View File

@@ -0,0 +1,21 @@
#ifndef CEILING_FLOOR_H
#define CEILING_FLOOR_H
#include <Area2D.hpp>
#include <Godot.hpp>
#include "ball.hpp"
class CeilingFloor : public godot::Area2D {
GODOT_CLASS(CeilingFloor, godot::Area2D)
public:
int bounce_direction = 1;
void _init() {}
void _on_area_entered(Ball *p_ball);
static void _register_methods();
};
#endif // CEILING_FLOOR_H

23
cpp/pong/src/entry.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include <Godot.hpp>
#include "ball.hpp"
#include "ceiling_floor.hpp"
#include "paddle.hpp"
#include "wall.hpp"
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
godot::Godot::gdnative_init(o);
}
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
godot::Godot::gdnative_terminate(o);
}
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
godot::Godot::nativescript_init(handle);
godot::register_class<Ball>();
godot::register_class<CeilingFloor>();
godot::register_class<Paddle>();
godot::register_class<Wall>();
}

40
cpp/pong/src/paddle.cpp Normal file
View File

@@ -0,0 +1,40 @@
#include "paddle.hpp"
#include <Input.hpp>
#include <RandomNumberGenerator.hpp>
void Paddle::_ready() {
_screen_size_y = get_viewport_rect().size.y;
godot::String n = godot::String(get_name()).to_lower();
_up = n + "_move_up";
_down = n + "_move_down";
if (n == "left") {
_ball_dir = 1;
} else {
_ball_dir = -1;
}
}
void Paddle::_process(double delta) {
godot::Input *input = godot::Input::get_singleton();
// Move up and down based on input.
real_t keyboard_input = input->get_action_strength(_down) - input->get_action_strength(_up);
godot::Vector2 position = get_position();
position.y = godot::Math::clamp(position.y + keyboard_input * MOVE_SPEED * delta, 16.0, _screen_size_y - 16.0);
set_position(position);
}
void Paddle::_on_area_entered(Ball *p_ball) {
if (p_ball->get_name() == "Ball") {
godot::Ref<godot::RandomNumberGenerator> random = godot::RandomNumberGenerator::_new();
random->randomize();
// Assign new direction.
p_ball->direction = godot::Vector2(_ball_dir, random->randf() * 2 - 1).normalized();
}
}
void Paddle::_register_methods() {
godot::register_method("_ready", &Paddle::_ready);
godot::register_method("_process", &Paddle::_process);
godot::register_method("_on_area_entered", &Paddle::_on_area_entered);
}

29
cpp/pong/src/paddle.hpp Normal file
View File

@@ -0,0 +1,29 @@
#ifndef PADDLE_H
#define PADDLE_H
#include <Area2D.hpp>
#include <Godot.hpp>
#include "ball.hpp"
class Paddle : public godot::Area2D {
GODOT_CLASS(Paddle, godot::Area2D)
const int MOVE_SPEED = 100;
int _ball_dir;
godot::String _up;
godot::String _down;
real_t _screen_size_y;
public:
void _init() {}
void _ready();
void _process(double p_delta);
void _on_area_entered(Ball *p_area);
static void _register_methods();
};
#endif // PADDLE_H

12
cpp/pong/src/wall.cpp Normal file
View File

@@ -0,0 +1,12 @@
#include "wall.hpp"
void Wall::_on_wall_area_entered(Ball *p_ball) {
if (p_ball->get_name() == "Ball") {
// Ball went out of game area, reset.
p_ball->reset();
}
}
void Wall::_register_methods() {
godot::register_method("_on_wall_area_entered", &Wall::_on_wall_area_entered);
}

19
cpp/pong/src/wall.hpp Normal file
View File

@@ -0,0 +1,19 @@
#ifndef WALL_H
#define WALL_H
#include <Area2D.hpp>
#include <Godot.hpp>
#include "ball.hpp"
class Wall : public godot::Area2D {
GODOT_CLASS(Wall, godot::Area2D)
public:
void _init() {}
void _on_wall_area_entered(Ball *p_area);
static void _register_methods();
};
#endif // WALL_H