Jump to content




BBTetris

game

26 replies to this topic

#1 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 09 November 2013 - 01:24 AM

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.

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.


#2 Zudo

  • Members
  • 800 posts
  • LocationUK

Posted 09 November 2013 - 05:40 AM

I will try it ASAP. The screenies look good!

#3 Yevano

  • Members
  • 376 posts
  • LocationUSA

Posted 09 November 2013 - 11:10 AM

Just played it. Great job on this. +1 for the save feature.

#4 Wojbie

  • Members
  • 631 posts
  • LocationKinda lost

Posted 09 November 2013 - 12:01 PM

I Love this program. Took it for a spin and even broke it! :D
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! :P )
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.


#5 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 09 November 2013 - 07:26 PM

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! :)

#6 Wojbie

  • Members
  • 631 posts
  • LocationKinda lost

Posted 09 November 2013 - 07:51 PM

View PostBomb 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! :)

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

#7 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 09 November 2013 - 08:40 PM

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.


#8 Wojbie

  • Members
  • 631 posts
  • LocationKinda lost

Posted 09 November 2013 - 08:51 PM

View PostBomb 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.

#9 Symmetryc

  • Members
  • 434 posts

Posted 10 November 2013 - 08:48 AM

There are a few things that you could've done to make your life easier, but very nice and solid program nonetheless :D

#10 Xenthera

  • Members
  • 170 posts

Posted 10 November 2013 - 06:03 PM

Not gonna lie. I spent a few hours playing it...

#11 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 16 November 2013 - 02:14 AM

View PostSymmetryc, 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 :D
I'm about at the point where I'm pretty sure this thing is "stable", but I'd still appreciate any tips on improving it (even if I might not use them until I write some other program). There's still a lot about Lua that I don't know. :)

View PostXenthera, on 10 November 2013 - 06:03 PM, said:

Not gonna lie. I spent a few hours playing it...
The save function went in directly after the basic game engine was done, specifically to stop me playing each and every trial run to completion.

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. ;)

#12 Symmetryc

  • Members
  • 434 posts

Posted 16 November 2013 - 12:38 PM

View PostBomb Bloke, on 16 November 2013 - 02:14 AM, said:

View PostSymmetryc, 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 :D
I'm about at the point where I'm pretty sure this thing is "stable", but I'd still appreciate any tips on improving it (even if I might not use them until I write some other program). There's still a lot about Lua that I don't know. :)

They aren't really improvements, but they're just more convenient. For example, you can define multiline strings like this:
[[
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 :P.

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.


#13 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 16 November 2013 - 06:39 PM

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... :wacko: 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! :)

#14 Yevano

  • Members
  • 376 posts
  • LocationUSA

Posted 16 November 2013 - 06:57 PM

View PostBomb 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.


#15 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 16 November 2013 - 07:09 PM

Ah, that puts my mind to rest, thanks. :)

#16 jay5476

  • Members
  • 289 posts

Posted 17 November 2013 - 04:47 AM

View PostYevano, on 16 November 2013 - 06:57 PM, said:

View PostBomb 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.
yes by using objects you can easily check collisions and data about that specific object(block)

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.


#17 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 17 November 2013 - 07:52 AM

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)


#18 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 17 November 2013 - 05:58 PM

View Posttheoriginalbit, 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.
Just a quick way to have the "sides" table discarded when I was done with it.

View Posttheoriginalbit, 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)
I think I'm not so much forgetting it as not knowing why I need it in the first place. :unsure:/>

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.

#19 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 17 November 2013 - 06:45 PM

View PostBomb 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.
But its local to the else block, so it will be discarded when the else block is finished.

View PostBomb 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. :unsure:/>

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.
Yeh I'm more talking about lines 1246-1251

#20 Symmetryc

  • Members
  • 434 posts

Posted 17 November 2013 - 08:23 PM

View PostBomb 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! :)
One way to do OOP (or something resembling it) would be to do something like this (your implementation of blocks is probably way different, but you can probably get the idea of what I'm talking about):
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.






2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users