BBTetris
Bomb Bloke 09 Nov 2013
So I thought I'd try my hand at something for a treasure disk - Yes, it's Tetris. I've probably overdone it, but so be it.
Ever seen those little grey hand-held Tetris games, with lots of variants built in? This is based on those. It's relatively simple (there's only a handful of extra game modes, and they're all variants of, well, Tetris), but you can mix and match to whatever suits your fancy.
When I first wrote this post I marked it as beta code, but I'm now satisfied it's stable and ready to put down as a "final release". By whatever coincedence wojbie posted his mirror util at about the same time as this, which was fortunate as it allowed me to quickly pick up some holes in my monitor-handling logic (since fixed).
I guess I may be able to claim the "first ComputerCraft game with music" title here - if one or more Iron Note Blocks from MoarPeripherals are available, along with the "note" resource pack downloadable from the same link, the game will play background music!
So, without further ado:
pastebin get nKQZwgtv bbtetris
Edited by Bomb Bloke, 10 February 2016 - 11:16 PM.
Screenshot
Ever seen those little grey hand-held Tetris games, with lots of variants built in? This is based on those. It's relatively simple (there's only a handful of extra game modes, and they're all variants of, well, Tetris), but you can mix and match to whatever suits your fancy.
When I first wrote this post I marked it as beta code, but I'm now satisfied it's stable and ready to put down as a "final release". By whatever coincedence wojbie posted his mirror util at about the same time as this, which was fortunate as it allowed me to quickly pick up some holes in my monitor-handling logic (since fixed).
I guess I may be able to claim the "first ComputerCraft game with music" title here - if one or more Iron Note Blocks from MoarPeripherals are available, along with the "note" resource pack downloadable from the same link, the game will play background music!
So, without further ado:
pastebin get nKQZwgtv bbtetris
Version History
Edited by Bomb Bloke, 10 February 2016 - 11:16 PM.
Wojbie 09 Nov 2013
I Love this program. Took it for a spin and even broke it!
If you run program on advanced screen and do a crtl+t screen stays on redirected on monitor. You could do that pullEventRaw() trick and make terminate quit program normally (witch includes term.restore from what i can see and would even save high-score! )
Also i would love option to give it in argument side of computer where monitor i want to use it is or none for it to skip that first y/n question. Example "tetris right" or "tetris none". That would be great for arcade room i have in my base.
Also love that you included modes and a awesome loading screen.
Edited by wojbie, 09 November 2013 - 12:08 PM.
If you run program on advanced screen and do a crtl+t screen stays on redirected on monitor. You could do that pullEventRaw() trick and make terminate quit program normally (witch includes term.restore from what i can see and would even save high-score! )
Also i would love option to give it in argument side of computer where monitor i want to use it is or none for it to skip that first y/n question. Example "tetris right" or "tetris none". That would be great for arcade room i have in my base.
Also love that you included modes and a awesome loading screen.
Edited by wojbie, 09 November 2013 - 12:08 PM.
Bomb Bloke 09 Nov 2013
I'd discarded the idea of using raw events out of hand... I usually see it used to make programs "unquitable". Decided that if someone wanted to try forcing the program to "drop everything" then it'd do exactly that, and they could live with the consequences.
That said, that was before the monitor code went in, and I can see that the average user is going to be scratching their head trying to work out how to fix that one, so "terminate" event handling is now in there. (Was tempted to have them prevent saving scores etc, but decided to have that go ahead anyway.)
Having to type a parameter to indicate you don't want to use a monitor is more effort then just tapping "n" when the program launches. Still, I suppose that's enough of an excuse to implement an INI file - now it'll generate one the first time you run it (BBTetris.ini), and if you open that up with your editor of choice the rest should be self explanatory.
Thanks for the feedback, folks!
That said, that was before the monitor code went in, and I can see that the average user is going to be scratching their head trying to work out how to fix that one, so "terminate" event handling is now in there. (Was tempted to have them prevent saving scores etc, but decided to have that go ahead anyway.)
Having to type a parameter to indicate you don't want to use a monitor is more effort then just tapping "n" when the program launches. Still, I suppose that's enough of an excuse to implement an INI file - now it'll generate one the first time you run it (BBTetris.ini), and if you open that up with your editor of choice the rest should be self explanatory.
Thanks for the feedback, folks!
Wojbie 09 Nov 2013
Bomb Bloke, on 09 November 2013 - 07:26 PM, said:
Having to type a parameter to indicate you don't want to use a monitor is more effort then just tapping "n" when the program launches. Still, I suppose that's enough of an excuse to implement an INI file - now it'll generate one the first time you run it (BBTetris.ini), and if you open that up with your editor of choice the rest should be self explanatory.
Thanks for the feedback, folks!
Thanks for the feedback, folks!
Great so i will be able to specify in that .ini file that its supposed to play on "monitor_126" instead of first one it sees? Great!
That will work great for my needs too. Also i love how program dynamically handles monitor resizes . Nice piece of code. Its defiantly getting spot in my arcade
Bomb Bloke 09 Nov 2013
Unfortunately it tried to handle resizes that weren't happening to the monitor it had control over (as I found on testing your mirroring tool), so I've again tweaked the code a bit.
Edited by Bomb Bloke, 09 November 2013 - 08:40 PM.
Edited by Bomb Bloke, 09 November 2013 - 08:40 PM.
Wojbie 09 Nov 2013
Bomb Bloke, on 09 November 2013 - 08:40 PM, said:
Unfortunately it tried to handle resizes that weren't happening to the monitor it had control over (as I found on testing your mirroring tool), so I've again tweaked the code a bit.
That was making me run ragged!!! I was looking at debug event queue on another monitor and I was like Wat?
Hehehehehe.
Symmetryc 10 Nov 2013
There are a few things that you could've done to make your life easier, but very nice and solid program nonetheless
Bomb Bloke 16 Nov 2013
Symmetryc, on 10 November 2013 - 08:48 AM, said:
There are a few things that you could've done to make your life easier, but very nice and solid program nonetheless
Xenthera, on 10 November 2013 - 06:03 PM, said:
Not gonna lie. I spent a few hours playing it...
At one stage I realised that I was gaming as a character who was getting addicted to a game, and that broke me out of it hard and fast.
Symmetryc 16 Nov 2013
Bomb Bloke, on 16 November 2013 - 02:14 AM, said:
Symmetryc, on 10 November 2013 - 08:48 AM, said:
There are a few things that you could've done to make your life easier, but very nice and solid program nonetheless
[[ Hello! Bye! ]]You can use these to print out things that would usually take more than one print statement or would be convoluted if done in one print statement, ex:
-- old way print("\nIf you wish to copy me to your internal drive (for play without the disk), type:\n\ncp \\disk\\BBTetris \\BBTetris\n") -- new way print([[ If you wish to copy me to your internal drive (for play without the disk), type: cp \disk\BBTetris \BBTetris ]]) -- Note: Putting "\\" in multiline strings will simply give you "\\"; Characters won't be escaped.Also, is there any reason that you're using term.write over write? I believe write has more features (such as \n support), although I'm not entirely sure.
Furthermore, are you familiar with the concept of objects? You might want to check out a tutorial on OOP in the Tutorials section, because from the way it looks, you could probably halve the amount of lines if you were to use objects over huge if statements .
However, this is still a very robust and impressive program and keep up the great work ! (Hope this helps )
Edited by Symmetryc, 16 November 2013 - 05:24 PM.
Bomb Bloke 16 Nov 2013
I started out with just the intention of having monitor support, and thought "term.write" would somehow make things easier there. As I found out there wasn't much difference, but there are a few spots where it's specifically needed (eg, where I write stuff off-screen). I suppose since it doesn't even consider word-wrapping and what-not it's also going to be faster then "write".
I'm familiar with Java and the joys of OOP, but I don't see how I'd implement any objects here. I mean, I could certainly throw at least one in, but I can't see how it'd be done without making the program longer... Sure, it'd let me shuffle code around, but that code wouldn't go away altogether: it'd just be wrapped up within additional function declarations elsewhere... Dunno.
I'm also a little suspicious as to how OOP works in Lua: I mean, there are times when that technique certainly seems to fit (eg, you've got a ton of enemies on screen which all have the same properties/functions), but I rather suspect that Lua's implementation wastes bucket loads of RAM duplicating functions to pull it off (er, or at least, more RAM then it usually does ). No idea, I'll have to try defining some and find out what the options are, as it can improve readability if nothing else.
I'd seen the [[]] thing used once before, but wasn't aware of its full capabilities. That'll indeed come in handy.
Thanks!
I'm familiar with Java and the joys of OOP, but I don't see how I'd implement any objects here. I mean, I could certainly throw at least one in, but I can't see how it'd be done without making the program longer... Sure, it'd let me shuffle code around, but that code wouldn't go away altogether: it'd just be wrapped up within additional function declarations elsewhere... Dunno.
I'm also a little suspicious as to how OOP works in Lua: I mean, there are times when that technique certainly seems to fit (eg, you've got a ton of enemies on screen which all have the same properties/functions), but I rather suspect that Lua's implementation wastes bucket loads of RAM duplicating functions to pull it off (er, or at least, more RAM then it usually does ). No idea, I'll have to try defining some and find out what the options are, as it can improve readability if nothing else.
I'd seen the [[]] thing used once before, but wasn't aware of its full capabilities. That'll indeed come in handy.
Thanks!
Yevano 16 Nov 2013
Bomb Bloke, on 16 November 2013 - 06:39 PM, said:
but I rather suspect that Lua's implementation wastes bucket loads of RAM duplicating functions to pull it off
If you use metatables, you don't have to worry about that. The common thing to do is to create a class table to hold all your functions and set the metatable of all instances to that of the class. That way, they just call the class function, passing the object in as self.
Edited by Yevano, 16 November 2013 - 06:57 PM.
jay5476 17 Nov 2013
Yevano, on 16 November 2013 - 06:57 PM, said:
Bomb Bloke, on 16 November 2013 - 06:39 PM, said:
but I rather suspect that Lua's implementation wastes bucket loads of RAM duplicating functions to pull it off
If you use metatables, you don't have to worry about that. The common thing to do is to create a class table to hold all your functions and set the metatable of all instances to that of the class. That way, they just call the class function, passing the object in as self.
EDIT: if i get time i will try to make my own version essentialy using OOP
Edited by jay5476, 17 November 2013 - 04:47 AM.
theoriginalbit 17 Nov 2013
Nice work. I am curious as to why you're doing an else block with do block inside of it at 1213. Also don't forget about the error level of 0.
error("No file or line numbers shown, just this message in red", 0)
Bomb Bloke 17 Nov 2013
theoriginalbit, on 17 November 2013 - 07:52 AM, said:
I am curious as to why you're doing an else block with do block inside of it at 1213.
theoriginalbit, on 17 November 2013 - 07:52 AM, said:
Also don't forget about the error level of 0.
error("No file or line numbers shown, just this message in red", 0)
If you're wondering about my use of the "erroring" value, that's less to report that "there was a problem at line such-and-such" and more to report things like "the user bulldozed my monitor!" - I then want it to go on to output the usual closing statements too. But I suspect that's not what you're getting at.
theoriginalbit 17 Nov 2013
Bomb Bloke, on 17 November 2013 - 05:58 PM, said:
Just a quick way to have the "sides" table discarded when I was done with it.
Bomb Bloke, on 17 November 2013 - 05:58 PM, said:
I think I'm not so much forgetting it as not knowing why I need it in the first place. />
If you're wondering about my use of the "erroring" value, that's less to report that "there was a problem at line such-and-such" and more to report things like "the user bulldozed my monitor!" - I then want it to go on to output the usual closing statements too. But I suspect that's not what you're getting at.
If you're wondering about my use of the "erroring" value, that's less to report that "there was a problem at line such-and-such" and more to report things like "the user bulldozed my monitor!" - I then want it to go on to output the usual closing statements too. But I suspect that's not what you're getting at.
Symmetryc 17 Nov 2013
Bomb Bloke, on 16 November 2013 - 06:39 PM, said:
I'm also a little suspicious as to how OOP works in Lua: I mean, there are times when that technique certainly seems to fit (eg, you've got a ton of enemies on screen which all have the same properties/functions), but I rather suspect that Lua's implementation wastes bucket loads of RAM duplicating functions to pull it off (er, or at least, more RAM then it usually does ). No idea, I'll have to try defining some and find out what the options are, as it can improve readability if nothing else.
Thanks!
Thanks!
Spoiler
Edit: When I said it could be shortened, I meant that if you had an table full of screen objects or similar, you could just iterate through them when the user clicked and check to see if the click came in contact with any of them and if it did, run the function within that screen object's table rather than having to build a huge if statement with each screen object having its own part.Ex:
Spoiler
Edited by Symmetryc, 17 November 2013 - 09:02 PM.