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 - hoffa

Pages: 1 [2]
16
Lua / [Howto] Check if a key is pressed down (more or less)
« on: October 01, 2011, 06:59:39 pm »


I was trying to find a way to know if a key is held down or not (for a Lua CHIP-8 emulator I'm writing, more as a proof of concept than anything else), but as you probably already knew if you've programmed in Lua on the TI-Nspire, there is no way of knowing anything except when a key is first pressed. That is because of the way the TI-Nspire has been made; while most of the keys only send one event signal each time the key is pressed, the tab and arrow keys continuously keep sending those signals after a short delay while holding the key down. What you first want to do is to somewhat be able to know when one of those special keys is pressed down. It won't be as accurate as you might want it to be, but using some timer tricks (to tackle that annoying delay gap before it starts bombarding with events among others) it is possible to implement something of an isDown() function. Here's some fairly simple code that displays "true" when the tab key is held down, it should be pretty self-explanatory (and as you will notice, it isn't that accurate. It might be made slightly more accurate by tuning those interval values):
Code: [Select]
Key = class()

function Key:init(eventInterval, firstEventInterval)
    self.keyDown = false
    self.eventInterval = eventInterval or 150
    self.firstEventInterval = firstEventInterval or 750
    self.time = {firstEvent = 0, lastEvent = 0}
end

function Key:keyEvent(timeNow)
    local timeNow = timeNow or timer.getMilliSecCounter()
    if not self.keyDown then
        self.time.firstEvent = timeNow
    end
    self.time.lastEvent = timeNow
    self.keyDown = true
end

function Key:isDown(timeNow)
    local timeNow = timeNow or timer.getMilliSecCounter()
    self.keyDown = timeNow - self.time.firstEvent < self.firstEventInterval
                or timeNow - self.time.lastEvent < self.eventInterval
    return self.keyDown
end

function on.tabKey()
    tab:keyEvent()
end

function on.timer()
    platform.window:invalidate()
end

function on.create()
    timer.start(0.01)
end

tab = Key()
function on.paint(gc)
    gc:drawString("Tab key down: " .. tostring(tab:isDown()), 0, 0, "top")
end

Now to know if a number or character key is pressed down, well, there is no way to do that. But one workaround would be to use the tab key. For example, if you wanted to make it possible for the program to know when a certain key is held down, you'd first have to press that key and then quickly press and hold the tab button. After some coding, we have this:

Code: [Select]
MasterKey = class()

function MasterKey:init(eventInterval, firstEventInterval)
    self.keyDown = false
    self.eventInterval = eventInterval or 200
    self.firstEventInterval = firstEventInterval or 750
    self.time = {firstEvent = 0, lastEvent = 0}
end

function MasterKey:keyEvent(timeNow)
    local timeNow = timeNow or timer.getMilliSecCounter()
    if not self.keyDown then
        self.time.firstEvent = timeNow
    end
    self.time.lastEvent = timeNow
    self.keyDown = true
end

function MasterKey:updateStatus(timeNow)
    local timeNow = timeNow or timer.getMilliSecCounter()
    self.keyDown = timeNow - self.time.firstEvent < self.firstEventInterval
                or timeNow - self.time.lastEvent < self.eventInterval
end

function MasterKey:isDown()
    return self.keyDown
end

Keys = class()

function Keys:init(keys, eventInterval)
    self.keys = {}
    for i = 1, #keys do
        self.keys[keys[i]] = {keyDown = false, timeLastEvent = 0}
    end
    self.eventInterval = eventInterval or 200
end

function Keys:keyEvent(key, timeNow)
    self.keys[nobbc].timeLastEvent = timeNow or timer.getMilliSecCounter()
end

function Keys:updateStatus(key, masterKey)
    if masterKey.keyDown then
        if not self.keys[nobbc].keyDown
       and masterKey.time.lastEvent - self.keys[nobbc].timeLastEvent
         < self.eventInterval then
            for key, value in pairs(self.keys) do
                self.keys[nobbc].keyDown = false
            end
            self.keys[nobbc].keyDown = true
        end
    else
        self.keys[nobbc].keyDown = false
    end
end

function Keys:isDown(key)
    return self.keys[nobbc].keyDown
end

function on.tabKey()
    tab:keyEvent()
end

function on.charIn(c)
    if c == "x" then
        keys:keyEvent("x")
    elseif c == "y" then
        keys:keyEvent("y")
    elseif c == "z" then
        keys:keyEvent("z")
    end
end

function on.timer()
    platform.window:invalidate()
end

function on.create()
    timer.start(0.01)
end

tab = MasterKey()
keys = Keys({"x", "y", "z"})
function on.paint(gc)
    tab:updateStatus()
    keys:updateStatus("x", tab)
    keys:updateStatus("y", tab)
    keys:updateStatus("z", tab)
    gc:drawString("'x' key down: " .. tostring(keys:isDown("x")), 0, 0, "top")
    gc:drawString("'y' key down: " .. tostring(keys:isDown("y")), 0, 20, "top")
    gc:drawString("'z' key down: " .. tostring(keys:isDown("z")), 0, 40, "top")
end

The "master key" in that case is the tab key, which tells the program how long a certain key should be held down. Try it out yourself, press tab + [x/y/z] quickly and hold on to tab, you'll see how the values change. It's not perfect but it's as far as I know the best you can do with TI-Nspire Lua.

Well that was it, going to bed now!

17
TI-Nspire / Pseudo-3D engine for the TI-Nspire using Lua
« on: September 13, 2011, 11:38:42 am »
Hello,

I've been working on a pseudo-3D (using ray casting) engine for the TI-Nspire. Chokosta has already made one (actually I got the idea from him), but I want to have a flexible and fast engine that could eventually be used to make some sort of games. Lua on the TI-Nspire is already quite slow, and so I will try and optimize the most critical parts as much as Lua allows it to have a decent rendering frame rate. At the moment I am in the testing phase, trying different techniques of ray casting (namely, using vectors like Lode Vandevenne in his tutorial does, or using angles) as I want to have good and clear code while still being fast. Also for texture mapping I have a few choices, so I'll have to weigh all that and choose the ones that suit the best.

As a summary, what I will try to make is an engine that has/is:
  • A decent rendering frame rate
  • Easy-to-use, easily configurable and flexible
  • Texture mapping on walls
  • Various rendering effects
  • Some sort of fog
  • Other stuff that I can't remember

As I love splash screens and screenshots in general, here you go:



Ain't much else for now. Let's just hope making this thread will keep me motivated. :*

18
TI-Nspire / Hyena: a simple (Lua) GUI library for the TI-Nspire
« on: August 17, 2011, 08:10:29 am »
Hello,

I started a small project of writing in Lua a GUI library for the TI-Nspire. At the moment there's not much; the windows are clickable and the general floating windows thing works.
As everybody loves screenshots, I give you a screenshot:



Also here's a very early video with some content in one of the windows. I can move windows around and close them also (forgot to show that, but it works).



I'm not even sure if it will actually be that useful when I eventually manage to make something usable, but we'll see about that later.
Well that's about it for the moment. :3

19
Hello,

I've been working on a copter-like game called Pixel Escape for a few days. If you have ever played the Copter Game, you should know what this is about. It's the same thing except there's no copter, but a "pixel" (I initially wanted to make it with a copter, but while I was testing the movement with a primitive rectangle, I realized it was quite nice with a trail of squares (looks like a sperm I have to admit), and decided to stick with it).





I filmed it while playing, here you go: (Edit: I'm more or less constantly changing things so the video won't be up-to-date):



The number at bottom left is the current score, while the one in the bottom right is the best score. The game gets harder as your pixel gets further.
Download link somewhere here (june 16 update).
The controls won't be that great if you try it on the computer, especially because of the huge clock difference.
In order to save your score, close the document with the Ctrl + W key combination (which is how you close a document, for anyone who didn't know), it should then ask to save or not.

20
Lua / [Nspire] Pokémon Fuchsia -- An experiment
« on: May 31, 2011, 12:11:08 pm »
Hey,

I yesterday started experimenting with Lua to see how well it handled graphics and other game-related stuff. I wrote on the other thread about my results. Well it seems like the calculator is not fast enough to handle games where fluidity in the gameplay is an important factor (i.e. many platformers). It's not that the calculator itself is slow, it's just the way Lua has been implemented on it that makes it inefficient for such games (Edit: invalidate() is able to update the screen partially, so all that written before might be wrong). I then decided playing around with Pokémon-like games, where speed is not the most important thing. And that's basically where I'm at, at the moment. For now with what I have done it seems to be working well. This also helps me to test Lua in a "real-life situation", with title screens and everything that a game usually has, in order to see what the difficulty of making such a game is and whatnot.

Everybody loves screenshots, so I give you screenshots:



It's not much (at least Ash can move and the basic tile "engine" is done), and I'm only in the experimenting/testing phase right now. I still have to see how to actually save an eventual game (it might be possible to do something with var.store() and its friends), if it is even possible, and many other things to see if it's even worth trying to make the game.

Spoiler For Spoiler:
It's Fuchsia because I didn't even know what kind of color fuchsia was, and also because it's such a manly color. (I don't even know how you pronounce "fuchsia")

That's it for now. :)

PS: Also notice the small black on the second screenshot at the bottom. By "removing" 4 pixels (which is the same width as the upper bar, so it's symmetrical and doesn't look ugly) I have a resolution of 318*208, which is a lot better (especially in a tile-based game) than normally.

21
Hello!

Here is a tool I wrote (even though I'm everything but a fan of PHP; it's just easier for everybody to use) to convert PNG/GIF/BMP/etc. images to the TI.Image format, usable within Lua scripts. It supports all image sizes and is able to convert colored images. CX or non-CX, it should work with both (color will just be transformed into shades of gray). Anyway, here's the link, try it out yourself:

http://hoffa.franceserv.fr/tiimage/

The usage is simple: select your file and press the button. The long string you'll see is the image in the TI.Image format. Use the image.new() function with that string to load the image, and draw it on the screen with gc:drawImage(). Nothing too complicated.


(that grayish square behind the sprite only shows up on the emulator, it shouldn't show up on the calculator. It's probably there so it's easier to differentiate transparent from white pixels)

Because the output is usually quite big, there will probably be some sort of compression (at least ~50% smaller) option in the near future, along with a Lua function to decompress the image in order to save some space.

Here is a very simple image viewer made with TI.Image images if you want to see what it looks like (use left and right arrows to change image): http://webgel.net/bf/simple_image_viewer.tns

Changelog:
  • 0.7
    • Now uses ImageMagick instead of GD, i.e. numerous image formats are now supported
    • Code cleanup and speed improvements
    • Minor UI changes
    • All bytes now have a length of 3 digits, otherwise some bugs might occur (e.g. \12\52 is changed into \124, which is the wrong byte)
    • Fixed a bug with transparency not working properly
  • 0.6
    • All possible "bytes" are now replaced with ASCII characters (except double quotes and backslashes for obvious reasons) to decrease the size of the output
    • Added option to enable/disable transparency
    • Minor code/UI changes
  • 0.5
    • Fixed a bug with some colors not being converted properly
    • Less function calls; the conversion should now be slightly faster
  • 0.4
    • Added support for color (CX and non-CX)
    • Minor code changes
  • 0.3
    • No more size restriction, the header is now generated as it should
    • Minor code/UI changes
  • 0.2
    • Added support for transparency
  • 0.1
    • First version

Notes: (these are just interesting things I've noticed while playing around with Lua and graphics, might be useful to some)
  • The screen is cleared at every call of on.paint(), so no need to fill the screen as with SDL and other low-level graphics libraries to avoid trailing
  • gc:drawImage() handles negative and out-of-the-screen coordinates well (i.e. just draws the visible part)
  • Moving a single sprite over a fullscreen background image is very slow, same thing with the same sprite drawn multiple times on the whole screen (i.e. tiling)
  • Slower using tiles converted from colored pictures than using tiles converted from black and white pictures (at least seems like it, I might be wrong. But it's still very slow), might be because the Nspire converts the colors at every single call to gc:drawImage() to shades of gray (if that's the case, I'll add an option to convert specifically to non-CX calculators some time)
  • Using transparent pixels is a lot faster than using plain white pixels. Using a background of fully transparent sprites is a lot faster (as if there was no background) than using a background of completely white sprites (which is as slow as if there were any kinds of sprites)

Pages: 1 [2]