Matt's Prototypes

I'm working on a larger game, but every so often I take a break and make a protoype of some sort to try out some other techniques that I plan to use in future. Here they be!

Feel free to ask questions about any of this and I'll do my best to answer.

Horse Race

  • I created such a game for my brother on his Psion Series 3 back in the 90s
  • Created to learn about how Sprites work
  • Purely random right now

horses.opt


Poker Dice

  • I want to make this game Portrait orientation so it's on hold for now
  • Created to test my own user interace module and a custom Font

dice.opt

  • broken in Pubic SDK 1.9.0 but you're not missing anything

Collector

  • Everything is drawn using graphics primitives (circle, rect, line)
  • Various ideas to flesh out this one
  • Crank or buttons to aim

collect.opt


Racer

  • Will take this one further
  • Uses off screen collision map (which I wish allowed more than black and white!)
  • Heuristic collisions rather than using the SDK
  • Crank or buttons to steer
  • Variable maximum speed
  • Needs an artist! (graphics quickly ripped from an arcade game)

count.opt

30 Likes

These all look great! I'm curious about how you drew the dithered fill circled in Collector, I haven't found anything in the docs about drawing graphics primitives with anything other than a solid fill or just an outline.

The racing game is really impressive, I would love to see that become a thing with bigger maps and AI racers :slight_smile: I'm a sucker for arcade racing games.

Keep up the awesome work! These are all really inspirational.

Thanks Scott! Your compliments mean a lot :yellow_heart:

I just updated the GIF for the racing game to feature a better car sprite. Next I want to redo the controls to allow drifting/skiding.

Anyway, you can define your own fill patterns with playdate.graphics.setPattern(pattern) I saw a use of that in the Asheteroids example. I used macOS calulator binary mode (click the digits inside the red highlight to "set pixels") and you'll see the number 0xF0 corresponds to 1111 0000. Do this 8 times to define 8 rows of pixels.

Screen shot 2020-05-22 at 19.32.16

So this sort of pattern means you can do "marching ants" quite easily with the following pattern applied to narrow lines.

pattern = { 0xF0, 0xE1, 0xC3, 0x87, 0xF, 0x1E, 0x3C, 0x78 }	-- diagonal lines

if ticks % 10  == 0 then
	table.insert(pattern, 1, table.remove(pattern))  -- rotate rows to animate pattern
end

playdate.graphics.drawRect(10,10,380,220) -- draw single pixel rect

Example:
ants.opt

12 Likes

I was just thinking of a better way to define patterns than using hex numbers. Importing a full bitwise module seemed overkill, so I ended up using tonumber (e [, base]) with base 2.

which means this cryptic and obtuse hex:

pattern = { 0xF0, 0xE1, 0xC3, 0x87, 0xF, 0x1E, 0x3C, 0x78 }	-- diagonal lines

becomes this much more visual and readable "binary":

pattern = {	--  diagonal lines
	tonumber('11110000', 2),
	tonumber('11100001', 2),
	tonumber('11000011', 2),
	tonumber('10000111', 2),
	tonumber('00001111', 2),
	tonumber('00011110', 2),
	tonumber('00111100', 2),
	tonumber('01111000', 2),
}

we could even go further with a simple wrapper:

-- binary string to number
local function b(e)
	return tonumber(e, 2)
end

pattern = {	--  diagonal lines
	b('11110000'),
	b('11100001'),
	b('11000011'),
	b('10000111'),
	b('00001111'),
	b('00011110'),
	b('00111100'),
	b('01111000'),
}
9 Likes

Oh awesome, that's a great idea! If it's ok with you, I'd like to try incorporating this into Planet Defense to draw my primitives.

that's a great tip!

In C you can format a number direction in binary similar to hexadecimal notation
int number = 0b0110;

It's a shame it is nor supported in lua.

1 Like

Scott, go for it! Excited to see what you do with it.

Nic, I agree! I was more than a little surprised to see Lua didn't know about 0b1

1 Like

New car physics with drifting and skid marks

skids.opt

22 Likes

Rendering low-poly cars using OpenSCAD language https://openscad.org

Screen shot 2020-05-27 at 19.12.13

5 Likes

Oh wow, so are you just rendering each of the angles you want and then loading those in and associating it with a range of angles? Your sense of perspective in this project is really well done so this really helps explain why it looks so good!

1 Like

Yes, in a nutshell.

I try to automate as much as possible so I can reprocess a workflow at any time.

I use SCAD to lock the view angle and zoom. I tie rotation to the animation value $t. Then I run the animation and the app spits out all the rotated images for me.

They need a little post-processing, so I use a single RetroBatch workflow to: crop, add transparency, invert, a few other things, and finally stitch the 32 images into one long sprite sheet. (On Windows I think you could use IrfanView)

Finally, I run the sprite sheet through my dithering tool to convert to 1-bit.

That's good enough for my current requirements. Later on I would want extra detail in the renders, either through texturing or by hand.

4 Likes

I just couldn't let it go.

Added a ton more detail to the model, most is lost during resize, but at least I know it's there.

Plus colouring, so dithering is now optional.

I now render wheels turning!

Screen shot 2020-05-29 at 16.07.55

3 Likes

This detail will be helpful for cutscenes in your game! As well as transition screens/loading screens :slight_smile: I'm curious what it looks like converted but bigger so it has more detail.

Hi Matt,

Nice little car mono color material rendered.

Are you going to render in 3D or 2D into the Playdate game ?

I noticed there is 3D API "playdate.graphics.fillTriangle()" though, I am very excited to do 3D games development on Playdate as well :slight_smile:

1 Like

I'm rendering 2D, I'm not sure about performance of 3D so I went with tried and tested 2D. I have three rows of rotated cars in the sprite sheet: each has wheels pointing in different directions.

I'm currently doing the skid marks as sprites (which is why they disappear over time) partly because it was easy to get going, partly to see performance limits (~350 sprites in the GIF below, 25 of which are collidable and have my custom physics applied). Will be drawing straight to screen at some point in the future.

Short term goal is to have some lap races/time-trials, plus a "driving test" or "stunt driving" mode which is what you're seeing here.

Codename is Crank Turismo

You can't hear my great synth-powered car engine and skidding sfx!

Try it for yourself: car.pdx.zip (35.7 KB)

controls:

  • L/R/Crank=steer
  • A/UP=accelerate
  • B=brake
  • Menu Options=reset positions

cone3.opt

12 Likes

Nice, getting realistic now.

1 Like

This is awesome! I don't have hardware yet, but even the simulator crank with a mouse feels intuitive to steer.

1 Like

Thanks! that's what I'm aiming for.

I have redone the collision/rebound physics, and car visual and steering is now affected when colliding - makes collisions feel really physical.

Tyres and Cones have different collision properties so they feel different.

So I'm now happy enough with the handling, time to get some gameplay in here.

newcones.opt

8 Likes

Fastest Time Challenge

  • hit all 8 cones as quickly as possible
  • obstacles getting stuck under your car will slow you down!

Download: car.pdx.zip (41.8 KB)

edit: fixed menu options reset, updated car sprite, 30fps

score.opt

6 Likes

This is looking great! :playdate_heart:

1 Like