Breakout 280
Here's a Breakout clone that fits in a single tweet (this version is three two characters shorter than the original). Use the mouse to control the paddle. The game will start right after loading/resetting so be ready to catch the ball. The game is made for PICO-8. See below the original and the commented version of the source code and follow me on Twitter to see more similar things.
1 2 3 4 5 | b,a={64,99},{.5,-1}poke(24365,1)memset(0,153,9215)::_::for z=0,5 do cls()map()rect(0,0,127,128)p=stat(32)rect(p-8,126,p+8,127)i=z%2+1y=b[i] b[i]+=a[i]if(pget(b[1],b[2])>0)mset(b[1]/8,b[2]/8,0)a[i]*=-1 b[i],a[i-1]=y,b[2]>119 and(b[1]-p)/8 or a[1] end pset(b[1],b[2])flip()goto _ |
And here is the annotated version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | -- set up ball position (b) and velocity vector (a) -- start game with the ball moving up-right b,a={64,99},{.5,-1} -- enable mouse controls poke(24365,1) -- fill sprite data and the top part of the map with 153 -- the sprite data starts at address 0 and the map is right -- after it. this makes all the sprites orange (one byte encodes -- two pixels in a sprite, 153 -> 0x99 in hex -> 9 is the index -- for the orange color) and the map is filled with tile 153. as -- long as the map has nonzero tiles this will work as all the -- sprites/tiles are now full orange. memset(0,153,9215) -- loop label for game logic start ::_:: -- loop six times per displayed frame so the gameplay is faster -- this needs to be a number divisible by two (see below why) -- the real multiplier for speed is actually three (see below) for z=0,5 do cls() -- just draw the whole map - only the top part was filled above map() -- draw playfield borders rect(0,0,127,128) -- take paddle positio (p) n from mouse x coordinate p=stat(32) -- draw 16 pixel wide paddle at paddle position on bottom of the -- screen rect(p-8,126,p+8,127) -- build an index counter (i) from the frame loop counter (z) -- the index counter can now be used to access both of the ball -- position and velocity components (x and y, 1 and 2) with the -- same code -- it first moves the ball horizontally and then -- vertically on the next frame loop. effectively there is no -- diagonal movement (it does look like that, though) i=z%2+1 -- store the previous value of the current position component y=b[i] -- move ball along the current axis using the velocity vector b[i]+=a[i] -- check for collision (pixel value under the ball is non-zero) if pget(b[1],b[2])>0 then -- the if-statement uses a pico8 preprocessor shorthand that -- allows for shorter code. here it is written using the standard -- if-then-end structure instead of the if(x) structure -- zero the map tile under the ball (each tile is 8x8 so we -- need to divide the ball coordinate by 8 to access the correct -- tile) mset(b[1]/8,b[2]/8,0) -- the grouped assignments are written in long form here. -- put the stored previous value back in the coordinate (the ball -- hit something so move it back outside whatever it hit) b[i]=y -- reverse the velocity component -- bounce! note that this could -- also be written like a[i]*=-1 (a[i] = -1 * a[i]) but this can't -- be done a[i]=-a[i] -- this is sneaky: the [i-1] is used to access the x component -- of the velocity vector (a) when we are processing the y -- component (i == 2, i-1 == 1): it will set index zero when -- processing x (i == 1, i-1 == 0) but that is never used. this -- sets the x component of the velocity vector based on the -- paddle position. the more to the left of the paddle hits, the -- more left motion the velocity will have and vice versa. -- if the position y component (b[2]) is over 119 (we know all -- hits will be a hit with the paddle instead of the top -- wall/bricks) -- otherwise it just reassigns the original -- value (a[1] == velocity x). -- -- this could be written as follows (but it's two chars longer): -- -- if b[2]>119 then -- a[i-1]=(b[1]-p)/8 -- end a[i-1]=b[2]>119 and(b[1]-p)/8 or a[1] -- end of collision logic end -- end of frame loop end -- draw the ball at the ball position pset(b[1],b[2]) -- flip the frame flip() -- loop to beginning of game logic goto _ |
Status | Released |
Platforms | HTML5 |
Rating | Rated 4.0 out of 5 stars (2 total ratings) |
Author | kometbomb |
Genre | Action |
Made with | PICO-8 |
Tags | Breakout, PICO-8, tweetjam |
Code license | MIT License |
Average session | A few seconds |
Inputs | Mouse |
Accessibility | Color-blind friendly, Textless |
Comments
Log in with itch.io to leave a comment.
Need points, 3 balls. game start and game over. Be finish after that.
Simple and solid. Short and sweet. Schway game.