Code:
/*
* Project: N|Watch
* Author: Zak Kemble, contact@zakkemble.co.uk
* Copyright: (C) 2013 by Zak Kemble
* License: GNU GPL v3 (see License.txt)
* Web: http://blog.zakkemble.co.uk/diy-digital-wristwatch/
*/
/* Pong watchface, based on breakout code */
#include "common.h"
#define PLATFORM_WIDTH 12
#define PLATFORM_HEIGHT 4
typedef struct{
float x;
float y;
float velX;
float velY;
}s_ball;
static const byte platform[] PROGMEM ={
0x0F,0x0F,
};
static const byte ballImg[] PROGMEM ={
0x03,0x03,
};
static s_ball ball;
static byte lives=0;
static uint score;
static byte platformX;
static byte cplatformX; // computer platform position
static void game_start(void);
static display_t draw(void);
void watchface_normal()
{
if (lives == 0){
game_start();
}
display_setDrawFunc(draw);
buttons_setFuncs(NULL, menu_select, NULL);
animation_start(NULL, ANIM_MOVE_ON);
}
void game_start()
{
menu_close();
srand(millis());
display_setDrawFunc(draw);
// buttons_setFuncs(btnRight, btnExit, btnLeft);
ball.y = FRAME_WIDTH / 2;
ball.x = FRAME_HEIGHT - 10;
ball.velX = -1;
ball.velY = -1.1;
// blocks = calloc(BLOCK_COUNT, 1);
lives = 3;
score = 0;
platformX = (FRAME_HEIGHT / 2) - (PLATFORM_WIDTH / 2);
cplatformX = ball.x;
}
static display_t draw()
{
byte platformXtmp = platformX;
platformXtmp = ball.x - PLATFORM_WIDTH/2;
// Make sure platform stays on screen
if(platformXtmp > 250-10)
platformXtmp = 1;
else if(platformXtmp > FRAME_HEIGHT - PLATFORM_WIDTH)
platformXtmp = FRAME_HEIGHT - PLATFORM_WIDTH;
// Draw platform
image_s img = newImage(FRAME_WIDTH - 2, platformXtmp, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(FRAME_WIDTH - 2, platformXtmp+2, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(FRAME_WIDTH - 2, platformXtmp+4, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(FRAME_WIDTH - 2, platformXtmp+6, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(FRAME_WIDTH - 2, platformXtmp+8, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
platformX = platformXtmp;
// Move ball
ball.x += ball.velX;
ball.y += ball.velY;
const byte ballX = ball.x;
const byte ballY = ball.y;
// Side wall collision
cplatformX = ball.x - PLATFORM_WIDTH/2;
platformXtmp = cplatformX;
// Make sure platform stays on screen
if(platformXtmp > 250-10)
platformXtmp = 1;
else if(platformXtmp > FRAME_HEIGHT - PLATFORM_WIDTH)
platformXtmp = FRAME_HEIGHT - PLATFORM_WIDTH;
img = newImage(0, platformXtmp, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(0, platformXtmp+2, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(0, platformXtmp+4, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(0, platformXtmp+6, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
img = newImage(0, platformXtmp+8, platform, 2, 8, WHITE, NOINVERT, 0);
draw_bitmap_set(&img);
draw_bitmap_s2(&img);
if(ballX > FRAME_HEIGHT - 2)
{
if(ballX > 240)
ball.x = 2;
else
ball.x = FRAME_HEIGHT - 2;
ball.velX *= -1;
}
// Platform collision
bool platformCollision = false;
if(ballY >= FRAME_WIDTH - PLATFORM_HEIGHT && ballY < 250 && ballX >= platformX && ballX <= platformX + PLATFORM_WIDTH)
{
platformCollision = true;
buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
ball.y = FRAME_WIDTH - PLATFORM_HEIGHT;
if(ball.velY > 0)
ball.velY *= -1;
ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
}
// Platform collision2
bool platformCollision = false;
if(ballY >= FRAME_WIDTH - PLATFORM_HEIGHT && ballY < 250 && ballX >= platformX && ballX <= platformX + PLATFORM_WIDTH)
{
platformCollision = true;
buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
ball.y = FRAME_WIDTH - PLATFORM_HEIGHT;
if(ball.velY > 0)
ball.velY *= -1;
ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
}
// Platform collision2
platformCollision = false;
if(ballY <= 2 && ballY > 0 && ballX >= cplatformX && ballX <= cplatformX + PLATFORM_WIDTH)
{
platformCollision = true;
buzzer_buzz(200, TONE_5KHZ, VOL_UI, PRIO_UI, NULL);
ball.y = PLATFORM_HEIGHT;
if(ball.velY < 0)
ball.velY *= -1;
ball.velX = ((float)rand() / (RAND_MAX / 2)) - 1; // -1.0 to 1.0
}
// Top/bottom wall collision
if(!platformCollision && (ballY > FRAME_WIDTH - 2))
{
ball.velY *= -1;
}
// Draw ball
img.bitmap = ballImg;
img.width = 2;
img.x = ball.y;
img.y = ball.x;
draw_bitmap_s2(&img);
draw_string(time_timeStr(), false, 48, 1);
return DISPLAY_DONE;
}