I was playing with some 3D rendering stuff and ended up making a tennis game.
Play against AI or with up to 4 players.
Z to hit the ball. To hit the ball in different directions you need to hit it when it's off to your side. So the further to your right the ball is when you hit it the more it will go left.
X to do a power shot. Whenever you return the ball during a rally you will build up power. You can do a power shot anytime you have power in your meter, but the more it builds up the faster your shot will be.
- As per Felice's comment I changed the display when a point is scored to make it easier to understand. It will now display PLAYER 1 POINT in blue. There's is also a message above that in orange for things like OUT or FAULT etc.
- Also adjusted the service so hitting a fault isn't unpredictable. Now the only way you should get a fault is if you over angle the ball (by moving sideways after you've thrown the ball, but before you hit it)
- Corrected the range from which you can hit the ball because it was WAY too far.
- Readjusted the hit distance to be a little more forgiving. Still not a broad as it was in the early version.
- Power shots are now a bit easier to direct. I was previously culled the angle on them a bit too much to account for the extra speed.
- Made a slight change so the AI isn't quite so strong. Basically just dumbed it down a bit more. I'd need to add some more advanced logic to make it more fun to play against. I've managed to get about 300 tokens, so I might look into it if I have time.
- Added new label image.
- Reduced AI difficulty slightly (particularly for Normal mode).
- Fixed a bug that caused the game to go into an inescapable AI match if the menu screen was left on for about 10 to 15 minutes.
- Changed matches to be best-of so they'll now end when a player/team has won more than half of the sets.
Now available on itch.io https://paranoidcactus.itch.io/pico-tennis
This is lovely. Quite difficult for me, but I think that's largely because I suck, and not because it's balanced poorly.
I would suggest making it clearer who got the point when it says "POINT". It seems to display the exact same message regardless of whether the AI or the player score, which can be confusing at times, especially for those of us only passingly familiar with tennis.
I've corrected the distance from which the player can hit the ball. I had extended it after watching a friend fail to hit the ball many times, but clearly I over compensated. I also found that I had an algorithm in there that was wrong and was probably making it worse in certain situations.
The screenshot looked great but the title screen is awesome!
The game is pretty cool. Love the customization of the players. I wonder if moving the camera a bit during the game to follow the players would help ... or get annoying.
This is phenomenally good (and polished!) - amazing work!
I did find the collision a tad harsh, but perhaps I'm also just crap at this! (found myself yelling McEnroe-style "You CANNOT be SERIOUS!!" a lot!)
Also really love your intro/logo - simple but VERY effective!
I love the presentation, menu, visuals, title music, and especially character customization.
However, I cannot for the life of me seem to reliably figure out the hitbox for the ball. I think it's a combination of it being too small (in my opinion) and the swing animation being a bit weird, making it very hard to judge where to stand to hit the ball, nevermind aim it. Maybe you could made a system that extends the racket to reach it if it's within a certain distance?
Good but very difficult. Compare this with Atari 2600 Tennis and all you had to do was be there to whack the ball.
No height was involved so you could always hit the ball as long as it was in front of you.
This game instead has accurate physics that make it tough to play. The ball can well be lobbed right over your head - making it difficult if not impossible to return.
@gradualgames, Pico-8 defaults to a random "pronounceable" word now when you upload a cart without choosing an exact name.
Here, I uploaded it to:
To load this game type:
Hope This Helps !
This is so neat! I'm amazed at the kind of things people can pull off in PICO-8. Once I got the hang of the positioning and timing I was able to reliably demolish the lower AI settings, I'll have to try it on Normal next.
One minor thing is that I was expecting the 3-set and 5-set options to be "best of", like an actual tennis match, but they aren't. I selected 3 sets, won the first two sets and wasn't expecting to have to play the third, but I did. Would it be possible to make it "best of" instead? idk how tight you are for tokens, and how many that would take.
@paranoidcactus, this is such a lovely game – I've been playing it a lot recently.
Also, I've started toying with the code, attempting to create a mod, where the game that is played is changed from tennis to double disc court (another 2 to 4 player game, played with frisbees). However, I can't quite get my head around the way you've stored the court line vectors in the map editor. Could you please give a pointer on how to start deciphering the system?
If I've understood correctly, it's the read_nibble() function, which returns the coordinates that are stored in the map, but I fail to understand how, when calling the function (and read_char() that calls it in turn), one knows which part of the court dimensions are coded in each part of the map. As you can see, I struggle even formulating a coherent question about this, since the storage system is a bit over my head. But any help you can spare would be much appreciated! =)
@vehka I wrote all the data to the map using an external tool. You could modify it using a text editor, but it would be a bit tedious.
The data is stored as a mix of nibbles and bytes, so byte values aren't always aligned to the actual bytes of map memory. Some byte values may have their 4 high bits stored in the low bits of one byte with the 4 low bits being the high bits of the next byte.
Byte values are written in an odd way, if the stored value is higher than 127 then 256 is subtracted from it to make it a value from -128 to -1.
If the byte is used for a floating point value then it is either divided by 16 or 4, depending on the range and precision required for that value.
There are 2 data blocks for lines; 1 for court lines and 1 for the net. They start with a byte for the number of lines, followed by line definitions. Each line definition is structured as:
All of those byte values here are divided by 4 after they're read.
All of the data is sequential, and the line data is preceded by sprite data, animation, player start positions, court bounds and a few other things so, to find out where that data is located, you'd need to check the value of parse_nibble_offset when read_line_data is called.
Thanks so much for your detailed reply @paranoidcactus! I really appreciate it.
Yeah, I understand that modifying the map tiles is not the most convenient way to edit the vectors. Could you tell me a bit more about the external tool you used to populate the map memory? I suppose I could just use it to convert my new court line vectors into binary map data.
Here is the cart I used to write data to map. You'll need to download it as it writes the map data to an external file. You can edit the lua tables, then run the cart and press x to export the map. It will save it to a cart called picotennis_sprites.p8. Then you can use a text editor to copy the
__map__ block to your own cart.
[Please log in to post a comment]