Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
80's style demos in Gideros - Page 3 — Gideros Forum

#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# 80's style demos in Gideros

13»

## Comments

• Maintainer
This is truly excellent, I frankly didn't expect a tetris in 3k, great job. We have pure gold in this thread, it will be hard to choose which one to publish first. Warm thanks to you all!

Likes: MoKaLux

+1 -1 (+1 / -0 )Share on Facebook
• Member
Simon says with sounds thanks to PaulH Removing tabs the char number drops below 3k but it has become already much more unreadable than before.

 ```local ns={440,261,293,392} function mwav(fn, q) local function wav(p,q) local n = math.floor(math.sin(p/6000 * q * math.rad(180))*256*127) local c2, c1 = (n>>8) & 0xff,n & 0xff return string.char(c1,c2) end f=io.open(fn,"wb") f:write(string.char(82,73,70,70,140, 9, 0, 0,87,65,86,69,102,109,116,32,16,0,0,0,1,0,1,0,112,23,0,0,224,46,0,0,2,0,16,0,100,97,116,97,96,9,0,0)) for l = 1, 1200 do f:write(wav(l,q)) end f:close() end   application:setBackgroundColor(0x000000) math.randomseed(os.timer()) s, sphrase, sstate, s_counter, usersay, start_time = {}, {}, "idle", 1, {}, os.timer() colors = {0xFF0000, 0x0000FF, 0x00FF00, 0xFFFF00} s_sector = Core.class(Sprite) sscale = {{5,5},{-5,5},{-5,-5},{5,-5}} function s_sector:init(i) self.gfx = Path2D.new() self.gfx:setSvgPath("M0.6,17.9c7.6,0,13.8,6.3,13.8,14.1L32,32C32,14.3,17.9,0,0.6,0V17.9z") self:addChild(self.gfx) self:setAnchorPoint(-0.01,1) self:setScale(sscale[i][1], sscale[i][2]) self.i = i self.gfx:setFillColor(colors[i],.5) self:addEventListener(Event.ENTER_FRAME, function() local dt = os.timer()-start_time if dt >0.5 and dt <0.6 then self.gfx:setFillColor(colors[i],.5) end end) end for i=1,4 do s[i] = s_sector.new(i) stage:addChild(s[i]) s[i]:setPosition(200,250) local b=Buffer.new(i..".wav") mwav("|B|"..i..".wav", ns[i], 1) ns[i] = Sound.new("|B|"..i..".wav") end play = TextField.new(nil, "PLAY") play:setTextColor(0xFFFFFF) play:setScale(2) play:setPosition(20,20) stage:addChild(play) stage:addEventListener(Event.MOUSE_DOWN, function(e) if sstate == "wait" then for i in ipairs(s) do if s[i].gfx:hitTestPoint(e.x, e.y) then ns[i]:play() -- bip usersay[#usersay+1] = i if sphrase[#usersay] == i then s[i].gfx:setFillColor(colors[i],1) if #usersay == #sphrase then sstate = "add" end else play:setText("YOU LOST AT LEVEL "..#sphrase.."!\nCLICK HERE TO TRY AGAIN") sstate = "idle" end end end end if play:hitTestPoint(e.x,e.y) then play:setText("SIMON'S TURN") sphrase = {} usersay = {} s_counter = 1 sstate = "add" end end) stage:addEventListener(Event.MOUSE_UP, function(e) for i in ipairs(s) do if s[i]:hitTestPoint(e.x, e.y) then s[i].gfx:setFillColor(colors[i],.5) end end end) stage:addEventListener(Event.ENTER_FRAME, function() if sstate == "go" then if os.timer()-start_time >0.7 then if s_counter <=#sphrase then ns[sphrase[s_counter]]:play() --bip s[sphrase[s_counter]].gfx:setFillColor(colors[sphrase[s_counter]],1) start_time = os.timer() end if s_counter == #sphrase then sstate = "wait" play:setText("YOUR TURN") else sstate = "next" play:setText("SIMON'S TURN") end end elseif sstate == "add" then sphrase[#sphrase+1]=math.random(4) s_counter, usersay, sstate, start_time = 1, {}, "go", os.timer() elseif sstate == "next" then s_counter, sstate = s_counter+1, "go" end end)```

Likes: PaulH, MoKaLux

+1 -1 (+2 / -0 )Share on Facebook
• Member
keszegh said:

rrraptor said:

keszegh said:

i did not expect a tetris in 3k. great thread.

A bit more I updated the code, now it is 3279 (114 lines) (before: 3317 (115))
you could separately share the imgui version, it could give ideas for us how to use the imgui graphics functions.
3062
 ```require "ImGui" ui=ImGui.new() application:setWindowSize(320,720) ui:getIO():setDisplaySize(320,720) stage:addChild(ui) GS,SC,MSC,TR,TS,CM,KC,BR,ST=0,0,0,0,1,false,KeyCode,{},{[0]=0,40,100,300,1200} BR=table.create(21) for i=1,20 do BR[i]=table.create(10,0) end BR[21]=table.create(10,8) TES={ {0x00F0F0,{{0,0,0,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}}}, {0x0000F0,{{1,0,0},{1,1,1},{0,0,0}}}, {0xF0A000,{{0,0,1},{1,1,1},{0,0,0}}}, {0xF0F000,{{1,1},{1,1}}}, {0x00F000,{{0,1,1},{1,1,0},{0,0,0}}}, {0xA000F0,{{0,1,0},{1,1,1},{0,0,0}}}, {0xF00000,{{1,1,0},{0,1,1},{0,0,0}}}, {0x323232} } T={i=0,x=4,y=1,d=0} function forT(t,c) for y=1,#t do for x=1,#t[1] do if t[y][x]>0 then local r=c(x,y) if r~=nil then return r end end end end end function over(t,tx,ty,td) return forT(td,function(x,y) local bv=t[ty+y-1][tx+x-1] if not bv or bv>0 then return true end end) end function put(t,tx,ty,td,n) forT(td,function(x,y) t[ty+y-1][tx+x-1]=n end) end function trMv(x,y,nb) local tb={} for i=1,21 do tb[i]={} for j=1,10 do tb[i][j]=BR[i][j] end end put(tb,T.x,T.y,T.d,0) if not over(tb,x,y,nb) then put(BR,T.x,T.y,T.d,0) put(BR,x,y,nb,T.i) return true end end function mv(dx, dy) local nx,ny=T.x+dx,T.y+dy if trMv(nx,ny,T.d) then T.x,T.y=nx,ny return true end end stage:addEventListener("keyDown", function(e) if e.keyCode==KC.SPACE and GS==0 then GS=1 end if not CM then return end if e.keyCode==KC.DOWN then TS=0.05 elseif e.keyCode==KC.UP then local nb={} for i=#T.d[1],1,-1 do nb[i]={} for j=1,#T.d do nb[i][j]=T.d[#T.d-j+1][i] end end if trMv(T.x,T.y,nb) then T.d=nb end elseif e.keyCode==KC.LEFT then mv(-1,0) elseif e.keyCode==KC.RIGHT then mv(1,0) end end) stage:addEventListener("keyUp", function(e) if e.keyCode==KC.DOWN then TS=1 end end) stage:addEventListener("enterFrame", function(e) ui:newFrame(e.deltaTime) TR+=e.deltaTime if TR>0.4*TS then TR=0 if GS==1 then T.x,T.y,T.i=4,1,math.random(1, 7) T.d=TES[T.i][2] if over(BR,T.x,T.y,T.d) then for i=1,m or 20 do for j=1,10 do BR[i][j]=0 end end GS,SC,CM=0,0,false else put(BR,T.x,T.y,T.d,T.i) GS,CM=2,true end elseif GS==2 then if not mv(0,1) then local r=0 for y=1,20 do local c=0 for x=1,10 do if BR[y][x]>0 then c+=1 end end if c == 10 then table.remove(BR,y) table.insert(BR,1,table.create(10,0)) r+=1 end end SC+=ST[r] MSC=MSC<>SC GS,CM=1,false end end end local list=ui:getForegroundDrawList() local text="Press 'Space' to start" if GS==0 then text=`Score: {SC} Max: {MSC}\n{text}` else text=`Score: {SC} Max: {MSC}` end list:addText(10,3,0,1,text) for i,r in ipairs(BR) do for j,c in ipairs(r) do if c>0 then list:addRectFilled((j-1)*32,i*32,j*32,(i+1)*32,TES[c][1]) list:addRect((j-1)*32,i*32,j*32,(i+1)*32,0,0.5,2) end end end list:addLine(0,32,320,32,0,1) ui:render() ui:endFrame() end)```
+1 -1 (+5 / -0 )Share on Facebook
• Member
@rrraptor Unbelievable! I still reading to find out why these 114 lines of code can have a complicated "rotate clamp in the boundary" feature! Thank you so much!
Coming soon
• Member
edited May 2023

@rrraptor Unbelievable! I still reading to find out why these 114 lines of code can have a complicated "rotate clamp in the boundary" feature! Thank you so much!

At the bottom I hardcoded a wall. For left & right boundaries the trick is that I copy the whole board into a temporary array (the "trMv" function aka "tryMove"), then I "erase" the current piece from it and check for a collision with something (but in a new position), there is also a check for out of bounds by checking for "nil" (however in the code I wrote it as "not bv" aka "boardValue ~= nil") in "over" function (aka "overlap")

Here is uncut version (with imgui):
 ```require "ImGui"   -- Constants -- BOARD_W = 10 BOARD_H = 20 TILE = 32   -- Global variables --   -- values for 'GameState' variable States = { GAME_OVER = 0, SPAWN = 1, REMOVE_LINES = 2 } GameState = 0 GameSpeed = 0.4 -- lower -> faster SpeedUPFactor = 0.05 -- GameSpeed multiplier when holding 'Down' (lower -> faster) Score = 0 MaxScore = 0 Timer = 0 TimerScale = 1 CanMove = false ScoreTable = {[0]=0,40,100,300,1200} -- how many scores player get for burning N lines   -- initialize simple matrix Board = table.create(BOARD_H + 1) for i=1, BOARD_H do Board[i] = table.create(BOARD_W, 0) end Board[BOARD_H + 1] = table.create(BOARD_W,8) -- Floor   Tetrominos = { { -- I color = 0x00F0F0, data = { {0,0,0,0}, {1,1,1,1}, {0,0,0,0}, {0,0,0,0} } }, { -- J color = 0x0000F0, data = { {1,0,0}, {1,1,1}, {0,0,0} } }, { -- L color = 0xF0A000, data = { {0,0,1}, {1,1,1}, {0,0,0} } }, { -- O color = 0xF0F000, data = { {1,1}, {1,1} } }, { -- S color = 0x00F000, data = { {0,1,1}, {1,1,0}, {0,0,0} } }, { -- T color = 0xA000F0, data = { {0,1,0}, {1,1,1}, {0,0,0} } }, { -- Z color = 0xF00000, data = { {1,1,0}, {0,1,1}, {0,0,0} } }, -- Floor color {0x323232} } CurrentTetromino = { index = 0, -- index in 'Tetrominos' table x = 4, -- position y = 1, data = 0 -- data from 'Tetrominos' table }   ui=ImGui.new() IO = ui:getIO() stage:addChild(ui)   function forEachTetromino(tetData, callback) local h = #tetData local w = #tetData[1] for y=1, h do for x=1, w do if tetData[y][x] > 0 then local returnValue = callback(x, y) if returnValue ~= nil then return returnValue end end end end end   function overlap(board, tx, ty, tetData) return forEachTetromino(tetData, function(x, y) local boardValue = board[ty + y - 1][tx + x - 1] if boardValue == nil or boardValue > 0 then return true end end) end   function setBoard(board, tx, ty, tetData, value) forEachTetromino(tetData, function(x, y) board[ty + y - 1][tx + x - 1] = value end) end   function tryMove(dstX, dstY, tetData) -- copy 'Board' to temp table local tempBoard = {} for i=1,BOARD_H + 1 do tempBoard[i] = {} for j = 1, BOARD_W do tempBoard[i][j] = Board[i][j] end end   -- remove current piece from temp board setBoard(tempBoard, CurrentTetromino.x, CurrentTetromino.y, CurrentTetromino.data, 0) -- check for collisions at destination point if not overlap(tempBoard, dstX, dstY, tetData) then -- erase data at old position setBoard(Board, CurrentTetromino.x, CurrentTetromino.y, CurrentTetromino.data, 0) -- add data at new position setBoard(Board, dstX, dstY, tetData, CurrentTetromino.index) return true end end   function move(dx, dy) local nx = CurrentTetromino.x + dx local ny = CurrentTetromino.y + dy   if tryMove(nx, ny, CurrentTetromino.data) then CurrentTetromino.x = nx CurrentTetromino.y = ny return true end end   function onAppResize() local minX, minY, maxX, maxY = application:getLogicalBounds() local screenW = maxX - minX local screenH = maxY - minY BoardOffsetX = (screenW - TILE * BOARD_W) * 0.5 BoardOffsetY = (screenH - TILE * BOARD_H) * 0.5 IO:setDisplaySize(screenW, screenH) end   function onKeyDown(e) if e.keyCode == KeyCode.SPACE and GameState == States.GAME_OVER then GameState = States.SPAWN end   if not CanMove then return end   if e.keyCode == KeyCode.DOWN then TimerScale = SpeedUPFactor elseif e.keyCode == KeyCode.UP then -- roatate current piece local rotatedData = {} local h = #CurrentTetromino.data local w = #CurrentTetromino.data[1]   for i = w, 1, -1 do rotatedData[i] = {} for j = 1, h do rotatedData[i][j] = CurrentTetromino.data[h - j + 1][i] end end   -- if there is no collision between rotated piece and something else, update current data if tryMove(CurrentTetromino.x, CurrentTetromino.y, rotatedData) then CurrentTetromino.data = rotatedData end elseif e.keyCode == KeyCode.LEFT then move(-1, 0) elseif e.keyCode == KeyCode.RIGHT then move(1, 0) end end   function onKeyUp(e) if e.keyCode == KeyCode.DOWN then TimerScale = 1 end end   function onEnterFrame(e) local dt = e.deltaTime   Timer += dt if Timer > GameSpeed * TimerScale then Timer = 0   if GameState == States.SPAWN then CurrentTetromino.x = math.round(BOARD_W / 2) CurrentTetromino.y = 1 CurrentTetromino.index = math.random(#Tetrominos - 1) CurrentTetromino.data = Tetrominos[CurrentTetromino.index].data   if overlap(Board, CurrentTetromino.x, CurrentTetromino.y, CurrentTetromino.data) then for i = 1, BOARD_H do for j=1, BOARD_W do Board[i][j] = 0 end end   GameState = States.GAME_OVER Score = 0 CanMove = false else setBoard(Board, CurrentTetromino.x, CurrentTetromino.y, CurrentTetromino.data, CurrentTetromino.index) GameState = States.REMOVE_LINES CanMove = true end elseif GameState == States.REMOVE_LINES then if not move(0, 1) then local rowsRemoved = 0   for y = 1, BOARD_H do local columnsFilled = 0   for x = 1, BOARD_W do if Board[y][x] > 0 then columnsFilled += 1 end end   if columnsFilled == BOARD_W then table.remove(Board, y) table.insert(Board, 1, table.create(BOARD_W, 0)) rowsRemoved += 1 end end   Score += ScoreTable[rowsRemoved] MaxScore = MaxScore <> Score GameState = States.SPAWN CanMove = false end end end   -- rendering with ImGui ui:newFrame(dt) local list = ui:getForegroundDrawList() local text = "Press 'Space' to start" if GameState == States.GAME_OVER then text=`Score: {Score} Max: {MaxScore}\n{text}` else text=`Score: {Score} Max: {MaxScore}` end list:addText(10, 3, 0, 1, text)   for i, row in ipairs(Board) do for j, cell in ipairs(row) do if cell > 0 then local sx = BoardOffsetX + (j - 1) * TILE local sy = BoardOffsetY + (i - 1) * TILE local ex = BoardOffsetX + j * TILE local ey = BoardOffsetY + i * TILE list:addRectFilled(sx, sy, ex, ey, Tetrominos[cell].color or 0) list:addRect(sx, sy, ex, ey,0, 0.5, 2) end end end list:addRect(BoardOffsetX, BoardOffsetY, BoardOffsetX + TILE * BOARD_W, BoardOffsetY + TILE * BOARD_H, 0, 1) ui:render() ui:endFrame() end   onAppResize() stage:addEventListener("applicationResize", onAppResize) stage:addEventListener("keyDown", onKeyDown) stage:addEventListener("keyUp", onKeyUp) stage:addEventListener("enterFrame", onEnterFrame)```
+1 -1 (+4 / -0 )Share on Facebook
• Member
I prefer latest rrraptor code, much more readable
Imho it is less scary (easier to explain) than all the funky code you guys posted.

So what is the goal, oneliners or short elegant Gideros games?

My two cents given I haven't produced anything yet
my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
• Member
edited May 2023
we could provide director's cuts (or uncut?) when possible, which are mostly the same code but more readable.

Likes: MoKaLux, pie, PaulH, hgy29

+1 -1 (+4 / -0 )Share on Facebook
• Maintainer
I've had a go at making a first single sheet short gideros code publication. For the first one, I choosed @PaulH plane game, I'll publish it on the internet and see if that gets some attention. If so, maybe we could make a poll to choose next publications.
Here is the first link: https://wiki.gideros.rocks/images/d/d1/Short-Issue1-Overheat.pdf

Likes: pie

+1 -1 (+1 / -0 )Share on Facebook
• Member
the line numbers should not be in the same block as the codes, as then one cannot copy-paste.
• Maintainer
keszegh said:

the line numbers should not be in the same block as the codes, as then one cannot copy-paste.

Well, you are not supposed to copy-paste, but to retype it, as if it was printed...
• Member
i understand the idea, but let's be realistic..
• Maintainer
keszegh said:

i understand the idea, but let's be realistic..

Agreed, but this fact is I just don't know how to separate the numbering from the text block, since numbering was done automatically by MS Publisher
• Member
even without numbers it would be better i think.
Sign In or Register to comment.