From d1ef73f17d42040ef5633d97503c1814a8c0fb8e Mon Sep 17 00:00:00 2001 From: RodrigoDornelles Date: Tue, 25 Jun 2024 14:09:56 -0300 Subject: [PATCH] feat: pong like hello world --- .gitignore | 1 + README.md | 4 ++ SUPPORT.md | 22 ++++++++++ examples/pong/game.lua | 65 ++++++++++++++++++++++++++++ src/cli.lua | 7 +++ src/common/game_math.lua | 23 ++++++++++ src/engine/ginga/core.lua | 90 +++++++++++++++++++++++++++++++++++++++ src/engine/ginga/main.ncl | 15 +++++++ 8 files changed, 227 insertions(+) create mode 100644 .gitignore create mode 100644 SUPPORT.md create mode 100644 examples/pong/game.lua create mode 100644 src/cli.lua create mode 100644 src/common/game_math.lua create mode 100644 src/engine/ginga/core.lua create mode 100644 src/engine/ginga/main.ncl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7773828 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist/ \ No newline at end of file diff --git a/README.md b/README.md index d7e628f..3add5aa 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # codename-videogame-engine A cross-platform embeddable LUA game engine such as ginga, love2d, roblox and its own console like a Wii clone. + +```bash +$ lua src/cli.lua && ginga dist/main.ncl +``` diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..12fbfa5 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,22 @@ +Platform Support List +===================== + +Tier 1 +------ + + - [ ] [Ginga](https://github.com/TeleMidia/ginga) + - [ ] [Love2D](https://github.com/love2d/love) + - [ ] UnitTest + +Tier 2 +------ + + - [ ] Curses + - [ ] Console + +Tier 3 +------ + + - [ ] Browser + - [ ] Roblox + diff --git a/examples/pong/game.lua b/examples/pong/game.lua new file mode 100644 index 0000000..ef26a6b --- /dev/null +++ b/examples/pong/game.lua @@ -0,0 +1,65 @@ +local function init(std, game) + game.highscore = game.highscore or 0 + game.player_size = std.game.height/8 + game.player_pos = std.game.height/2 - game.player_size/2 + game.ball_pos_x = std.game.witdh/2 + game.ball_pos_y = std.game.height/2 + game.ball_spd_x = 5 + game.ball_spd_y = 1 + game.ball_size = 8 + game.score = 0 +end + +local function loop(std, game) + -- inputs + game.player_dir = std.key.press.down - std.key.press.up + -- moves + game.player_pos = std.math.clamp(game.player_pos + (game.player_dir * 7), 0, std.game.height - game.player_size) + game.ball_pos_x = game.ball_pos_x + game.ball_spd_x + game.ball_pos_y = game.ball_pos_y + game.ball_spd_y + -- colisions + if game.ball_pos_x >= (std.game.witdh - game.ball_size) then + game.ball_spd_x = game.ball_spd_x * -1 + end + if game.ball_pos_y <= 0 or game.ball_pos_y >= (std.game.height - game.ball_size) then + game.ball_spd_y = game.ball_spd_y * -1 + end + if game.ball_pos_x <= 0 then + if std.math.clamp(game.ball_pos_y, game.player_pos, game.player_pos + game.player_size) == game.ball_pos_y then + game.ball_spd_y = std.math.clamp(game.ball_spd_y + (game.player_pos % 10) - 5, -10, 10) + game.ball_spd_x = game.ball_spd_x * -1.05 + game.score = game.score + 1 + else + std.game.reset() + end + end +end + +local function draw(std, game) + std.draw.color('black') + std.draw.rect('fill', 0, 0, std.game.witdh, std.game.height) + std.draw.color('white') + std.draw.rect('fill', 4, game.player_pos, 8, game.player_size) + std.draw.rect('fill', game.ball_pos_x, game.ball_pos_y, game.ball_size, game.ball_size) + std.draw.font('Tiresias', 32) + std.draw.text(std.game.witdh/4, 16, game.score) + std.draw.text((std.game.witdh/4 * 3), 16, game.highscore) +end + +local function exit(std, game) + game.highscore = std.math.clamp(game.highscore, game.score, game.highscore) +end + +local P = { + title='Pong', + description='simple pong', + version='1.0.0', + callbacks={ + init=init, + loop=loop, + draw=draw, + exit=exit + } +} + +return P; diff --git a/src/cli.lua b/src/cli.lua new file mode 100644 index 0000000..2b3aa21 --- /dev/null +++ b/src/cli.lua @@ -0,0 +1,7 @@ +local os = require('os') + +print(os.execute('mkdir -p ./dist/')) +print(os.execute('cp examples/pong/game.lua dist/game.lua')) +print(os.execute('cp src/common/*.lua dist')) +print(os.execute('cp src/engine/ginga/core.lua dist/main.lua')) +print(os.execute('cp src/engine/ginga/main.ncl dist/main.ncl')) diff --git a/src/common/game_math.lua b/src/common/game_math.lua new file mode 100644 index 0000000..0f8fbca --- /dev/null +++ b/src/common/game_math.lua @@ -0,0 +1,23 @@ +local function clamp(value, min, max) + if value < min then + return min + elseif value > max then + return max + else + return value + end +end + +local function abs(value) + if value < 0 then + return -value + end + return value +end + +local P = { + clamp=clamp, + abs=abs +} + +return P; diff --git a/src/engine/ginga/core.lua b/src/engine/ginga/core.lua new file mode 100644 index 0000000..247718c --- /dev/null +++ b/src/engine/ginga/core.lua @@ -0,0 +1,90 @@ +local game = require('game') +local math = require('game_math') +local canvas = canvas +local event = event +local game_obj = {} +local std = {draw={},key={press={}},game={}} +local fixture190 = '' +_ENV = nil + +local function std_draw_color(color) + canvas:attrColor(color) +end + +local function std_draw_rect(a,b,c,d,e) + canvas:drawRect(a,b,c,d,e) +end + +local function std_draw_text(a,b,c) + canvas:drawText(a,b,c) +end + +local function std_draw_font(a,b,c) + canvas:attrFont(a,b,c) +end + +local function std_game_reset() + if game.callbacks.exit then + game.callbacks.exit(std, game_obj) + end + if game.callbacks.init then + game.callbacks.init(std, game_obj) + end +end + +local function event_loop(evt) + if evt.class ~= 'key' then return end + + -- https://github.com/TeleMidia/ginga/issues/190 + if #fixture190 == 0 and evt.key ~= 'ENTER' then + fixture190 = evt.type + end + + if fixture190 == evt.type then + if evt.key == 'CURSOR_UP' then + std.key.press.up = 1 + end + if evt.key == 'CURSOR_DOWN' then + std.key.press.down = 1 + end + else + if evt.key == 'CURSOR_UP' then + std.key.press.up = 0 + end + if evt.key == 'CURSOR_DOWN' then + std.key.press.down = 0 + end + end +end + +local function fixed_loop() + game.callbacks.loop(std, game_obj) + canvas:attrColor(0, 0, 0, 0) + canvas:clear() + game.callbacks.draw(std, game_obj) + canvas:flush() + event.timer(1, fixed_loop) +end + +local function setup(evt) + if evt.class ~= 'ncl' or evt.action ~= 'start' then return end + local w, h = canvas:attrSize() + std.math=math + std.draw.color=std_draw_color + std.draw.rect=std_draw_rect + std.draw.text=std_draw_text + std.draw.font=std_draw_font + std.key.press.up=0 + std.key.press.down=0 + std.key.press.left=0 + std.key.press.right=0 + std.game.reset=std_game_reset + std.game.witdh=w + std.game.height=h + game.callbacks.init(std, game_obj) + event.register(event_loop) + event.timer(1, fixed_loop) + event.unregister(setup) +end + +event.register(setup) diff --git a/src/engine/ginga/main.ncl b/src/engine/ginga/main.ncl new file mode 100644 index 0000000..a7742fa --- /dev/null +++ b/src/engine/ginga/main.ncl @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + +