Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Chockosta

Pages: [1] 2
1
TI-Nspire / [Lua] Unnamed danmaku
« on: December 19, 2012, 02:48:52 pm »
Hello guys !

Lately, I've been quite addicted into Touhou (even if my gameplay is terrible :) )

So I tried to make a danmaku game for the TI-Nspire. (danmaku are also known as bullet hells)
For now, my engine works nicely with ennemies and bosses. It still lacks lasers, but it is almost complete.
There is one demo level if you want to try it.
It's very short and simple, but it shows the possibilities of this game.


(The sprites are from Touhou Danmakufu)

BTW, please don't play it with the TI Nspire computer software, it reacts weirdly.

Here is the source code, if you want to have a look :
Code: [Select]
enemySprite={}
enemySprite[1]=image.new("\016\000\000\000\018\000\000\000\000\000\000\000 \000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000d\136\198\144c\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000c\140\198\148\132\140c\136\231\148J\210\139\218j\218\232\144!\132c\136\165\144\165\144c\140\000\000!\000J\165\016\186\239\181\173\165L\202\219\255\255\255\151\255j\210J\157\172\1691\190\017\190K\165!\004!\000\140\169\247\210Z\227\024\211\229\242\238\242\138\226\013\243\228\246\178\206\024\219Z\227\214\210\173\173!\004\000\000J\161\214\210\156\235\156\235\005\255n\218\243\238/\214\229\2421\239{\235Z\227s\194)\161\000\000\000\000\165\144R\186Z\223\189\247,\251\241\234w\255\244\234)\239\185\251[\227\214\206\140\165\132\140\000\000\000\000\165\1442\1869\215\189\243\220\251\246\169\244\234R\165\189\219\255\255|\223\247\210J\161!\132\000\000\000\000\165\1441\186Z\223\028\207=\223\188\182\216\1659\174\159\223\219\206\183\177\023\215k\165c\136\000\000\000\000\132\136\140\165\213\202\213\144\249\177\252\202\252\202^\211~\227W\165\212\140\248\182\207\161&\165\163\144!\132g\173S\170=\171\025\166}\227\159\235\191\231\191\231\158\231\029\199\217\157\219\170\247\186i\218\229\156\230\148\167\226v\219\127\191\026\162\253\194\158\223\190\231\190\223\220\190\151\161:\1626\207P\235\148\186\198\144\198\144\242\226\020\199\188\174\026\158[\170\220\190\029\195\188\170\221\162\249\157\213\194p\2356\211\150\182\198\144\198\144Z\227\158\207\249\182\221\170\221\166\254\170\030\171\030\171>\171\210\202/\2278\203~\211\182\194\131\136!\000\181\206}\211\021\203>\183\029\171\248\1902\227\210\202\244\1942\215\023\195\159\199}\223\016\182\000\128\000\000\231\148\253\1708\195\019\211\022\1994\2159\1957\199\218\182}\195\159\199:\211k\157B\132\000\000\000\000c\136\140\157;\191\187\170\154\174\029\187\159\211\158\2159\174}\215Z\219s\194\198\144\000\000\000\000\000\000\000\000c\136(\153\021\1585\166u\182\214\210\182\194U\162\016\182(\153\132\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000B\004\165\144\132\140c\136c\136!\132\000\000\000\000\000\000\000\000\000\000\000\000")
enemySprite[2]=image.new("\016\000\000\000\018\000\000\000\000\000\000\000 \000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000D\140\134\148#\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000c\140\166\148d\144C\140\167\152J\210\139\218j\218\136\156!\132C\136\133\144\133\148c\140\000\000!\000*\165\208\189\175\185-\173L\202\219\255\255\255\151\255j\210\234\164M\173\241\193\241\193+\169!\004!\000L\173\151\218\026\231\152\218\229\242\238\242\138\226\013\243\228\246\178\206\216\222\026\231\150\214m\177!\004\000\000\010\165\150\214\092\239\092\243\005\255n\218\243\238/\214\229\2421\239[\239\026\231\019\202\009\161\000\000\000\000\133\148\210\193\250\230\189\247,\251\241\234w\255\244\234)\239\185\251\027\231v\210,\169d\140\000\000\000\000\133\148\210\193\185\222\157\247\220\251V\209\244\2342\201\221\230\255\255\252\234\151\214\010\165!\132\000\000\000\000\133\144\209\189\250\226|\230\253\242\188\2258\217y\217\255\246{\234\151\221\184\218+\169C\140\000\000\000\000D\140,\173V\206\149\208\153\225\092\234\092\234\158\238\030\2437\217t\208\184\205\015\177&\165\163\144!\132g\173S\189]\2179\217\029\239_\247?\247?\247>\243=\234\249\216[\217\215\201i\218\229\156\230\148\167\226v\219\255\233\026\217\029\234\254\242>\247\254\242\252\229\023\217\026\2176\207P\235\212\197\134\148\134\148\242\226\020\199|\225\250\216[\221\252\229\029\230\092\221\029\221\249\216\022\202p\2356\211\182\205\134\148\134\148\026\231~\234\185\213]\221=\221^\225^\225^\217^\217\210\202/\227Y\214\158\234\022\206D\140!\000u\210\157\234\021\203\190\225]\221\248\2052\227\210\202\244\1942\215\024\206?\234\253\234\176\185\000\128\000\000\167\152]\217\025\210\019\2118\2064\215\025\2149\210\186\217\029\226?\234\154\226\235\164\034\136\000\000\000\000C\140\236\168\251\221[\217z\213\221\225\159\238\190\238y\221\189\234\218\230\019\198\134\148\000\000\000\000\000\000\000\000C\140\201\156\245\1965\201\181\201\150\214\022\206\021\197\176\185\201\156d\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000B\004\133\144d\144C\136C\136!\132\000\000\000\000\000\000\000\000\000\000\000\000")

bossSprite={}
bossSprite[1]=image.new("\028\000\000\000 \000\000\000\000\000\000\0008\000\000\000\016\000\001\000!\004!\004B\008B\008!\004B\008B\008B\008c\008c\008c\008c\008c\008\132\012\133\140\173\136\199\144\198\144\132\140c\008C\008B\008B\008B\008!\004!\004!\004!\004!\004!\004!\004B\008!\004!\004!\004!\004!\004!\004!\004!\004B\008c\012\199\144\188\128-\149\212\132\172\136\132\140B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008!\004!\004!\004!\004!\004!\004B\008B\008c\136\165\144\012\149\190\128W\145\223\128\186\128\165\144B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008B\008!\004!\004!\004!\004B\008c\136\132\140\199\148J\157T\149\223\132\223\128\223\128\014\149\165\140B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008c\140\198\144k\161R\190\214\202\029\170\031\133\255\128\028\137)\153\132\140B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008B\008c\136\198\144\016\182{\2319\223\255\255\223\247\255\210\255\206s\190)\153\132\140B\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008B\136C\136\165\144\173\169{\235{\231\127\231_\182\127\145\158\202\191\243\156\235\173\165\198\148c\136B\136B\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008B\008C\136\165\144)\157s\194\156\235\223\169u\128\184\128\186\128\149\128\127\141\127\1331\178)\153\198\144\132\140C\136B\008!\004!\004!\004!\004!\004B\008B\004B\004B\004B\008c\140\231\148\173\169\025\219\249\144\191\128\158\128\186\128\253\128Z\129t\128_\129Z\223{\235s\198J\161c\140B\008B\008B\008B\008B\008B\008B\008B\136c\140c\140\132\140\133\140\206\181\214\214t\194\028\137\191\132\027\129\156\129\127\1865\1299\129\029\129\025\219\189\243{\235\016\186\165\144\132\140\132\140\132\140\132\140B\008B\008\132\144\198\148\165\144\133\140\165\144\165\144\008\153\140\169\173\161\223\128\191\128\222\129\127\154\222\190Y\170\127\133\253\128s\186\181\202\016\182\140\161\008\149\008\149J\161k\169\198\148C\136B\008c\136\165\144)\157J\161\173\173J\161\008\149\008\149k\157\182\157\155\128\249\128\222\182\221\186\028\134\254\129\152\182\016\174\140\161k\157\206\173s\1989\227\024\223s\202\231\152B\136C\136\165\148)\161\206\181s\198\181\206\214\210\148\202\239\177\206\165\154\174\031\195\031\130\158\146\191\146_\130\159\154[\215R\186\148\194\024\2199\2279\227\148\202\206\173)\161\164\140B\136c\140\165\144\198\148*\161\239\177\247\214\247\2149\2239\219\024\211|\219\191\235\031\139\255\150\222\130\255\130~\203\158\235\214\2069\219\023\211R\190\239\173J\157\231\148\165\140c\136B\008B\008B\136c\136\132\140\231\148\173\173\017\182\214\206Z\2239\223\156\235\223\247_\187\255\129\255\129\031\151\190\239\223\239\247\218{\2319\219\181\2021\182\140\169)\157\230\148\132\140B\008B\008B\004B\008c\136\132\140\230\144k\161\148\194Z\223\024\223[\231\255\251\223\235\255\190\254\194\127\203\222\247|\227\023\211\023\215\247\214\248\218\024\219t\202\173\177k\169\165\144B\008!\004!\004B\008c\140\230\152\008\157\173\1699\223\156\239{\235Y\223\189\243\223\231\191\219\159\227\159\231|\231\181\198\017\170\173\165\173\169\173\173\239\181\206\181)\161\199\152\132\140B\008!\004!\004B\008c\140\231\152)\161\140\169s\202\148\198\181\198\150\182\250\178\127\219_\215\127\227\127\219\218\190\248\2023\166\240\169)\153\231\148\165\144\165\144\132\140c\136B\008B\004!\004!\004B\004B\136\132\144\198\148\166\144\231\148J\153\239\165\029\175>\175\159\166_\219?\207\191\174\253\198\159\223_\187^\199\150\182\008\149\132\140B\136B\008B\008B\008!\004!\004!\004B\008B\008B\136c\140c\136\165\144J\153\029\179\191\227\255\247\157\178\255\186\092\162\253\198\223\247\191\231?\179\191\227\158\227\140\165\165\140B\008!\004!\004!\004!\004!\004!\004!\004!\004B\004B\008\132\140\231\148\017\166_\187_\187\159\207?\187\029\207\220\198\255\247\223\235_\187\031\159\191\227\127\195T\170\231\144C\136!\004!\004!\004!\004!\004!\004!\004!\004B\008B\008\199\148\140\161[\207_\183?\179\127\191_\183\127\203\159\215\159\215_\187_\191\159\223?\203\191\150\187\138\009\145c\136!\004!\004!\004!\004!\004!\004!\004!\004B\008B\136\231\148\241\161_\195\127\219_\215_\207\191\231?\175_\187\127\203_\183\159\231\189\186=\154\159\130\222\134)\149c\140!\004!\004!\004!\004!\004!\004!\004!\004!\004c\136\008\149\154\138\026\130\253\137\188\129\187\129>\146\031\199\031\203\127\223>\207\029\150U\129\029\130\255\138\255\138)\153\132\140!\004!\004!\004!\004!\004!\004!\004!\004!\004\132\140K\153v\129\185\129\153\129\153\129\153\129\153\129\153\129w\129\253\133v\129\183\129\092\130[\130\191\130\255\134)\153\132\140!\004!\004!\004!\004!\004!\004!\004!\004!\004\132\140l\1533\129=\130\223\146]\130^\130^\130\026\130\150\129\026\130\092\130\158\130\223\1344\129\223\138\223\130\009\153c\140!\004!\004!\004!\004!\004!\004!\004!\004!\004\132\140)\153\216\129}\130\031\155\255\134\223\130\223\130\223\134}\130\223\130\255\134\255\134\223\138\220\129\031\167\188\142\231\148c\136!\004!\004!\004!\004!\004!\004!\004!\004!\004c\136\231\1448\134\223\130\223\130\223\130\223\130\223\130~\130\027\130\255\134\255\134\255\134\031\159?\155?\167\021\146\165\144C\136!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008\132\140)\153\154\138\223\130\223\130\223\130\223\130\027\130\185\129\223\130\223\130\255\134\030\167\017\170\142\149\231\144c\140B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008c\136\166\144\242\141\255\130\255\138\255\146\223\138]\130\027\130\223\134\255\134\253\170\215\206k\161\166\144c\136B\008B\008!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008c\136+\137\209\145\155\142\253\166>\183\255\166\127\130\218\166\150\1781\178\207\177\165\144c\136B\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004!\004B\008B\136c\140\165\144L\145J\153\140\153\241\157\173\161k\161)\153\231\144\165\144c\136B\008!\004!\004!\004!\004!\004!\004!\004")

playerSprite=image.new("\020\000\000\000\030\000\000\000\000\000\000\000(\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000J\241\140\241\240\245k\241\008\229\240\245\140\241J\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008E\000\000\174\2451\250k\245)\2331\250\206\245\000\000\008E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\166\160k\241)\237\198\172k\245k\241\198\220\199\164\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\173\205k\241\232\192\240\205J\221J\237\232\192\232\168\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\250\206\245\231\228l\189\016\210\009\181)\2171\250)\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\245\206\249\199\164\140\197*\185*\185)\177*\2292\250\206\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\239\245\215\254\198\168K\189\199\168)\181\198\164\008\177J\249K\237k\241k\241kq\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\250k\253\198\168\207\197*\181\141\193\207\233*\185\198\168\000\000\198\220\198\220\198\092\000\000\000\000\000\000\000\000\000\000\000\000\000\000\231\228\173\229Z\255\140\245k\245\231\228\165\220Z\255\255\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\217\238\241\140\241R\250\140\241k\241\231\228\008\225\248\250;\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000<\235\026\243\255\255\198\220\000\128\000\128\000\128\000\128\000\128\191\247\025\243]\235\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\190\251\024\251\247\246\000\128\255\255\255\255\255\255\255\255\255\255\000\128\247\250\190\251\000\000\000\000\000\000\000\000\000\000\000\000;o\027\235\223\255\223\255\000\128\255\255\255\255\255\255\255\255\255\255\255\255\255\255\000\128\255\255\027\235\000\000\000\000\000\000;o\000\000\027\235\190\251\255\255\250\234\000\128\255\255\255\255\255\255\255\255\255\255\255\255\255\255\000\128\222\251\190\251\027\235\000\000;o\000\000\027\235\223\255\255\255}\247U\222\000\128\255\255\255\255\255\255\255\255\255\255\255\255\255\255\000\128]\239\222\251\223\255\027\235\000\000\216\238\181\250\255\255\158\247;\2393\218\000\128\255\255\255\255\255\255\255\255\255\255\255\255\255\255\000\128\008\225<\235\255\255\181\250\216\238\217\226\024\247\255\255\141\233\150\226U\218\000\128\255\255\255\255\255\255\255\255\255\255\255\255\255\255\000\128k\241\140\225}\247\024\247\217\226\000\000v\218;\239;\239\184\222)\237\173\237\000\128\255\255\255\255\255\255\255\255\255\255\000\128\140\241\165\220S\234;\239;\239\000\000vZ\000\000;\239w\214\008\225\207\245\173\245\239\245\000\128\000\128\000\128\000\128\000\128l\237\198\220\198\220\164\220\151\218\000\000;o\000\000;o\000\000\000\000J\237R\250\173\241J\237J\237)\237J\237J\237J\237J\237J\237\198\220\198\220\198\220\000\000\000\000\000\000\000\000\000\000\000\1402\2501\2502\2501\250\173\241R\250k\241k\241J\237k\241k\241\198\224\198\220\198\220\198\220\000\000\000\000\000\000\000\000\132\216\239\2452\250R\250J\241\173\2452\250\017\250J\241\198\220k\241k\241J\237\198\220\198\220\198\220\000\000\000\000\000\000\000\000J\237\016\2501\250R\250k\241J\2332\2502\250\174\245\198\220k\241k\241k\241\008\229\198\220\198\220\000\000\000\000\000\000\000\000*\233\016\2502\250\173\241k\241J\2332\2502\250\173\241k\241\198\224J\241J\241\174\233\141\221\165\220\000\000\000\000\000\000\000\000\206\233\255\255\017\250\140\245k\241\231\228\240\2492\250\017\250J\241\165\2203\222\216\242)\229\009\221\198\220\000\000\000\000\000\000\000\000\140\241\239\249s\250\157\247k\241\141\225\223\255\017\250Z\255;\243\008\237\165\220\165\220\198\220\000\000\000\000\198\092\000\000\000\000\000\000\165\216)\237\008\229\008\229\008\233\165\224)\233k\237\173\249J\237\008\233\198\220\198\220\198\220\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\198`\000\000\198\168*\185*\185)\181\198\168\198\168\198\168\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\198\168\009\181*\185)\181\198\168\199\168\000\000\199(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\198(\000\000\199\168\199\172\199\172C\152\000\000\198(\000\000\000\000\000\000\000\000\000\000\000\000")

function copyTable(t)
 local t2={}
 for i,e in pairs(t) do
  t2[i]=e
 end
 return t2
end

function init()
 menu=true
 menuOptions={"Back to game",true,"Level 1",true,"Level 2",false,"Level 3",false,"Level 4",false,"Level 5",false,"Level 6",false,"Help",true}
 cursor=1
 level=1
 initLevels()
end

function initLevelVars()
 lives,bombs,dead,invincible=3,3,false,0
 count,bombTime,transitionTime=0,0,0
 xPlayer,yPlayer=160,183
 wave=1
 bossPhase=0
 enemies=copyTable(levelEnemies[level][1])
 explosion=false
 explosionRay,explosionMaxRay=0,0
 explosionX,explosionY=0,0
 xBoss,yBoss=levelBoss[level][3],levelBoss[level][4]
 bossHP=levelBoss[level][1]
 maxBullets=copyTable(levelEnemiesMaxBullets[level])
 bossFireRate=copyTable(levelBossFireRate[level][1])
 initBullets()
end

function initLevels()
 levelBoss,levelBossMaxBullets,levelEnemiesMaxBullets,levelBackground,levelBossFireRate,levelEnemies={},{},{},{},{},{}
 levelEnemyFireRate={5}
 levelEnemiesMaxBullets={{50,50,0,0,0}}
 levelEnemies[1]={{1,15,-10,1,60,-10,1,120,-10},{1,295,-10,1,250,-10,1,200,-10},{2,160,-30,4,80,-30,4,240,-30},{1,30,-10,1,30,-40,1,30,-70,1,30,-100,1,30,-130},{1,290,-10,1,290,-40,1,290,-70,1,290,-100,1,290,-130},{4,160,-10,4,80,-10,4,240,-10,1,120,-10,1,120,-40,1,120,-70,1,200,-10,1,200,-40,1,200,-70}}
 levelBackground[1]={0,0,0}
 levelBoss[1]={100,2,160,90,{100,60,30}}
 levelBossMaxBullets[1]={{25,25,25,25,0},{0,0,0,0,20},{0,0,10,50,0}}
 levelBossFireRate[1]={{1,1,1,1,1},{20,10,10,10,1},{0,0,1,1,0}}
end

function initBullets()
 x,y,cx,cy,px,py={},{},{},{},{},{}
 for i=1,10 do px[i],py[i]=0,-10 end
 for j=1,5 do
  x[j],y[j]={},{}
  cx[j],cy[j]={},{}
  for i=1,50 do
   x[j][i],y[j][i]=-10,-10
   cx[j][i],cy[j][i]=0,0
  end
 end
 bulletsSize={2,3,5,7,10}
 bulletsSpeed={5,3,3,2,1}
 bulletsColor={{255,255,0},{255,0,0},{0,255,0},{150,150,255},{255,255,255}}
end

--Bosses and enemies fires
bossFire,enemyFire={},{}

bossFire[1]={}
bossFire[1][1]=function(type,index)
  local angle=math.random(0,628)/100
  x[type][index],y[type][index]=xBoss,yBoss
  cx[type][index],cy[type][index]=math.cos(angle)*5,math.sin(angle)*5
end

bossFire[1][2]=function(type,index)
  x[type][index],y[type][index]=xBoss,yBoss
  local dist=math.sqrt((xPlayer-xBoss)*(xPlayer-xBoss)+(yPlayer-yBoss)*(yPlayer-yBoss))
  cx[type][index],cy[type][index]=(xBoss-xPlayer)/dist*math.random(-5,-2)+math.random(-10,10)/7,(yBoss-yPlayer)/dist*math.random(-5,-2)+math.random(-10,10)/7
end

bossFire[1][3]=function(type,index)
 if type==4 then
  local r=math.random(0,200)/100
  if count%40==0 or count%40==20 then
   local k=count%40+5
   for i=1+k,25+k do
    x[4][i],y[4][i],cx[4][i],cy[4][i]=xBoss,yBoss,math.cos(i*6.28/25+r)*8,math.sin(i*6.28/25+r)*8
   end
  if index>=1+k and index<=25+k then x[4][index],y[4][index]=x[4][index]+cx[4][index],y[4][index]+cy[4][index] end
  end
 elseif type==3 and count%6==0 then
  x[type][index],y[type][index]=xBoss,yBoss
  local dist=math.sqrt((xPlayer-xBoss)*(xPlayer-xBoss)+(yPlayer-yBoss)*(yPlayer-yBoss))
  cx[3][index],cy[3][index]=(xBoss-xPlayer)/dist*-5,(yBoss-yPlayer)/dist*-5
 end
end

enemyFire[1]=function(enemy,type,index)
 if type==1 and (count+enemy)%levelEnemyFireRate[level]==0 and enemies[enemy*3]>5 and enemies[enemy*3]<200 then
  local xe,ye=enemies[enemy*3-1],enemies[enemy*3]
  x[type][index],y[type][index]=xe,ye
  local dist=math.sqrt((xPlayer-xe)*(xPlayer-xe)+(yPlayer-ye)*(yPlayer-ye))
  cx[type][index],cy[type][index]=(xPlayer-xe)/dist*5,(yPlayer-ye)/dist*5
 end
end

enemyFire[2]=enemyFire[1]

enemyFire[4]=function(enemy,type,index)
 if type==2 and count%50<30 and enemies[enemy*3]>29 and enemies[enemy*3]<200 then
  x[type][index],y[type][index]=enemies[enemy*3-1],enemies[enemy*3]
  local angle=4.71+(count%3-1)*0.8
  cx[type][index],cy[type][index]=math.cos(angle)*-6,math.sin(angle)*-6
 end
end

function updateBullets()
 for j=1,5 do
  local checkedEnemies=0
  local size=bombTime==0 and bulletsSize[j] or bulletsSize[j]+10+bombTime*2.5
  local bulletsFired=0
  for i=1,maxBullets[j] do
   local bx,by=x[j][i],y[j][i]
   if bx>-10 and bx<330 and by>-10 and by<220 then
    if (xPlayer-bx)*(xPlayer-bx)+(yPlayer-by)*(yPlayer-by)<size*size+25 then
     if bombTime==0 then looseLife() end
     x[j][i],y[j][i]=-10,-10
    else
     x[j][i],y[j][i]=bx+cx[j][i],by+cy[j][i]
    end
   elseif bossPhase==0 then
    if checkedEnemies<#enemies/3 then
     checkedEnemies=checkedEnemies+1
     enemyFire[enemies[checkedEnemies*3-2]](checkedEnemies,j,i)
    end
   elseif bossPhase>0 and bulletsFired<bossFireRate[j]  and bossHP>0  and transitionTime==0 then
    bulletsFired=bulletsFired+1
    bossFire[level][bossPhase](j,i)
   end
  end
 end
end

function updatePlayerBullets()
 local fired=false
 for i=1,10 do
  if py[i]>-5 then
   py[i]=py[i]-8
   if bossPhase>0 then
    if math.abs(px[i]-xBoss)<10 and math.abs(py[i]-yBoss)<20 and bossHP>0 then
     hitBoss()
     py[i]=-10
    end
   elseif bossPhase==0 then
    for e=1,#enemies/3 do
     if math.abs(px[i]-enemies[e*3-1])<10 and math.abs(py[i]-enemies[e*3])<10 and py[i]>=0 then
      enemies[e*3]=300
      py[i]=-10
     end
    end
   end
  elseif count%3==0 and not fired and not dead and bossHP>0 then
   px[i],py[i]=xPlayer,yPlayer-5
   fired=true
  end
 end
end

function drawBullets(gc)
 for j=1,5 do
  local size=bulletsSize[j]
  gc:setColorRGB(unpack(bulletsColor[j]))
  for i=1,maxBullets[j] do
   local bx,by=x[j][i],y[j][i]
   if bx>-10 and bx<330 and by>-10 and by<220 then
    gc:fillArc(bx-size,by-size,size*2,size*2,0,360)
   end
  end
 end
end

function drawPlayerBullets(gc)
 gc:setColorRGB(200,0,255)
 for i=1,10 do
  if py[i]>-5 then
   gc:fillRect(px[i]-1,py[i]-8,3,10)
   gc:fillRect(px[i]-5,py[i]-5,3,10)
   gc:fillRect(px[i]+3,py[i]-5,3,10)
  end
 end
end

function updateBoss()
 if bossHP>0 and bossPhase>0 and bossPhase<#levelBoss[level][5] then
  if bossHP<=levelBoss[level][5][bossPhase+1] then
   bossPhase=bossPhase+1
    maxBullets=copyTable(levelBossMaxBullets[level][bossPhase])
    bossFireRate=copyTable(levelBossFireRate[level][bossPhase])
   transitionTime=15
   initBullets()
  end
 end
end

function hitBoss()
 if bossHP>1 and not dead and transitionTime==0 then
  bossHP=bossHP-1
 elseif bossHP>0 and not dead and transitionTime==0 then
  bossHP=0
  explosion=true
  explosionRay=5
  explosionX,explosionY=xBoss,yBoss
  explosionMaxRay=200
 end
end

function looseLife()
 if invincible==0 and bossHP>0 then
  explosion,dead=true,true
  invincible=30
  lives=lives-1
  bombs=3
  explosionRay=5
  explosionX,explosionY=xPlayer,yPlayer
  explosionMaxRay=35
 end
end

function updateEnemies()
 if bossPhase==0 then
  local aliveEnemies=false
  for i=1,#enemies/3 do
   if enemies[i*3]<220 then
    aliveEnemies=true
    if enemies[i*3-2]%2==1 or enemies[i*3]<30 then enemies[i*3]=enemies[i*3]+2 end
   end
  end
  if not aliveEnemies then
   wave=wave+1
   if wave>#levelEnemies[level] then
    bossPhase=1
     maxBullets=copyTable(levelBossMaxBullets[level][1])
    bossFireRate=copyTable(levelBossFireRate[level][1])
    transitionTime=15
    initBullets()
   else
   enemies=copyTable(levelEnemies[level][wave])
   end
  end
 end
end

function nextLevel()
 wave=1
 bossPhase=0
 enemies=copyTable(levelEnemies[level][1])
 maxBullets=copyTable(levelEnemiesMaxBullets[level])
 bossFireRate=copyTable(levelBossFireRate[level][1])
 initBullets()
end

function drawExplosion(gc)
 gc:setColorRGB(255,255,255)
 if explosionRay<explosionMaxRay then
  explosionRay=explosionRay+4
  gc:drawArc(explosionX-explosionRay,explosionY-explosionRay,explosionRay*2,explosionRay*2,0,360)
 else
  explosion=false
  initBullets()
  if dead then
   dead=false
   xPlayer,yPlayer=160,180
  end
 end
end

function drawPanel(gc)
 gc:setColorRGB(200,200,200)
 gc:setFont("sansserif","r",10)
 local str1,str2="Lives : "..string.rep("o",lives),"Bombs : "..string.rep("o",bombs)
 gc:drawString(str1,315-gc:getStringWidth(str1),5,"top")
 gc:drawString(str2,315-gc:getStringWidth(str2),20,"top")
 if bossPhase>0 then
  gc:fillRect(2,2,bossHP*2,3)
  for i,e in pairs(levelBoss[level][5]) do
   if bossHP>e then gc:fillRect(e*2+2,1,1,5) end
  end
 end
 if bossHP==0 and lives>0 and not explosion then
  gc:setColorRGB(255,255,255)
  gc:setFont("sansserif","b",12)
  gc:drawString("Clear",30,30,"top")
  gc:setFont("sansserif","r",12)
  gc:drawString("Press enter to go to level "..tostring(level+1),30,60,"top")
 end
end

function drawPentacle(gc,x,y,s)
 gc:drawArc(x,y,s,s,0,360)
 gc:drawArc(x+s/20,y+s/20,s-s/10,s-s/10,0,360)
 local tx,ty={2.31*s/4+x,1.19*s/4+x,1.2*s/4+x,2.32*s/4+x,3*s/4+x},{2.95*s/4+y,2.58*s/4+y,1.4*s/4+y,1.05*s/4+y,2.02*s/4+y}
 for i=1,5 do
  gc:drawArc(tx[i]-s/4,ty[i]-s/4,s/2,s/2,0,360)
 end
end

function drawBomb(gc)
 if bombTime>0 then
  gc:setColorRGB(200,0,255)
  local size=20+bombTime*5
  drawPentacle(gc,xPlayer-size/2,yPlayer-size/2,size)
 end
end

function drawEnemies(gc)
 if bossPhase==0 then
  gc:setColorRGB(150,150,150)
  for i=1,#enemies/3 do
   if enemies[i*3]>-5 and enemies[i*3]<220 then
    gc:drawImage(enemySprite[enemies[i*3-2]%2+1],enemies[i*3-1]-8,enemies[i*3]-9)
   end
  end
 end
end

function drawTransition(gc)
 if transitionTime>0 then
  local size=(16-transitionTime)*10+10
  gc:setColorRGB(255,255,255)
  drawPentacle(gc,xBoss-size/2,yBoss-size/2,size)
 end
end

init()


function drawGame(gc)
 gc:setColorRGB(unpack(levelBackground[level]))
 gc:fillRect(0,0,320,240)
 updateBoss()
 updateBullets()
 updateEnemies()
 updatePlayerBullets()
 drawPlayerBullets(gc)
 drawTransition(gc)
 drawBomb(gc)
 if explosion then
  drawExplosion(gc)
 end
 if not dead and invincible%2==0 then
  gc:drawImage(playerSprite,xPlayer-10,yPlayer-15)
 end
 drawBullets(gc)
 drawEnemies(gc)
 if bossHP>0 and bossPhase>0 then gc:drawImage(bossSprite[level],xBoss-14,yBoss-16) end
 drawPanel(gc)
 timer.start(0.08)
end

function drawMenu(gc)
 menuOptions[2]=(lives and lives~=0)
 gc:setFont("sansserif","b",12)
 gc:setColorRGB(0,0,0)
 gc:fillRect(0,0,320,240)
 gc:setColorRGB(200,0,255)
 drawPentacle(gc,-60,-60,360)
 gc:drawLine(35,cursor*20+15,gc:getStringWidth(menuOptions[cursor*2-1])+35,cursor*20+15)
 gc:drawLine(35,cursor*20+15+1,gc:getStringWidth(menuOptions[cursor*2-1])+35,cursor*20+15+1)
 for i=1,#menuOptions/2 do
  if menuOptions[i*2] then
   gc:setColorRGB(250,250,250)
  else
   gc:setColorRGB(100,100,100)
  end
  gc:drawString(menuOptions[i*2-1],35,i*20+13,"baseline")
 end
 if cursor==8 then
  local help={"You can control the red","character on the bottom","of the screen with the","arrows (or 8,4,2,6)","You start with 3 lives.","When you get hit, you","loose a life, so be careful !","You have 3 bombs per","live. When you press tab,","they make you invincible","for a few seconds. Use","them wisely."}
  gc:setFont("sansserif","r",10)
  gc:setColorRGB(255,255,255)
  for i,e in pairs(help) do
   gc:drawString(e,160,17*i-10,"top")
  end
 end
end

function drawGameOver(gc)
 cursor=cursor>2 and 1 or cursor
 gc:setColorRGB(0,0,0)
 gc:fillRect(0,0,320,240)
 gc:setColorRGB(200,0,255)
 gc:setFont("sansserif","b",12)
 drawPentacle(gc,-60,-60,360)
 gc:fillRect(cursor==1 and 30 or gc:getStringWidth("Yes       ")+30,152,cursor==1 and gc:getStringWidth("Yes") or gc:getStringWidth("No"),2)
 gc:setColorRGB(255,255,255)
 gc:drawString("Game over",30,50,"top")
 gc:drawString("Try again ?",30,90,"top")
 gc:drawString("Yes       No",30,150,"baseline")
end

function on.paint(gc)
 if menu then
  drawMenu(gc)
 elseif lives>0 or explosion then
  drawGame(gc)
 else
  drawGameOver(gc)
 end
 gc:setColorRGB(75,75,75)
 gc:setFont("sansserif","r",8)
 gc:drawString("Lua Danmaku - By Loic Pujet",10,200,"top")
end

function on.timer()
 timer.stop()
 if not menu then
  count=count+1
  if invincible>0 then invincible=invincible-1 end
  if bombTime>0 then bombTime=bombTime-1 end
  if transitionTime>0 then transitionTime=transitionTime-1 end
  platform.window:invalidate()
 end
end

function on.arrowKey(a)
 if menu then
  cursor=a=="up" and cursor-1 or cursor
  cursor=a=="down" and cursor+1 or cursor
  cursor=(cursor-1)%(#menuOptions/2)+1
  platform.window:invalidate()
 elseif lives>0 then
  xPlayer=(a=="right" and xPlayer<305) and xPlayer+8 or xPlayer
  xPlayer=(a=="left"  and xPlayer>8) and xPlayer-8 or xPlayer
  yPlayer=(a=="down" and yPlayer<200)  and yPlayer+8 or yPlayer
  yPlayer=(a=="up"and yPlayer>5) and yPlayer-8 or yPlayer
 else
  cursor=cursor==1 and 2 or 1
  platform.window:invalidate()
 end
end

function on.tabKey()
 if bombTime==0 and bossHP>0 and bombs>0 and not dead and not menu then
  bombs=bombs-1
  bombTime=20
 end
end

function on.enterKey()
 if menu and menuOptions[cursor*2] then
  if cursor==1 and lives~=0 and lives then
   menu=false
   platform.window:invalidate()
  elseif cursor>=2 and cursor<=7 then
   level=cursor-1
   menu=false
   cursor=1
   initLevelVars()
   platform.window:invalidate()
  end
 elseif not menu and lives<=0 and not explosion then
  if cursor==1 then initLevelVars() else menu=true end
  platform.window:invalidate()
 elseif not menu and lives>0 and bossHP==0 then
  if level+1<=#levelBackground then
   nextLevel()
  else
   menu=true
  end
  platform.window:invalidate()
 end
end

function on.escapeKey()
 if not menu then
  menu=true
  cursor=1
  platform.window:invalidate()
 end
end

function on.charIn(c)
 if c=="8" then on.arrowKey("up") end
 if c=="6" then on.arrowKey("right") end
 if c=="4" then on.arrowKey("left") end
 if c=="2" then on.arrowKey("down") end
end

2
Other Calculators / Gravity Guy
« on: April 30, 2012, 12:11:49 am »
Gravity Guy



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=790

A clone of the famous computer/phone game.
You have the power to inverse gravity (whith tab/enter) and your goal is to finish 50 challenging levels... (There is also a random mode to play infinite runs)
I you manage to finish them all, you will unlock bonus levels...

Screenshots :



(Thanks to Jonius7 for the moving screenshot. The actual game is slower)

3
TI-Nspire / nCraft (3D minecraft-like game for the nspire)
« on: February 28, 2012, 02:43:10 pm »
Hello,

Since I like 3D, I wanted to try it with ndless.
After a couple experiments, I got spinning cubes... Yeah :P

At first, I wanted to try a minecraft-like game, but it's waaay too slow.
I'll try to do some optimizations, but I don't hope too much. Sorry.

The source is attached with a screenie.

4
TI-Nspire / [Lua] Gravity guy
« on: December 15, 2011, 03:47:57 pm »
FINAL UPDATE : 14/04/2012
Spoiler For Spoiler:
Download




Moving screenshot (thanks to Jonius7). The actual game is slower...


Hi there !

Sorry if I may seem inactive, but I am in a 'non-motivation' period.
But I'm not dead (even if I only program 2 hours a week).
So my latest project is a Gravity Guy clone. It is quite fast (and really blurry on grayscale nspires)

Some screenies are attached to my post.

Note that I will change the player sprite.
And, by the way, I used linear gravity (like the original game). Should I use more realistic calculations ?

5
Other Calculators / CubeField
« on: December 07, 2011, 03:54:39 pm »
CubeField



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=734

This is a game inspired by CubeRunner (for smartphones), written in Lua (OS>3)
Survive as long as you can without getting hit by the cubes!    
Every 1000 points, a corridor appears to introduce the next level, where the speed icreases.


6
Other Calculators / CubeField
« on: November 02, 2011, 09:42:43 pm »
CubeField



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=734

This is a game inspired by CubeRunner (for smartphones), written in Lua (OS>3)
Survive as long as you can without getting hit by the cubes!    
Every 1000 points, a corridor appears to introduce the next level, where the speed icreases.


7
Other Calculators / FreeCell
« on: November 02, 2011, 09:42:43 pm »
FreeCell



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=735

This is a FreeCell clone for your nspire, written in lua. (OS>3)
More info on FreeCell's rules here : http://www.freecell.org/rules.html


8
Other Calculators / Minesweeper
« on: November 02, 2011, 09:42:43 pm »
Minesweeper



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=736

A minesweeper clone written in Lua for your TI-Nspire (OS>3)
For more information about minesweeper's rules, click here : http://en.wikipedia.org/wiki/Minesweeper_%28video_game%29


9
Other Calculators / Mazes 3D
« on: November 02, 2011, 09:42:01 pm »
Mazes 3D



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=737

A 3D maze game for your TI-Nspire, written in Lua (OS>3)
Find the white gate to escape from the maze where you're stuck.

(Billions of mazes can be generated)


10
Introduce Yourself! / I just noticed I never intoduced myself !
« on: October 24, 2011, 02:03:58 pm »
... So I never got peanuts.
That's so sad :(

Let's fix that !

My name is Loïc Pujet, and I've chosen 'Chockosta' as my nick, because I love chocolate.

I'm now 16, and I started programming at 14, in C.
When I went to high school, I bought a TI-83+ BE. And I fell in love with that thing. I learnt TI-Basic, then Axe.

But later, I saw the new nSpire calculators. I decided to get one, and I bought a clickpad non-CAS on eBay (50€ !)
I started to program in C, I created a periodic table and 3 games.
When Lua came, I fell in love once again. And I thought that it would be better to share my projects, so I signed up on Omni. That's why I'm here.

And I hope I'll stay here a long time !

11
TI-Nspire / [Lua] CubeField
« on: October 18, 2011, 12:22:19 pm »
Hello !

I hate school, I don't have enough free time to work on my games. (Yeah, I have a lot of simultaneous game projects)
But I managed to get a playable CubeField clone...

So basically you just have to avoid cubes :P
When you reach 1000, 2000, 3000... points, the speed increases and the colors change.
The 3D projection is not really realistic, I'll have to work on it.
And I also have to add a nice sprite for the player's ship.

But you still can have fun with this... (My highscore is 5600 points ! Can you beat it ?)



DOWNLOAD FINAL VERSION (modified 11/1/2011) (re-modified 11/27/2011)


_________________
EDIT : 10/19/2011


Animated screenshot (thanks to Jonius7)
Spoiler For Spoiler:

_________________
EDIT : 23/10/2011

-Now when you turn, the cubes become diagonal.
-The bug which caused some blocks that are farther to appear on top of the closer ones is fixed.
-Before the speed increases, a "Speed Up!" sign appears.
-Between 2 "levels", there is a corridor made of cubes.

_________________
EDIT : 23/10/2011

FINAL VERSION !

-There is a nice sprite for the player
-The corridor is more regular

Screenshots :
Spoiler For Spoiler:

_________________
EDIT : 10/19/2011

New final version :P
The 3D projection is now more realistic.
A little bugfix

Screenie :


_________________
EDIT : 10/19/2011

Yet another final version

Now the speed of the cubes automatically adapts to the framerate.
So the speed is the same on CX, clickpad, or computer software.

Color screenie :


Code :
Spoiler For Spoiler:
Code: [Select]
playerImg=image.new("\020\000\000\000\020\000\000\000\000\000\000\000(\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\128\000\128\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\128\000\128")

cubesX={1,5,7,6,4,6,4,1,3,2,3,7,8,9,1,2,3,4,2,6,7,1,9,1,2,3,4}
cubesY={1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9}
lastCube=1
player=0
speed=0.08
moving=false
dir=1
moveStart=0
menu=true
score=0
level=1
color={225,170,0}
rotation=0
lastTick=0
delay=0

function render(gc)
 drawHorizon(gc)
 local size,x,y,i,polygon
 for j=1,27 do
  i=(j+lastCube-2)%27+1
  size=100/(10-cubesY[i])
  x=(cubesX[i]-7-player)/(10-cubesY[i])*150-size/2
  y=5/(10-cubesY[i])*50-180
  polygon=rotate({x,y,x+size,y,x+size,y+size,x,y+size,x,y})
  if cubesY[i]>1 then
   gc:setColorRGB(color[1],color[2],color[3])
   gc:fillPolygon(polygon)
   gc:setColorRGB(0,0,0)
   gc:drawPolyLine(polygon)
  end
  if y+size>3 and y<17 then
   if x<6 and x+size>-6 then
    menu=true
    score=math.floor(score)
   end
  end
 end
end

function rotate(p)
 local s,c=math.sin(rotation),math.cos(rotation)
 return {p[1]*c-p[2]*s+159,p[1]*s+p[2]*c+202,p[3]*c-p[4]*s+159,p[3]*s+p[4]*c+202,p[5]*c-p[6]*s+159,p[5]*s+p[6]*c+202,p[7]*c-p[8]*s+159,p[7]*s+p[8]*c+202,p[9]*c-p[10]*s+159,p[9]*s+p[10]*c+202}
end

function updateCubes()
 local step=menu and 0.06 or speed
 for i=1,27 do
  cubesY[i]=cubesY[i]+step*delay/30
  if cubesY[i]>10 then
   if score%1000<800 then
    cubesX[i]=math.random(0,140)/10+player
   else
    cubesX[i]=math.random(0,140)/200+player+(i-1)%2*5+4.1
   end
   cubesY[i]=cubesY[i]-9
   lastCube=lastCube==1 and 27 or lastCube-1
  end
 end
end

function updateMove()
 if moving then
  player=player+0.07*dir*delay/30
  if math.abs(rotation)<0.15 or dir==rotation/math.abs(rotation) then
   rotation=rotation-0.005*dir*delay/30
  end
  if timer.getMilliSecCounter()-moveStart>=150 then
   moving=false
  end
 else
  if math.abs(rotation)>0.005 then
   rotation=rotation-0.005*rotation/math.abs(rotation)*delay/30
  end
 end
end

function drawPlayer(gc)
 if not menu then
  gc:drawImage(playerImg,149,192)
 end
end

function drawHorizon(gc)
 local s,c=math.sin(rotation),math.cos(rotation)
 gc:setColorRGB(0,0,0)
 gc:drawLine(s*142-c*200+159,202-c*142-s*200,c*200+s*142+159,s*200-c*142+202)
end

function drawMenu(gc)
 if menu then
  gc:setColorRGB(0,0,0)
  gc:setFont("sansserif","r",30)
  gc:drawString("CubeField",80,10,"top")
  gc:setFont("sansserif","b",12)
  gc:drawString("Press Enter",115,150,"top")
  local highscore=var.recall("highscore")
  if not highscore then
   var.store("highscore",0)
   highscore=0
  end
  if score>highscore then
   var.store("highscore",score)
   document.markChanged()
  end
  local str="Score : "..tostring(score).."              Highscore : "..tostring(highscore)
  gc:drawString(str,159-gc:getStringWidth(str)/2,100,"top")
 end
end

function drawScore(gc)
 if not menu then
  gc:setColorRGB(0,0,0)
  gc:setFont("sansserif","r",12)
  gc:drawString(tostring(math.floor(score)),2,0,"top")
  if score%1000>950 then
   gc:setFont("sansserif","r",30)
   gc:drawString("Speed Up !",80,10,"top")
  end
 end
end

function levelUp()
 speed=speed+0.02
 level=level+1
 if (level-1)%5==0 then
  color={225,170,0}
 elseif (level-1)%5==1 then
  color={0,0,255}
 elseif (level-1)%5==2 then
  color={100,100,100}
 elseif (level-1)%5==3 then
  color={90,255,0}
 elseif (level-1)%5==4 then
  color={255,255,255}
 end
end

function on.paint(gc)
 render(gc)
 drawPlayer(gc)
 drawMenu(gc)
 drawScore(gc)
 gc:setColorRGB(0,0,0)
 gc:setFont("sansserif","r",8)
 gc:drawString("Lua CubeField - Par Loic Pujet",10,200,"top")
 updateFPS()
 timer.start(0.01)
end

function on.timer()
 timer.stop()
 updateCubes()
 updateMove()
 if not menu then
  score=score+delay/30
  if score>level*1000 then
   levelUp()
  end
 end
 platform.window:invalidate()
end

function on.enterKey()
 if menu then
  menu=false
  speed=0.08
  moving=false
  score=0
  level=1
  color={225,170,0}
  for i=1,27 do
   cubesY[i]=cubesY[i]-5
  end
 end
end

function on.arrowLeft()
 if not menu then
  dir=-1
  moving=true
  moveStart=timer.getMilliSecCounter()
 end
end

function on.arrowRight()
 if not menu then
  dir=1
  moving=true
  moveStart=timer.getMilliSecCounter()
 end
end

function on.charIn(ch)
 if ch=="6" then
  on.arrowRight()
 elseif ch=="4" then
  on.arrowLeft()
 end
end

function updateFPS()
 delay=timer.getMilliSecCounter()-lastTick
 delay=delay<300 and delay or 0
 lastTick=timer.getMilliSecCounter()
end

12
TI-Nspire / [Lua] Tiny3D
« on: September 24, 2011, 09:01:10 am »
Hello guys !

I haven't done anything for two weeks, because of my homework :(
But I have a new project ! This is a small 3D engine.
I know that there is already Make3D by Levak, which is amazing, but I have to train with 3D. Moreover, mine is supposed to be a game engine, because it is very small. (I don't know if Lua is fast enough to use it)

So if anyone's interested, I post my engine...
I also add screenshots of a little 3D viewer made with that engine.
For now, it only draw vertices and edges. I'll try to add triangles...

________________________________________________________________________________

EDIT

10/01/2011 : The engine is finished...
New code :
Spoiler For Spoiler:
Code: [Select]
--Lua Tiny3D - By Loic Pujet

function multiplyMatrix(matrix,vector)
 local x=matrix[1][1]*vector[1]+matrix[1][2]*vector[2]+matrix[1][3]*vector[3]
 local y=matrix[2][1]*vector[1]+matrix[2][2]*vector[2]+matrix[2][3]*vector[3]
 local z=matrix[3][1]*vector[1]+matrix[3][2]*vector[2]+matrix[3][3]*vector[3]
 return x,y,z
end

function width() return platform.window:width() end
function height() return platform.window:height() end

function reverseTable(tbl)
 local tbl2={}
 for i,e in ipairs(tbl) do
  tbl2[#tbl-i+1]=e
 end
 return tbl2
end

function replaceFaces(tbl1,tbl2,faces)
 local faces2,count={},1
 for i,e in pairs(tbl1) do
  for j,e2 in pairs(tbl2) do
   if e2 then
    if e==e2 then
     faces2[count]=faces[j]
     count=count+1
     tbl2[j]=nil
    end
   end
  end
 end
 return reverseTable(faces2)
end

function sortFaces(vertices,faces,offset)
 local faces2,distTbl,facesTbl={},{},{}
 local middle={}
 local dist,xsum,ysum,zsum=0,0,0,0
 for i,e in pairs(faces) do
  xsum,ysum,zsum=0,0,0,0
  for j,e2 in pairs(e) do
   xsum,ysum,zsum=xsum+vertices[e2][1],ysum+vertices[e2][2],zsum+vertices[e2][3]
  end
  middle={xsum/#e,ysum/#e+offset,zsum/#e}
   dist=middle[1]*middle[1]+middle[2]*middle[2]+middle[3]*middle[3]
  distTbl[i]=dist
  facesTbl[i]=dist
 end
 table.sort(distTbl)
 return replaceFaces(distTbl,facesTbl,faces)
end

function chooseColor(gc,vertices,face,color)
 if #face<3 then
  gc:setColorRGB(color[1],color[2],color[3])
 else
  local a,b,c=vertices[face[1]][1]-vertices[face[2]][1],vertices[face[1]][2]-vertices[face[2]][2],vertices[face[1]][3]-vertices[face[2]][3]
  local d,e,f=vertices[face[1]][1]-vertices[face[3]][1],vertices[face[1]][2]-vertices[face[3]][2],vertices[face[1]][3]-vertices[face[3]][3]
  local normale={math.abs(b*f-c*e),math.abs(c*d-a*f),math.abs(a*e-b*d)}
  local angle=math.atan(math.sqrt(normale[1]*normale[1]+normale[3]*normale[3])/normale[2])
  local R,G,B=color[1]+angle*-60+50,color[2]+angle*-60+50,color[3]+angle*-60+50
  R,G,B=R>255 and 255 or R,G>255 and 255 or G,B>255 and 255 or B
  R,G,B=R<0 and 0 or R,G<0 and 0 or G,B<0 and 0 or B
  gc:setColorRGB(R,G,B)
 end
end

function renderFaces(gc,vertices,faces,pos,mode,color,offset)
 local polygon,size,faces2={},0,{}
 if mode==4 or mode==5 or mode==6 then
  faces2=sortFaces(vertices,faces,offset)
 else
  faces2=faces
 end
 for i,e in pairs(faces2) do
  polygon,size={},0
  drawPoly=true
  for j,f in pairs(faces2[i]) do
   if not pos[f] then
    drawPoly=false
   else
    polygon[j*2-1]=pos[f][1]
    polygon[j*2]=pos[f][2]
    size=size+2
   end
  end
  if drawPoly then
   polygon[size+1]=pos[faces2[i][1]][1]
   polygon[size+2]=pos[faces2[i][1]][2]
   if mode==4 then
    gc:setColorRGB(color[1],color[2],color[3])
    gc:fillPolygon(polygon)
   elseif mode==5 or mode==6 then
    chooseColor(gc,vertices,e,color)
    gc:fillPolygon(polygon)
   end
   if mode==2 or mode==3 or mode==4 or mode==5 then
    gc:setColorRGB(0,0,0)
    gc:setPen("thin","smooth")
    gc:drawPolyLine(polygon)
   end
  end
 end
end

function renderVertices(gc,pos)
 gc:setColorRGB(0,0,0)
 for i,e in pairs(pos) do
  if e then
   gc:fillRect(e[1]-1,e[2]-1,3,3)
  end
 end
end

----------------------------------------------------------------------------

function rotate(vertices,angle,x,y,z)
 local sum=x+y+z
 x,y,z=x/sum,y/sum,z/sum
 local c,s=math.cos(angle),math.sin(angle)
 local matrix={{x*x+(1-x*x)*c,x*y*(1-c)-z*s,x*z*(1-c)+y*s},{x*y*(1-c)+z*s,y*y+(1-y*y)*c,y*z*(1-c)-x*s},{x*z*(1-c)-y*s,y*z*(1-c)+x*s,z*z+(1-z*z)*c}}
 for i,e in pairs(vertices) do
  vertices[i]={multiplyMatrix(matrix,e)}
 end
end

function translate(vertices,x,y,z)
 for i,e in pairs(vertices) do
  vertices[i]={e[1]+x,e[2]+y,e[3]+z}
 end
end

function scale(vertices,x,y,z)
 for i,e in pairs(vertices) do
  vertices[i]={e[1]*x,e[2]*y,e[3]*z}
 end
end

function render(gc,vertices,faces,mode,color,offset)
 local yDist,pos=0,{}
 for i,e in pairs(vertices) do
  if e[2]>-offset then
   yDist=offset/(e[2]+offset)
   pos[i]={e[1]*yDist*25+width()/2,height()/2-e[3]*yDist*25}
  else
   pos[i]=false
  end
 end
 if mode==1 or mode==2 then
  renderVertices(gc,pos)
 end
 if #faces>0 and (mode==2 or mode==3 or mode==4 or mode==5 or mode==6) then
  renderFaces(gc,vertices,faces,pos,mode,color,offset)
 end
end

----------------------------------------------------------------------------
New screenshots :

13
TI-Nspire / [Lua] Image Editor
« on: August 06, 2011, 12:38:27 pm »
Hello everybody !

Spoiler For Old first post:
A while ago, p2 sent me this PM :
Quote from: p2
can you please try to make a drawing-program for the NI NSPIRE CX CAS?

So I tried that.

It already features :
-Opening and saving ti.images
-Zoom in and zoom out
-A nice color selecting window
-Error messages
-Transparency support

And it will feature :
-Creating blanks images Done
-Pixel-per-pixel drawing Done
-Lines, squares and circles drawing Done
-Text
-Opening and saving BMP files (maybe)

The script is almost 500 lines long.
To open an image, it has to be saved in a string in a "Calculator" application.
I had to rewrite TI.images loading and displaying, because in Lua, "\000" can't be saved in a string. Thanks to Inspired Lua for this page !
It was supposed to be called Paintbrush, but Google told me that a MacOS software is already called "Paintbrush". Do you have any suggestions ?

EDIT 08/07/2011 : Now you can fill and erase pixels.

EDIT 30/10/2011 : To see the last version, go HERE


The last version is nSpaint 0.7. It features :


-Two editors : nSpaint for images and nAnima for animations
-A lot of tools : scroll, draw, erase, fill, pick, circle, line, rectangle, fill circle, fill rectangle.
-A native-like GUI (in nAnima too)
-Save, open or create images of any dimensions
-Transparency support
-A file manager, which can be used to delete images (in nAnima too)
-A tool to copy the current image code to the clipboard (really useful to Lua developpers!)
-A tool to paste an image if there's one in the clipboard
-Undo and redo! (5 times max)
-A option to erase all the image
-A nice color selecter
-Tools to flip/rotate the image
-A filter which replace a color with another one
-A filter which erases a color
-Two filters to increase and decrease brightness
-A 'help' window for each tool
-A splash screen (in nAnima too)
-You can move the cursor with the mouse
-The image is automatically moved when the cursor goes off the screen
-The cursor is moved when you scroll

DOWNLOAD

Screenies:


(The attached screenies are old ones)

14
Other Calculators / Bobby Carrot
« on: July 15, 2011, 06:24:50 pm »
Bobby Carrot



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=693

In this puzzle game, you have to help Bobby, the rabbit, to eat all the carrots... But be careful,    because there are lots of traps! Spikes, rotating ways, mazes...


15
Other Calculators / Snake Lua
« on: July 15, 2011, 06:24:49 pm »
Snake Lua



http://www.omnimaga.org/index.php?action=downloads;sa=view;down=694

The famous snake game in Lua for the TI-Nspire.


Pages: [1] 2